mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: per-view field settings (#3199)
* chore: field-setting entities-events-notifications * chore: update field settings * chore: add tests * chore: add docs * chore: use an enum for field visibility * chore: clippy warnings * fix: deps fields * chore: collab merge main * chore: collab ref * test: fix tests * fix: tauri bump collab rev
This commit is contained in:
parent
6634a0ecb3
commit
f0e4f3db61
@ -34,15 +34,15 @@ default = ["custom-protocol"]
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
||||
|
||||
[patch.crates-io]
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-define = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-define = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
|
||||
#collab = { path = "../../../../AppFlowy-Collab/collab" }
|
||||
#collab-folder = { path = "../../../../AppFlowy-Collab/collab-folder" }
|
||||
|
61
frontend/rust-lib/Cargo.lock
generated
61
frontend/rust-lib/Cargo.lock
generated
@ -120,7 +120,7 @@ checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854"
|
||||
[[package]]
|
||||
name = "appflowy-integrate"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -611,7 +611,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -629,7 +629,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-client-ws"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab-sync",
|
||||
@ -647,7 +647,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -664,6 +664,8 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"strum",
|
||||
"strum_macros 0.25.2",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
@ -674,7 +676,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-define"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
@ -682,7 +684,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -694,7 +696,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -713,7 +715,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -733,7 +735,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-persistence"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
@ -753,7 +755,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -782,7 +784,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-sync"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab",
|
||||
@ -804,7 +806,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-user"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cff1b9#cff1b99f4ed51f65dab73492eac4da8e7907f079"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b1f6737#b1f67375e39c67e32c502b2968749bedf61d6a46"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -1351,7 +1353,7 @@ dependencies = [
|
||||
"flowy-sqlite",
|
||||
"lib-dispatch",
|
||||
"protobuf",
|
||||
"strum_macros",
|
||||
"strum_macros 0.21.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1438,7 +1440,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"strum_macros 0.25.2",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"url",
|
||||
@ -1492,7 +1494,7 @@ dependencies = [
|
||||
"protobuf",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum_macros",
|
||||
"strum_macros 0.21.1",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
@ -1571,7 +1573,7 @@ dependencies = [
|
||||
"nanoid",
|
||||
"parking_lot 0.12.1",
|
||||
"protobuf",
|
||||
"strum_macros",
|
||||
"strum_macros 0.21.1",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tracing",
|
||||
@ -1771,7 +1773,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"strum_macros",
|
||||
"strum_macros 0.21.1",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"unicode-segmentation",
|
||||
@ -2088,6 +2090,12 @@ dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
@ -4210,9 +4218,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.21.0"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2"
|
||||
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
@ -4220,12 +4228,25 @@ version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.3.3",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.25.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
|
@ -39,14 +39,14 @@ opt-level = 3
|
||||
incremental = false
|
||||
|
||||
[patch.crates-io]
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab-define = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cff1b9" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
appflowy-integrate = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
collab-define = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b1f6737" }
|
||||
|
||||
#collab = { path = "../AppFlowy-Collab/collab" }
|
||||
#collab-folder = { path = "../AppFlowy-Collab/collab-folder" }
|
||||
|
@ -42,8 +42,8 @@ async-trait = "0.1"
|
||||
chrono-tz = "0.8.2"
|
||||
csv = "1.1.6"
|
||||
|
||||
strum = "0.21"
|
||||
strum_macros = "0.21"
|
||||
strum = "0.25"
|
||||
strum_macros = "0.25"
|
||||
|
||||
[dev-dependencies]
|
||||
flowy-test = { path = "../flowy-test", default-features = false }
|
||||
|
@ -311,6 +311,13 @@ impl std::convert::From<String> for RepeatedFieldIdPB {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<String>> for RepeatedFieldIdPB {
|
||||
fn from(value: Vec<String>) -> Self {
|
||||
let field_ids = value.into_iter().map(FieldIdPB::from).collect();
|
||||
RepeatedFieldIdPB { items: field_ids }
|
||||
}
|
||||
}
|
||||
|
||||
/// [TypeOptionChangesetPB] is used to update the type-option data.
|
||||
#[derive(ProtoBuf, Default)]
|
||||
pub struct TypeOptionChangesetPB {
|
||||
|
@ -0,0 +1,118 @@
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::ErrorCode;
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::entities::parser::NotEmptyStr;
|
||||
use crate::entities::RepeatedFieldIdPB;
|
||||
use crate::impl_into_field_visibility;
|
||||
use crate::services::field_settings::{FieldSettings, FieldSettingsChangesetParams};
|
||||
|
||||
/// Defines the field settings for a field in a view.
|
||||
#[derive(Debug, Default, Clone, ProtoBuf)]
|
||||
pub struct FieldSettingsPB {
|
||||
#[pb(index = 1)]
|
||||
pub field_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub visibility: FieldVisibility,
|
||||
}
|
||||
|
||||
impl From<FieldSettings> for FieldSettingsPB {
|
||||
fn from(value: FieldSettings) -> Self {
|
||||
Self {
|
||||
field_id: value.field_id,
|
||||
visibility: value.visibility,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Default, Clone, ProtoBuf_Enum, PartialEq)]
|
||||
pub enum FieldVisibility {
|
||||
#[default]
|
||||
AlwaysShown = 0,
|
||||
HideWhenEmpty = 1,
|
||||
AlwaysHidden = 2,
|
||||
}
|
||||
|
||||
impl_into_field_visibility!(i64);
|
||||
impl_into_field_visibility!(u8);
|
||||
|
||||
impl From<FieldVisibility> for i64 {
|
||||
fn from(value: FieldVisibility) -> Self {
|
||||
(value as u8) as i64
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, ProtoBuf)]
|
||||
pub struct FieldIdsPB {
|
||||
#[pb(index = 1)]
|
||||
pub view_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub field_ids: RepeatedFieldIdPB,
|
||||
}
|
||||
|
||||
/// Defines a set of fields in a database view, identified by their `field_ids`
|
||||
pub struct FieldIdsParams {
|
||||
pub view_id: String,
|
||||
pub field_ids: Vec<String>,
|
||||
}
|
||||
|
||||
impl TryInto<(String, Vec<String>)> for FieldIdsPB {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_into(self) -> Result<(String, Vec<String>), Self::Error> {
|
||||
let view_id = NotEmptyStr::parse(self.view_id)
|
||||
.map_err(|_| ErrorCode::ViewIdIsInvalid)?
|
||||
.0;
|
||||
let field_ids = self
|
||||
.field_ids
|
||||
.deref()
|
||||
.iter()
|
||||
.map(|field_id| field_id.field_id.clone())
|
||||
.collect();
|
||||
|
||||
Ok((view_id, field_ids))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, ProtoBuf)]
|
||||
pub struct RepeatedFieldSettingsPB {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<FieldSettingsPB>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, ProtoBuf)]
|
||||
pub struct FieldSettingsChangesetPB {
|
||||
#[pb(index = 1)]
|
||||
pub view_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub field_id: String,
|
||||
|
||||
#[pb(index = 3, one_of)]
|
||||
pub visibility: Option<FieldVisibility>,
|
||||
}
|
||||
|
||||
impl From<FieldSettingsChangesetParams> for FieldSettingsChangesetPB {
|
||||
fn from(value: FieldSettingsChangesetParams) -> Self {
|
||||
Self {
|
||||
view_id: value.view_id,
|
||||
field_id: value.field_id,
|
||||
visibility: value.visibility,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<FieldSettingsChangesetPB> for FieldSettingsChangesetParams {
|
||||
type Error = ErrorCode;
|
||||
|
||||
fn try_from(value: FieldSettingsChangesetPB) -> Result<Self, Self::Error> {
|
||||
Ok(FieldSettingsChangesetParams {
|
||||
view_id: value.view_id,
|
||||
field_id: value.field_id,
|
||||
visibility: value.visibility,
|
||||
})
|
||||
}
|
||||
}
|
@ -23,3 +23,22 @@ macro_rules! impl_into_field_type {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_into_field_visibility {
|
||||
($target: ident) => {
|
||||
impl std::convert::From<$target> for FieldVisibility {
|
||||
fn from(ty: $target) -> Self {
|
||||
match ty {
|
||||
0 => FieldVisibility::AlwaysShown,
|
||||
1 => FieldVisibility::HideWhenEmpty,
|
||||
2 => FieldVisibility::AlwaysHidden,
|
||||
_ => {
|
||||
tracing::error!("🔴Can't parser FieldVisibility from value: {}", ty);
|
||||
FieldVisibility::AlwaysShown
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ mod calendar_entities;
|
||||
mod cell_entities;
|
||||
mod database_entities;
|
||||
mod field_entities;
|
||||
mod field_settings_entities;
|
||||
pub mod filter_entities;
|
||||
mod group_entities;
|
||||
pub mod parser;
|
||||
@ -19,6 +20,7 @@ pub use calendar_entities::*;
|
||||
pub use cell_entities::*;
|
||||
pub use database_entities::*;
|
||||
pub use field_entities::*;
|
||||
pub use field_settings_entities::*;
|
||||
pub use filter_entities::*;
|
||||
pub use group_entities::*;
|
||||
pub use row_entities::*;
|
||||
|
@ -14,6 +14,7 @@ use crate::services::field::checklist_type_option::ChecklistCellChangeset;
|
||||
use crate::services::field::{
|
||||
type_option_data_from_pb_or_default, DateCellChangeset, SelectOptionCellChangeset,
|
||||
};
|
||||
use crate::services::field_settings::FieldSettingsChangesetParams;
|
||||
use crate::services::group::{GroupChangeset, GroupSettingChangeset};
|
||||
use crate::services::share::csv::CSVFormat;
|
||||
|
||||
@ -891,3 +892,36 @@ pub(crate) async fn get_snapshots_handler(
|
||||
let snapshots = manager.get_database_snapshots(&view_id, 10).await?;
|
||||
data_result_ok(RepeatedDatabaseSnapshotPB { items: snapshots })
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||
pub(crate) async fn get_field_settings_handler(
|
||||
data: AFPluginData<FieldIdsPB>,
|
||||
manager: AFPluginState<Weak<DatabaseManager>>,
|
||||
) -> DataResult<RepeatedFieldSettingsPB, FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let (view_id, field_ids) = data.into_inner().try_into()?;
|
||||
let database_editor = manager.get_database_with_view_id(&view_id).await?;
|
||||
let field_settings = database_editor
|
||||
.get_field_settings(&view_id, field_ids)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(FieldSettingsPB::from)
|
||||
.collect::<Vec<FieldSettingsPB>>();
|
||||
data_result_ok(RepeatedFieldSettingsPB {
|
||||
items: field_settings,
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||
pub(crate) async fn update_field_settings_handler(
|
||||
data: AFPluginData<FieldSettingsChangesetPB>,
|
||||
manager: AFPluginState<Weak<DatabaseManager>>,
|
||||
) -> FlowyResult<()> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let params: FieldSettingsChangesetParams = data.into_inner().try_into()?;
|
||||
let database_editor = manager.get_database_with_view_id(¶ms.view_id).await?;
|
||||
database_editor
|
||||
.update_field_settings_with_changeset(params)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -72,8 +72,12 @@ pub fn init(database_manager: Weak<DatabaseManager>) -> AFPlugin {
|
||||
.event(DatabaseEvent::SetLayoutSetting, set_layout_setting_handler)
|
||||
.event(DatabaseEvent::GetLayoutSetting, get_layout_setting_handler)
|
||||
.event(DatabaseEvent::CreateDatabaseView, create_database_view)
|
||||
// Export
|
||||
.event(DatabaseEvent::ExportCSV, export_csv_handler)
|
||||
.event(DatabaseEvent::GetDatabaseSnapshots, get_snapshots_handler)
|
||||
// Field settings
|
||||
.event(DatabaseEvent::GetFieldSettings, get_field_settings_handler)
|
||||
.event(DatabaseEvent::UpdateFieldSettings, update_field_settings_handler)
|
||||
}
|
||||
|
||||
/// [DatabaseEvent] defines events that are used to interact with the Grid. You could check [this](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/backend/protobuf)
|
||||
@ -315,4 +319,12 @@ pub enum DatabaseEvent {
|
||||
/// Returns all the snapshots of the database view.
|
||||
#[event(input = "DatabaseViewIdPB", output = "RepeatedDatabaseSnapshotPB")]
|
||||
GetDatabaseSnapshots = 150,
|
||||
|
||||
/// Returns the field settings for the provided fields in the given view
|
||||
#[event(input = "FieldIdsPB", output = "RepeatedFieldSettingsPB")]
|
||||
GetFieldSettings = 160,
|
||||
|
||||
/// Updates the field settings for a field in the given view
|
||||
#[event(input = "FieldSettingsChangesetPB")]
|
||||
UpdateFieldSettings = 161,
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ use crate::entities::{
|
||||
use crate::notification::{send_notification, DatabaseNotification};
|
||||
use crate::services::database::DatabaseEditor;
|
||||
use crate::services::database_view::DatabaseLayoutDepsResolver;
|
||||
use crate::services::field_settings::{
|
||||
default_field_settings_by_layout, default_field_settings_by_layout_map,
|
||||
};
|
||||
use crate::services::share::csv::{CSVFormat, CSVImporter, ImportResult};
|
||||
|
||||
pub trait DatabaseUser: Send + Sync {
|
||||
@ -249,12 +252,18 @@ impl DatabaseManager {
|
||||
database_view_id: String,
|
||||
) -> FlowyResult<()> {
|
||||
let wdb = self.get_workspace_database().await?;
|
||||
let mut params = CreateViewParams::new(database_id.clone(), database_view_id, name, layout);
|
||||
let mut params = CreateViewParams::new(
|
||||
database_id.clone(),
|
||||
database_view_id,
|
||||
name,
|
||||
layout,
|
||||
default_field_settings_by_layout(layout),
|
||||
);
|
||||
if let Some(database) = wdb.get_database(&database_id).await {
|
||||
let (field, layout_setting) = DatabaseLayoutDepsResolver::new(database, layout)
|
||||
.resolve_deps_when_create_database_linked_view();
|
||||
if let Some(field) = field {
|
||||
params = params.with_deps_fields(vec![field]);
|
||||
params = params.with_deps_fields(vec![field], default_field_settings_by_layout_map())
|
||||
}
|
||||
if let Some(layout_setting) = layout_setting {
|
||||
params = params.with_layout_setting(layout_setting);
|
||||
|
@ -50,6 +50,8 @@ pub enum DatabaseNotification {
|
||||
DidMoveDatabaseViewToTrash = 84,
|
||||
DidUpdateDatabaseSyncUpdate = 85,
|
||||
DidUpdateDatabaseSnapshotState = 86,
|
||||
// Trigger when the field setting is changed
|
||||
DidUpdateFieldSettings = 87,
|
||||
}
|
||||
|
||||
impl std::convert::From<DatabaseNotification> for i32 {
|
||||
@ -81,6 +83,7 @@ impl std::convert::From<i32> for DatabaseNotification {
|
||||
82 => DatabaseNotification::DidUpdateDatabaseLayout,
|
||||
83 => DatabaseNotification::DidDeleteDatabaseView,
|
||||
84 => DatabaseNotification::DidMoveDatabaseViewToTrash,
|
||||
87 => DatabaseNotification::DidUpdateFieldSettings,
|
||||
_ => DatabaseNotification::Unknown,
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,10 @@ use crate::services::field::{
|
||||
type_option_data_from_pb_or_default, type_option_to_pb, DateCellData, SelectOptionCellChangeset,
|
||||
SelectOptionIds, TypeOptionCellDataHandler, TypeOptionCellExt,
|
||||
};
|
||||
use crate::services::field_settings::{
|
||||
default_field_settings_by_layout, default_field_settings_by_layout_map, FieldSettings,
|
||||
FieldSettingsChangesetParams,
|
||||
};
|
||||
use crate::services::filter::Filter;
|
||||
use crate::services::group::{
|
||||
default_group_setting, GroupSetting, GroupSettingChangeset, RowChangeset,
|
||||
@ -474,15 +478,17 @@ impl DatabaseEditor {
|
||||
None => default_type_option_data_from_type(field_type),
|
||||
Some(type_option_data) => type_option_data_from_pb_or_default(type_option_data, field_type),
|
||||
};
|
||||
let (index, field) =
|
||||
self
|
||||
.database
|
||||
.lock()
|
||||
.create_field_with_mut(view_id, name, field_type.into(), |field| {
|
||||
field
|
||||
.type_options
|
||||
.insert(field_type.to_string(), type_option_data.clone());
|
||||
});
|
||||
let (index, field) = self.database.lock().create_field_with_mut(
|
||||
view_id,
|
||||
name,
|
||||
field_type.into(),
|
||||
|field| {
|
||||
field
|
||||
.type_options
|
||||
.insert(field_type.to_string(), type_option_data.clone());
|
||||
},
|
||||
default_field_settings_by_layout_map(),
|
||||
);
|
||||
|
||||
let _ = self
|
||||
.notify_did_insert_database_field(field.clone(), index)
|
||||
@ -1101,6 +1107,35 @@ impl DatabaseEditor {
|
||||
Ok(csv)
|
||||
}
|
||||
|
||||
pub async fn get_field_settings(
|
||||
&self,
|
||||
view_id: &str,
|
||||
field_ids: Vec<String>,
|
||||
) -> Result<Vec<FieldSettings>, anyhow::Error> {
|
||||
let view = self.database_views.get_view_editor(view_id).await?;
|
||||
view.v_get_field_settings(field_ids).await
|
||||
}
|
||||
|
||||
pub async fn get_all_field_settings(
|
||||
&self,
|
||||
view_id: &str,
|
||||
) -> Result<Vec<FieldSettings>, anyhow::Error> {
|
||||
let view = self.database_views.get_view_editor(view_id).await?;
|
||||
view.v_get_all_field_settings().await
|
||||
}
|
||||
|
||||
pub async fn update_field_settings_with_changeset(
|
||||
&self,
|
||||
params: FieldSettingsChangesetParams,
|
||||
) -> FlowyResult<()> {
|
||||
let view = self.database_views.get_view_editor(¶ms.view_id).await?;
|
||||
view
|
||||
.v_update_field_settings(¶ms.view_id, ¶ms.field_id, params.visibility)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_auto_updated_fields(&self, view_id: &str) -> Vec<Field> {
|
||||
self
|
||||
.database
|
||||
@ -1188,6 +1223,7 @@ impl DatabaseViewData for DatabaseViewDataImpl {
|
||||
.type_options
|
||||
.insert(field_type.to_string(), type_option_data);
|
||||
},
|
||||
default_field_settings_by_layout_map(),
|
||||
);
|
||||
to_fut(async move { field })
|
||||
}
|
||||
@ -1353,4 +1389,68 @@ impl DatabaseViewData for DatabaseViewDataImpl {
|
||||
TypeOptionCellExt::new_with_cell_data_cache(field, Some(self.cell_cache.clone()))
|
||||
.get_type_option_cell_data_handler(field_type)
|
||||
}
|
||||
|
||||
fn get_field_settings(
|
||||
&self,
|
||||
view_id: &str,
|
||||
field_ids: Vec<String>,
|
||||
) -> Result<Vec<FieldSettings>, anyhow::Error> {
|
||||
let field_settings_map = self
|
||||
.database
|
||||
.lock()
|
||||
.get_field_settings(view_id, Some(field_ids));
|
||||
|
||||
let field_settings: Result<Vec<FieldSettings>, anyhow::Error> = field_settings_map
|
||||
.into_iter()
|
||||
.map(|(field_id, field_settings)| FieldSettings::try_from_anymap(field_id, field_settings))
|
||||
.collect();
|
||||
|
||||
field_settings
|
||||
}
|
||||
|
||||
fn get_all_field_settings(&self, view_id: &str) -> Result<Vec<FieldSettings>, anyhow::Error> {
|
||||
let field_settings_map = self.database.lock().get_field_settings(view_id, None);
|
||||
|
||||
let field_settings: Result<Vec<FieldSettings>, anyhow::Error> = field_settings_map
|
||||
.into_iter()
|
||||
.map(|(field_id, field_settings)| FieldSettings::try_from_anymap(field_id, field_settings))
|
||||
.collect();
|
||||
|
||||
field_settings
|
||||
}
|
||||
|
||||
fn update_field_settings(
|
||||
&self,
|
||||
view_id: &str,
|
||||
field_id: &str,
|
||||
visibility: Option<FieldVisibility>,
|
||||
) {
|
||||
let field_settings = self
|
||||
.get_field_settings(view_id, vec![field_id.to_string()])
|
||||
.ok();
|
||||
|
||||
let new_field_settings = match field_settings {
|
||||
Some(field_settings) => {
|
||||
let mut field_settings = field_settings.first().unwrap().clone();
|
||||
field_settings.visibility = visibility.unwrap_or(field_settings.visibility);
|
||||
field_settings
|
||||
},
|
||||
None => {
|
||||
let layout_ty = self.get_layout_for_view(view_id);
|
||||
let mut field_settings = FieldSettings::try_from_anymap(
|
||||
field_id.to_string(),
|
||||
default_field_settings_by_layout(layout_ty),
|
||||
)
|
||||
.unwrap();
|
||||
field_settings.visibility = visibility.unwrap_or(field_settings.visibility);
|
||||
field_settings
|
||||
},
|
||||
};
|
||||
|
||||
self.database.lock().update_field_settings(
|
||||
view_id,
|
||||
Some(vec![field_id.to_string()]),
|
||||
new_field_settings,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ use std::sync::Arc;
|
||||
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::field::{DateTypeOption, SingleSelectTypeOption};
|
||||
use crate::services::field_settings::default_field_settings_by_layout_map;
|
||||
use crate::services::setting::CalendarLayoutSetting;
|
||||
|
||||
/// When creating a database, we need to resolve the dependencies of the views.
|
||||
@ -83,7 +84,10 @@ impl DatabaseLayoutDepsResolver {
|
||||
tracing::trace!("Create a new date field after layout type change");
|
||||
let field = self.create_date_field();
|
||||
let field_id = field.id.clone();
|
||||
self.database.lock().create_field(field);
|
||||
self
|
||||
.database
|
||||
.lock()
|
||||
.create_field(field, default_field_settings_by_layout_map());
|
||||
field_id
|
||||
},
|
||||
Some(date_field) => date_field.id,
|
||||
|
@ -14,9 +14,9 @@ use lib_infra::future::Fut;
|
||||
|
||||
use crate::entities::{
|
||||
CalendarEventPB, DatabaseLayoutMetaPB, DatabaseLayoutSettingPB, DeleteFilterParams,
|
||||
DeleteGroupParams, DeleteSortParams, FieldType, GroupChangesPB, GroupPB, GroupRowsNotificationPB,
|
||||
InsertedRowPB, LayoutSettingParams, RowMetaPB, RowsChangePB, SortChangesetNotificationPB, SortPB,
|
||||
UpdateFilterParams, UpdateSortParams,
|
||||
DeleteGroupParams, DeleteSortParams, FieldType, FieldVisibility, GroupChangesPB, GroupPB,
|
||||
GroupRowsNotificationPB, InsertedRowPB, LayoutSettingParams, RowMetaPB, RowsChangePB,
|
||||
SortChangesetNotificationPB, SortPB, UpdateFilterParams, UpdateSortParams,
|
||||
};
|
||||
use crate::notification::{send_notification, DatabaseNotification};
|
||||
use crate::services::cell::CellCache;
|
||||
@ -32,6 +32,7 @@ use crate::services::database_view::{
|
||||
DatabaseViewChangedNotifier, DatabaseViewChangedReceiverRunner,
|
||||
};
|
||||
use crate::services::field::TypeOptionCellDataHandler;
|
||||
use crate::services::field_settings::FieldSettings;
|
||||
use crate::services::filter::{
|
||||
Filter, FilterChangeset, FilterController, FilterType, UpdatedFilterType,
|
||||
};
|
||||
@ -123,6 +124,21 @@ pub trait DatabaseViewData: Send + Sync + 'static {
|
||||
field: &Field,
|
||||
field_type: &FieldType,
|
||||
) -> Option<Box<dyn TypeOptionCellDataHandler>>;
|
||||
|
||||
fn get_field_settings(
|
||||
&self,
|
||||
view_id: &str,
|
||||
field_ids: Vec<String>,
|
||||
) -> Result<Vec<FieldSettings>, anyhow::Error>;
|
||||
|
||||
fn get_all_field_settings(&self, view_id: &str) -> Result<Vec<FieldSettings>, anyhow::Error>;
|
||||
|
||||
fn update_field_settings(
|
||||
&self,
|
||||
view_id: &str,
|
||||
field_id: &str,
|
||||
visibility: Option<FieldVisibility>,
|
||||
);
|
||||
}
|
||||
|
||||
pub struct DatabaseViewEditor {
|
||||
@ -892,6 +908,30 @@ impl DatabaseViewEditor {
|
||||
.send();
|
||||
}
|
||||
|
||||
pub async fn v_get_field_settings(
|
||||
&self,
|
||||
field_ids: Vec<String>,
|
||||
) -> Result<Vec<FieldSettings>, anyhow::Error> {
|
||||
self.delegate.get_field_settings(&self.view_id, field_ids)
|
||||
}
|
||||
|
||||
pub async fn v_get_all_field_settings(&self) -> Result<Vec<FieldSettings>, anyhow::Error> {
|
||||
self.delegate.get_all_field_settings(&self.view_id)
|
||||
}
|
||||
|
||||
pub async fn v_update_field_settings(
|
||||
&self,
|
||||
view_id: &str,
|
||||
field_id: &str,
|
||||
visibility: Option<FieldVisibility>,
|
||||
) -> FlowyResult<()> {
|
||||
self
|
||||
.delegate
|
||||
.update_field_settings(view_id, field_id, visibility);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn mut_group_controller<F, T>(&self, f: F) -> Option<T>
|
||||
where
|
||||
F: FnOnce(&mut Box<dyn GroupController>, Arc<Field>) -> FlowyResult<T>,
|
||||
|
@ -0,0 +1,47 @@
|
||||
use anyhow::bail;
|
||||
use collab::core::any_map::AnyMapExtension;
|
||||
use collab_database::views::{FieldSettingsMap, FieldSettingsMapBuilder};
|
||||
|
||||
use crate::entities::FieldVisibility;
|
||||
|
||||
/// Stores the field settings for a single field
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FieldSettings {
|
||||
pub field_id: String,
|
||||
pub visibility: FieldVisibility,
|
||||
}
|
||||
|
||||
pub const VISIBILITY: &str = "visibility";
|
||||
|
||||
impl FieldSettings {
|
||||
pub fn try_from_anymap(
|
||||
field_id: String,
|
||||
field_settings: FieldSettingsMap,
|
||||
) -> Result<Self, anyhow::Error> {
|
||||
let visibility = match field_settings.get_i64_value(VISIBILITY) {
|
||||
Some(visbility) => visbility.into(),
|
||||
_ => bail!("Invalid field settings data"),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
field_id,
|
||||
visibility,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FieldSettings> for FieldSettingsMap {
|
||||
fn from(field_settings: FieldSettings) -> Self {
|
||||
FieldSettingsMapBuilder::new()
|
||||
.insert_i64_value(VISIBILITY, field_settings.visibility.into())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
/// Contains the changeset to a field's settings.
|
||||
/// A `Some` value for constitutes a change in that particular setting
|
||||
pub struct FieldSettingsChangesetParams {
|
||||
pub view_id: String,
|
||||
pub field_id: String,
|
||||
pub visibility: Option<FieldVisibility>,
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use collab_database::views::{DatabaseLayout, FieldSettingsMap, FieldSettingsMapBuilder};
|
||||
|
||||
use crate::{entities::FieldVisibility, services::field_settings::VISIBILITY};
|
||||
|
||||
/// Creates a map of the database layout and the default field settings for fields
|
||||
/// in a view of that database layout
|
||||
pub fn default_field_settings_by_layout_map() -> HashMap<DatabaseLayout, FieldSettingsMap> {
|
||||
let mut template = HashMap::new();
|
||||
for layout_ty in DatabaseLayout::iter() {
|
||||
template.insert(layout_ty, default_field_settings_by_layout(layout_ty));
|
||||
}
|
||||
|
||||
template
|
||||
}
|
||||
|
||||
/// Returns the default FieldSettingsMap for the given database layout
|
||||
pub fn default_field_settings_by_layout(layout_ty: DatabaseLayout) -> FieldSettingsMap {
|
||||
let visibility = default_visibility(layout_ty);
|
||||
FieldSettingsMapBuilder::new()
|
||||
.insert_i64_value(VISIBILITY, visibility.into())
|
||||
.build()
|
||||
}
|
||||
|
||||
/// Returns the default visibility of a field for the given database layout
|
||||
pub fn default_visibility(layout_ty: DatabaseLayout) -> FieldVisibility {
|
||||
match layout_ty {
|
||||
DatabaseLayout::Grid => FieldVisibility::AlwaysShown,
|
||||
DatabaseLayout::Board => FieldVisibility::HideWhenEmpty,
|
||||
DatabaseLayout::Calendar => FieldVisibility::HideWhenEmpty,
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
use collab_database::views::DatabaseLayout;
|
||||
|
||||
use crate::entities::FieldVisibility;
|
||||
|
||||
use crate::services::field_settings::{default_visibility, FieldSettings};
|
||||
|
||||
/// Helper struct to create a new field setting
|
||||
pub struct FieldSettingsBuilder {
|
||||
field_settings: FieldSettings,
|
||||
}
|
||||
|
||||
impl FieldSettingsBuilder {
|
||||
pub fn new(field_id: &str) -> Self {
|
||||
let field_settings = FieldSettings {
|
||||
field_id: field_id.to_string(),
|
||||
visibility: FieldVisibility::AlwaysShown,
|
||||
};
|
||||
Self { field_settings }
|
||||
}
|
||||
|
||||
pub fn from_layout_type(field_id: &str, layout_ty: DatabaseLayout) -> Self {
|
||||
let field_settings = FieldSettings {
|
||||
field_id: field_id.to_string(),
|
||||
visibility: default_visibility(layout_ty),
|
||||
};
|
||||
Self { field_settings }
|
||||
}
|
||||
|
||||
pub fn field_id(mut self, field_id: &str) -> Self {
|
||||
self.field_settings.field_id = field_id.to_string();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn visibility(mut self, visibility: FieldVisibility) -> Self {
|
||||
self.field_settings.visibility = visibility;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> FieldSettings {
|
||||
self.field_settings
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
mod entities;
|
||||
mod field_settings;
|
||||
mod field_settings_builder;
|
||||
|
||||
pub use entities::*;
|
||||
pub use field_settings::*;
|
||||
pub use field_settings_builder::*;
|
@ -2,6 +2,7 @@ pub mod cell;
|
||||
pub mod database;
|
||||
pub mod database_view;
|
||||
pub mod field;
|
||||
pub mod field_settings;
|
||||
pub mod filter;
|
||||
pub mod group;
|
||||
pub mod setting;
|
||||
|
@ -9,6 +9,7 @@ use flowy_error::{FlowyError, FlowyResult};
|
||||
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::field::{default_type_option_data_from_type, CELL_DATA};
|
||||
use crate::services::field_settings::default_field_settings_by_layout;
|
||||
use crate::services::share::csv::CSVFormat;
|
||||
|
||||
#[derive(Default)]
|
||||
@ -134,6 +135,7 @@ fn database_from_fields_and_rows(
|
||||
sorts: vec![],
|
||||
created_rows,
|
||||
fields,
|
||||
field_settings: default_field_settings_by_layout(DatabaseLayout::Grid),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ use crate::services::cell::{insert_select_option_cell, insert_text_cell};
|
||||
use crate::services::field::{
|
||||
FieldBuilder, SelectOption, SelectOptionColor, SingleSelectTypeOption,
|
||||
};
|
||||
use crate::services::field_settings::default_field_settings_by_layout;
|
||||
use crate::services::setting::CalendarLayoutSetting;
|
||||
|
||||
pub fn make_default_grid(view_id: &str, name: &str) -> CreateDatabaseParams {
|
||||
@ -41,6 +42,7 @@ pub fn make_default_grid(view_id: &str, name: &str) -> CreateDatabaseParams {
|
||||
CreateRowParams::new(gen_row_id()),
|
||||
],
|
||||
fields: vec![text_field, single_select, checkbox_field],
|
||||
field_settings: default_field_settings_by_layout(DatabaseLayout::Grid),
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,6 +94,7 @@ pub fn make_default_board(view_id: &str, name: &str) -> CreateDatabaseParams {
|
||||
sorts: vec![],
|
||||
created_rows: rows,
|
||||
fields: vec![text_field, single_select],
|
||||
field_settings: default_field_settings_by_layout(DatabaseLayout::Board),
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,5 +136,6 @@ pub fn make_default_calendar(view_id: &str, name: &str) -> CreateDatabaseParams
|
||||
sorts: vec![],
|
||||
created_rows: vec![],
|
||||
fields: vec![text_field, date_field, multi_select_field],
|
||||
field_settings: default_field_settings_by_layout(DatabaseLayout::Calendar),
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
mod script;
|
||||
mod test;
|
@ -0,0 +1,104 @@
|
||||
use flowy_database2::entities::FieldVisibility;
|
||||
use flowy_database2::services::field_settings::FieldSettingsChangesetParams;
|
||||
|
||||
use crate::database::database_editor::DatabaseEditorTest;
|
||||
|
||||
pub enum FieldSettingsScript {
|
||||
AssertFieldSettings {
|
||||
field_id: String,
|
||||
visibility: FieldVisibility,
|
||||
},
|
||||
AssertAllFieldSettings {
|
||||
visibility: FieldVisibility,
|
||||
},
|
||||
UpdateFieldSettings {
|
||||
field_id: String,
|
||||
visibility: Option<FieldVisibility>,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct FieldSettingsTest {
|
||||
inner: DatabaseEditorTest,
|
||||
}
|
||||
|
||||
impl FieldSettingsTest {
|
||||
pub async fn new_grid() -> Self {
|
||||
let inner = DatabaseEditorTest::new_grid().await;
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub async fn new_board() -> Self {
|
||||
let inner = DatabaseEditorTest::new_board().await;
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub async fn new_calendar() -> Self {
|
||||
let inner = DatabaseEditorTest::new_calendar().await;
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub async fn run_scripts(&mut self, scripts: Vec<FieldSettingsScript>) {
|
||||
for script in scripts {
|
||||
self.run_script(script).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run_script(&mut self, script: FieldSettingsScript) {
|
||||
match script {
|
||||
FieldSettingsScript::AssertFieldSettings {
|
||||
field_id,
|
||||
visibility,
|
||||
} => {
|
||||
let field_settings = self
|
||||
.editor
|
||||
.get_field_settings(&self.view_id, vec![field_id])
|
||||
.await
|
||||
.unwrap()
|
||||
.first()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
|
||||
assert_eq!(field_settings.visibility, visibility)
|
||||
},
|
||||
FieldSettingsScript::AssertAllFieldSettings { visibility } => {
|
||||
let field_settings = self
|
||||
.editor
|
||||
.get_all_field_settings(&self.view_id)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
for field_settings in field_settings.into_iter() {
|
||||
assert_eq!(field_settings.visibility, visibility)
|
||||
}
|
||||
},
|
||||
FieldSettingsScript::UpdateFieldSettings {
|
||||
field_id,
|
||||
visibility,
|
||||
} => {
|
||||
let params = FieldSettingsChangesetParams {
|
||||
view_id: self.view_id.clone(),
|
||||
field_id,
|
||||
visibility,
|
||||
};
|
||||
let _ = self
|
||||
.editor
|
||||
.update_field_settings_with_changeset(params)
|
||||
.await;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for FieldSettingsTest {
|
||||
type Target = DatabaseEditorTest;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for FieldSettingsTest {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
use collab_database::views::DatabaseLayout;
|
||||
use flowy_database2::entities::FieldType;
|
||||
use flowy_database2::entities::FieldVisibility;
|
||||
use flowy_database2::services::field_settings::default_visibility;
|
||||
|
||||
use crate::database::field_settings_test::script::FieldSettingsScript::*;
|
||||
use crate::database::field_settings_test::script::FieldSettingsTest;
|
||||
|
||||
/// Check default field settings for grid, kanban and calendar
|
||||
#[tokio::test]
|
||||
async fn get_default_field_settings() {
|
||||
let mut test = FieldSettingsTest::new_grid().await;
|
||||
let visibility = default_visibility(DatabaseLayout::Grid);
|
||||
let scripts = vec![AssertAllFieldSettings { visibility }];
|
||||
test.run_scripts(scripts).await;
|
||||
|
||||
let mut test = FieldSettingsTest::new_board().await;
|
||||
let visibility = default_visibility(DatabaseLayout::Board);
|
||||
let scripts = vec![AssertAllFieldSettings { visibility }];
|
||||
test.run_scripts(scripts).await;
|
||||
|
||||
let mut test = FieldSettingsTest::new_calendar().await;
|
||||
let visibility = default_visibility(DatabaseLayout::Calendar);
|
||||
let scripts = vec![AssertAllFieldSettings { visibility }];
|
||||
test.run_scripts(scripts).await;
|
||||
}
|
||||
|
||||
/// Update field settings for a field
|
||||
#[tokio::test]
|
||||
async fn update_field_settings_test() {
|
||||
let mut test = FieldSettingsTest::new_grid().await;
|
||||
let checkbox_field = test.get_first_field(FieldType::Checkbox);
|
||||
let text_field = test.get_first_field(FieldType::RichText);
|
||||
let visibility = default_visibility(DatabaseLayout::Grid);
|
||||
let new_visibility = FieldVisibility::AlwaysHidden;
|
||||
|
||||
let scripts = vec![
|
||||
AssertAllFieldSettings {
|
||||
visibility: visibility.clone(),
|
||||
},
|
||||
UpdateFieldSettings {
|
||||
field_id: checkbox_field.id.clone(),
|
||||
visibility: Some(new_visibility.clone()),
|
||||
},
|
||||
AssertFieldSettings {
|
||||
field_id: checkbox_field.id,
|
||||
visibility: new_visibility,
|
||||
},
|
||||
AssertFieldSettings {
|
||||
field_id: text_field.id,
|
||||
visibility,
|
||||
},
|
||||
];
|
||||
test.run_scripts(scripts).await;
|
||||
}
|
@ -1,9 +1,6 @@
|
||||
// #![allow(clippy::all)]
|
||||
// #![allow(dead_code)]
|
||||
// #![allow(unused_imports)]
|
||||
|
||||
use collab_database::database::{gen_database_id, gen_database_view_id, gen_row_id, DatabaseData};
|
||||
use collab_database::views::{DatabaseLayout, DatabaseView};
|
||||
use flowy_database2::services::field_settings::default_field_settings_by_layout;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use flowy_database2::entities::FieldType;
|
||||
@ -21,6 +18,7 @@ pub fn make_test_board() -> DatabaseData {
|
||||
let mut fields = vec![];
|
||||
let mut rows = vec![];
|
||||
// Iterate through the FieldType to create the corresponding Field.
|
||||
let field_settings = default_field_settings_by_layout(DatabaseLayout::Board);
|
||||
for field_type in FieldType::iter() {
|
||||
match field_type {
|
||||
FieldType::RichText => {
|
||||
@ -238,6 +236,7 @@ pub fn make_test_board() -> DatabaseData {
|
||||
field_orders: vec![],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
field_settings,
|
||||
};
|
||||
DatabaseData { view, fields, rows }
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use collab_database::database::{gen_database_id, gen_database_view_id, gen_row_id, DatabaseData};
|
||||
use collab_database::views::{DatabaseLayout, DatabaseView, LayoutSetting, LayoutSettings};
|
||||
use flowy_database2::services::field_settings::default_field_settings_by_layout;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use flowy_database2::entities::FieldType;
|
||||
@ -12,6 +13,8 @@ use crate::database::database_editor::TestRowBuilder;
|
||||
pub fn make_test_calendar() -> DatabaseData {
|
||||
let mut fields = vec![];
|
||||
let mut rows = vec![];
|
||||
let field_settings = default_field_settings_by_layout(DatabaseLayout::Calendar);
|
||||
|
||||
// text
|
||||
let text_field = FieldBuilder::from_field_type(FieldType::RichText)
|
||||
.name("Name")
|
||||
@ -25,7 +28,6 @@ pub fn make_test_calendar() -> DatabaseData {
|
||||
.name("Date")
|
||||
.visibility(true)
|
||||
.build();
|
||||
|
||||
let date_field_id = date_field.id.clone();
|
||||
fields.push(date_field);
|
||||
|
||||
@ -120,6 +122,7 @@ pub fn make_test_calendar() -> DatabaseData {
|
||||
field_orders: vec![],
|
||||
created_at: 0,
|
||||
modified_at: 0,
|
||||
field_settings,
|
||||
};
|
||||
|
||||
DatabaseData { view, fields, rows }
|
||||
|
@ -1,5 +1,6 @@
|
||||
use collab_database::database::{gen_database_id, gen_database_view_id, gen_row_id, DatabaseData};
|
||||
use collab_database::views::{DatabaseLayout, DatabaseView};
|
||||
use flowy_database2::services::field_settings::default_field_settings_by_layout;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use flowy_database2::entities::FieldType;
|
||||
@ -15,6 +16,7 @@ use crate::database::mock_data::{COMPLETED, FACEBOOK, GOOGLE, PAUSED, PLANNED, T
|
||||
pub fn make_test_grid() -> DatabaseData {
|
||||
let mut fields = vec![];
|
||||
let mut rows = vec![];
|
||||
let field_settings = default_field_settings_by_layout(DatabaseLayout::Grid);
|
||||
// Iterate through the FieldType to create the corresponding Field.
|
||||
for field_type in FieldType::iter() {
|
||||
match field_type {
|
||||
@ -238,10 +240,11 @@ pub fn make_test_grid() -> DatabaseData {
|
||||
}
|
||||
|
||||
let view = DatabaseView {
|
||||
id: gen_database_view_id(),
|
||||
database_id: gen_database_id(),
|
||||
id: gen_database_id(),
|
||||
database_id: gen_database_view_id(),
|
||||
name: "".to_string(),
|
||||
layout: DatabaseLayout::Grid,
|
||||
field_settings,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@ -251,6 +254,7 @@ pub fn make_test_grid() -> DatabaseData {
|
||||
pub fn make_no_date_test_grid() -> DatabaseData {
|
||||
let mut fields = vec![];
|
||||
let mut rows = vec![];
|
||||
let field_settings = default_field_settings_by_layout(DatabaseLayout::Grid);
|
||||
// Iterate through the FieldType to create the corresponding Field.
|
||||
for field_type in FieldType::iter() {
|
||||
match field_type {
|
||||
@ -319,6 +323,7 @@ pub fn make_no_date_test_grid() -> DatabaseData {
|
||||
database_id: gen_database_id(),
|
||||
name: "".to_string(),
|
||||
layout: DatabaseLayout::Grid,
|
||||
field_settings,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
mod block_test;
|
||||
mod cell_test;
|
||||
mod database_editor;
|
||||
mod field_settings_test;
|
||||
mod field_test;
|
||||
mod filter_test;
|
||||
mod group_test;
|
||||
|
Loading…
Reference in New Issue
Block a user