chore: move type option to collab repo (#6921)

* chore: bump collab

* chore: bump collab

* chore: fix test compile

* chore: fix test

* chore: remove numeric

* chore: fix media type option
This commit is contained in:
Nathan.fooo 2024-12-05 14:12:25 +08:00 committed by GitHub
parent 92945cafdf
commit dddf5aa195
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
59 changed files with 298 additions and 884 deletions

View file

@ -1030,7 +1030,7 @@ dependencies = [
[[package]]
name = "collab"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"arc-swap",
@ -1055,7 +1055,7 @@ dependencies = [
[[package]]
name = "collab-database"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"async-trait",
@ -1094,7 +1094,7 @@ dependencies = [
[[package]]
name = "collab-document"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"arc-swap",
@ -1115,7 +1115,7 @@ dependencies = [
[[package]]
name = "collab-entity"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"bytes",
@ -1135,7 +1135,7 @@ dependencies = [
[[package]]
name = "collab-folder"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"arc-swap",
@ -1157,7 +1157,7 @@ dependencies = [
[[package]]
name = "collab-importer"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"async-recursion",
@ -1218,7 +1218,7 @@ dependencies = [
[[package]]
name = "collab-plugins"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"async-stream",
@ -1298,7 +1298,7 @@ dependencies = [
[[package]]
name = "collab-user"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"collab",

View file

@ -120,14 +120,14 @@ custom-protocol = ["tauri/custom-protocol"]
# 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 = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-importer = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-importer = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
# Working directory: frontend
# To update the commit ID, run:

View file

@ -1028,7 +1028,7 @@ dependencies = [
[[package]]
name = "collab"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"arc-swap",
@ -1053,7 +1053,7 @@ dependencies = [
[[package]]
name = "collab-database"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"async-trait",
@ -1092,7 +1092,7 @@ dependencies = [
[[package]]
name = "collab-document"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"arc-swap",
@ -1113,7 +1113,7 @@ dependencies = [
[[package]]
name = "collab-entity"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"bytes",
@ -1133,7 +1133,7 @@ dependencies = [
[[package]]
name = "collab-folder"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"arc-swap",
@ -1155,7 +1155,7 @@ dependencies = [
[[package]]
name = "collab-importer"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"async-recursion",
@ -1216,7 +1216,7 @@ dependencies = [
[[package]]
name = "collab-plugins"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"async-stream",
@ -1296,7 +1296,7 @@ dependencies = [
[[package]]
name = "collab-user"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"collab",

View file

@ -118,14 +118,14 @@ custom-protocol = ["tauri/custom-protocol"]
# 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 = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-importer = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-importer = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
# Working directory: frontend

View file

@ -891,7 +891,7 @@ dependencies = [
[[package]]
name = "collab"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"arc-swap",
@ -916,7 +916,7 @@ dependencies = [
[[package]]
name = "collab-database"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"async-trait",
@ -955,7 +955,7 @@ dependencies = [
[[package]]
name = "collab-document"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"arc-swap",
@ -976,7 +976,7 @@ dependencies = [
[[package]]
name = "collab-entity"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"bytes",
@ -996,7 +996,7 @@ dependencies = [
[[package]]
name = "collab-folder"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"arc-swap",
@ -1018,7 +1018,7 @@ dependencies = [
[[package]]
name = "collab-importer"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"async-recursion",
@ -1079,7 +1079,7 @@ dependencies = [
[[package]]
name = "collab-plugins"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"async-stream",
@ -1159,7 +1159,7 @@ dependencies = [
[[package]]
name = "collab-user"
version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0efc824a6e1a56e4485646e6428c07fdccf6e918#0efc824a6e1a56e4485646e6428c07fdccf6e918"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=8bd376c0c71ce366d763a70385c7b445a98241ed#8bd376c0c71ce366d763a70385c7b445a98241ed"
dependencies = [
"anyhow",
"collab",

View file

@ -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 = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab-importer = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "0efc824a6e1a56e4485646e6428c07fdccf6e918" }
collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
collab-importer = { version = "0.1", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "8bd376c0c71ce366d763a70385c7b445a98241ed" }
# Working directory: frontend
# To update the commit ID, run:

View file

@ -11,7 +11,7 @@ use collab_database::rows::{Row, RowId};
use flowy_database2::entities::*;
use flowy_database2::event_map::DatabaseEvent;
use flowy_database2::services::cell::CellBuilder;
use flowy_database2::services::field::ChecklistCellInsertChangeset;
use flowy_database2::services::field::checklist_filter::ChecklistCellInsertChangeset;
use flowy_database2::services::share::csv::CSVFormat;
use flowy_folder::entities::*;
use flowy_folder::event_map::FolderEvent;

View file

@ -1,8 +1,8 @@
use collab_database::fields::relation_type_option::RelationTypeOption;
use collab_database::template::relation_parse::RelationCellData;
use flowy_derive::ProtoBuf;
use crate::entities::CellIdPB;
use crate::services::field::RelationCellData;
#[derive(Debug, Clone, Default, ProtoBuf)]
pub struct RelationCellDataPB {

View file

@ -45,6 +45,7 @@ impl From<TimestampTypeOptionPB> for TimestampTypeOption {
time_format: data.time_format.into(),
include_time: data.include_time,
field_type: data.field_type.into(),
timezone: None,
}
}
}

View file

@ -10,9 +10,10 @@ use lib_dispatch::prelude::{af_spawn, data_result_ok, AFPluginData, AFPluginStat
use crate::entities::*;
use crate::manager::DatabaseManager;
use crate::services::field::checklist_filter::ChecklistCellChangeset;
use crate::services::field::date_filter::DateCellChangeset;
use crate::services::field::{
type_option_data_from_pb, ChecklistCellChangeset, DateCellChangeset, RelationCellChangeset,
SelectOptionCellChangeset, TypeOptionCellExt,
type_option_data_from_pb, RelationCellChangeset, SelectOptionCellChangeset, TypeOptionCellExt,
};
use crate::services::group::GroupChangeset;
use crate::services::share::csv::CSVFormat;

View file

@ -95,7 +95,7 @@ impl CalculationsService {
if let Some(handler) = TypeOptionCellExt::new(field, None).get_type_option_cell_data_handler() {
let empty_count = cells
.par_iter()
.filter(|cell| handler.handle_is_cell_empty(cell, field))
.filter(|cell| handler.handle_is_empty(cell, field))
.count();
empty_count.to_string()
} else {
@ -107,7 +107,7 @@ impl CalculationsService {
if let Some(handler) = TypeOptionCellExt::new(field, None).get_type_option_cell_data_handler() {
let non_empty_count = cells
.par_iter()
.filter(|cell| !handler.handle_is_cell_empty(cell, field))
.filter(|cell| !handler.handle_is_empty(cell, field))
.count();
non_empty_count.to_string()
} else {

View file

@ -5,12 +5,17 @@ use collab_database::fields::media_type_option::MediaCellData;
use collab_database::fields::select_type_option::SelectOptionIds;
use collab_database::fields::Field;
use collab_database::rows::{get_field_type_from_cell, Cell, Cells};
use collab_database::template::relation_parse::RelationCellData;
use flowy_error::{FlowyError, FlowyResult};
use lib_infra::box_any::BoxAny;
use tracing::trace;
use crate::entities::{CheckboxCellDataPB, FieldType};
use crate::services::cell::{CellCache, CellProtobufBlob};
use crate::services::field::checklist_filter::{
ChecklistCellChangeset, ChecklistCellInsertChangeset,
};
use crate::services::field::date_filter::DateCellChangeset;
use crate::services::field::*;
use crate::services::group::make_no_status_group;
@ -24,7 +29,9 @@ pub trait CellDataDecoder: TypeOption {
///
/// * `cell`: the cell to be decoded
///
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData>;
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(Self::CellData::from(cell))
}
/// Decodes the [Cell] that is of a particular field type into a `CellData` of this `TypeOption`'s field type.
///
@ -48,12 +55,6 @@ pub trait CellDataDecoder: TypeOption {
/// separated by a comma.
///
fn stringify_cell_data(&self, cell_data: <Self as TypeOption>::CellData) -> String;
/// Decode the cell into f64
/// Different field type has different way to decode the cell data into f64
/// If the field type doesn't support to decode the cell data into f64, it will return None
///
fn numeric_cell(&self, cell: &Cell) -> Option<f64>;
}
pub trait CellDataChangeset: TypeOption {
@ -223,6 +224,7 @@ impl<'a> CellBuilder<'a> {
for (field_id, cell_str) in cell_by_field_id {
if let Some(field) = field_maps.get(&field_id) {
let field_type = FieldType::from(field.field_type);
trace!("Field type: {:?}, cell_str: {}", field_type, cell_str);
match field_type {
FieldType::RichText | FieldType::Translate | FieldType::Summary => {
cells.insert(field_id, insert_text_cell(cell_str, field));
@ -262,10 +264,14 @@ impl<'a> CellBuilder<'a> {
}
},
FieldType::Relation => {
cells.insert(field_id, (&RelationCellData::from(cell_str)).into());
if let Ok(cell_data) = RelationCellData::from_str(&cell_str) {
cells.insert(field_id, cell_data.into());
}
},
FieldType::Media => {
cells.insert(field_id, MediaCellData::from(cell_str).into());
if let Ok(cell_data) = MediaCellData::from_str(&cell_str) {
cells.insert(field_id, cell_data.into());
}
},
}
}

View file

@ -7,11 +7,11 @@ use crate::services::database::util::database_view_setting_pb_from_view;
use crate::services::database_view::{
DatabaseViewChanged, DatabaseViewEditor, DatabaseViewOperation, DatabaseViews, EditorByViewId,
};
use crate::services::field::checklist_filter::ChecklistCellChangeset;
use crate::services::field::type_option_transform::transform_type_option;
use crate::services::field::{
default_type_option_data_from_type, select_type_option_from_field, type_option_data_from_pb,
ChecklistCellChangeset, SelectOptionCellChangeset, StringCellData, TimestampCellData,
TimestampCellDataWrapper, TypeOptionCellDataHandler, TypeOptionCellExt,
SelectOptionCellChangeset, StringCellData, TypeOptionCellDataHandler, TypeOptionCellExt,
};
use crate::services::field_settings::{default_field_settings_by_layout_map, FieldSettings};
use crate::services::filter::{Filter, FilterChangeset};
@ -30,6 +30,7 @@ use collab_database::fields::media_type_option::MediaCellData;
use collab_database::fields::relation_type_option::RelationTypeOption;
use collab_database::fields::{Field, TypeOptionData};
use collab_database::rows::{Cell, Cells, DatabaseRow, Row, RowCell, RowDetail, RowId, RowUpdate};
use collab_database::template::timestamp_parse::TimestampCellData;
use collab_database::views::{
DatabaseLayout, FilterMap, LayoutSetting, OrderObjectPosition, RowOrder,
};
@ -891,12 +892,12 @@ impl DatabaseEditor {
match field_type {
FieldType::LastEditedTime | FieldType::CreatedTime => {
let row = database.get_row(row_id).await;
let wrapped_cell_data = if field_type.is_created_time() {
TimestampCellDataWrapper::from((field_type, TimestampCellData::new(row.created_at)))
let cell_data = if field_type.is_created_time() {
TimestampCellData::new(row.created_at)
} else {
TimestampCellDataWrapper::from((field_type, TimestampCellData::new(row.modified_at)))
TimestampCellData::new(row.modified_at)
};
Some(Cell::from(wrapped_cell_data))
Some(cell_data.to_cell(field.field_type))
},
_ => database.get_cell(field_id, row_id).await.cell,
}
@ -938,7 +939,7 @@ impl DatabaseEditor {
};
Some(RowCell {
row_id: row.id,
cell: Some(Cell::from(data)),
cell: Some(data.to_cell(field.field_type)),
})
},
Err(_) => None,

View file

@ -10,7 +10,7 @@ use flowy_error::FlowyResult;
use crate::entities::{CheckboxCellDataPB, CheckboxFilterPB, FieldType};
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
use crate::services::field::{
TypeOption, TypeOptionCellDataCompare, TypeOptionCellDataFilter, TypeOptionCellDataSerde,
CellDataProtobufEncoder, TypeOption, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionTransform,
};
use crate::services::sort::SortCondition;
@ -24,24 +24,16 @@ impl TypeOption for CheckboxTypeOption {
impl TypeOptionTransform for CheckboxTypeOption {}
impl TypeOptionCellDataSerde for CheckboxTypeOption {
impl CellDataProtobufEncoder for CheckboxTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
) -> <Self as TypeOption>::CellProtobufType {
cell_data
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(CheckboxCellDataPB::from(cell))
}
}
impl CellDataDecoder for CheckboxTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
self.parse_cell(cell)
}
fn decode_cell_with_transform(
&self,
cell: &Cell,
@ -58,15 +50,6 @@ impl CellDataDecoder for CheckboxTypeOption {
fn stringify_cell_data(&self, cell_data: <Self as TypeOption>::CellData) -> String {
cell_data.to_string()
}
fn numeric_cell(&self, cell: &Cell) -> Option<f64> {
let cell_data = self.parse_cell(cell).ok()?;
if cell_data.is_checked {
Some(1.0)
} else {
Some(0.0)
}
}
}
pub type CheckboxCellChangeset = String;

View file

@ -1,143 +0,0 @@
use crate::entities::{ChecklistCellDataChangesetPB, FieldType};
use crate::services::field::{TypeOptionCellData, CELL_DATA};
use collab::util::AnyMapExt;
use collab_database::fields::select_type_option::SelectOption;
use collab_database::rows::{new_cell_builder, Cell};
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
pub struct ChecklistCellData {
pub options: Vec<SelectOption>,
pub selected_option_ids: Vec<String>,
}
impl ToString for ChecklistCellData {
fn to_string(&self) -> String {
serde_json::to_string(self).unwrap_or_default()
}
}
impl TypeOptionCellData for ChecklistCellData {
fn is_cell_empty(&self) -> bool {
self.options.is_empty()
}
}
impl ChecklistCellData {
pub fn selected_options(&self) -> Vec<SelectOption> {
self
.options
.iter()
.filter(|option| self.selected_option_ids.contains(&option.id))
.cloned()
.collect()
}
pub fn percentage_complete(&self) -> f64 {
let selected_options = self.selected_option_ids.len();
let total_options = self.options.len();
if total_options == 0 {
return 0.0;
}
((selected_options as f64) / (total_options as f64) * 100.0).round() / 100.0
}
pub fn from_options(new_tasks: Vec<ChecklistCellInsertChangeset>) -> Self {
let (options, selected_ids): (Vec<_>, Vec<_>) = new_tasks
.into_iter()
.map(|new_task| {
let option = SelectOption::new(&new_task.name);
let selected_id = new_task.is_complete.then(|| option.id.clone());
(option, selected_id)
})
.unzip();
let selected_option_ids = selected_ids.into_iter().flatten().collect();
Self {
options,
selected_option_ids,
}
}
}
impl From<&Cell> for ChecklistCellData {
fn from(cell: &Cell) -> Self {
cell
.get_as::<String>(CELL_DATA)
.map(|data| serde_json::from_str::<ChecklistCellData>(&data).unwrap_or_default())
.unwrap_or_default()
}
}
impl From<ChecklistCellData> for Cell {
fn from(cell_data: ChecklistCellData) -> Self {
let data = serde_json::to_string(&cell_data).unwrap_or_default();
let mut cell = new_cell_builder(FieldType::Checklist);
cell.insert(CELL_DATA.into(), data.into());
cell
}
}
#[derive(Debug, Clone, Default)]
pub struct ChecklistCellChangeset {
pub insert_tasks: Vec<ChecklistCellInsertChangeset>,
pub delete_tasks: Vec<String>,
pub update_tasks: Vec<SelectOption>,
pub completed_task_ids: Vec<String>,
pub reorder: String,
}
impl From<ChecklistCellDataChangesetPB> for ChecklistCellChangeset {
fn from(value: ChecklistCellDataChangesetPB) -> Self {
ChecklistCellChangeset {
insert_tasks: value
.insert_task
.into_iter()
.map(|pb| ChecklistCellInsertChangeset {
name: pb.name,
is_complete: false,
index: pb.index,
})
.collect(),
delete_tasks: value.delete_tasks,
update_tasks: value
.update_tasks
.into_iter()
.map(SelectOption::from)
.collect(),
completed_task_ids: value.completed_tasks,
reorder: value.reorder,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct ChecklistCellInsertChangeset {
pub name: String,
pub is_complete: bool,
pub index: Option<i32>,
}
impl ChecklistCellInsertChangeset {
pub fn new(name: String, is_complete: bool) -> Self {
Self {
name,
is_complete,
index: None,
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn test() {
let a = 1;
let b = 2;
let c = (a as f32) / (b as f32);
println!("{}", c);
}
}

View file

@ -1,9 +1,13 @@
use crate::entities::ChecklistCellDataChangesetPB;
use crate::entities::{ChecklistFilterConditionPB, ChecklistFilterPB};
use crate::services::filter::PreFillCellsWithFilter;
use collab_database::fields::select_type_option::SelectOption;
use collab_database::fields::Field;
use collab_database::rows::Cell;
use collab_database::template::check_list_parse::ChecklistCellData;
use crate::entities::{ChecklistFilterConditionPB, ChecklistFilterPB};
use crate::services::filter::PreFillCellsWithFilter;
use std::fmt::Debug;
impl ChecklistFilterPB {
pub fn is_visible(
@ -47,3 +51,82 @@ impl PreFillCellsWithFilter for ChecklistFilterPB {
None
}
}
pub fn checklist_from_options(new_tasks: Vec<ChecklistCellInsertChangeset>) -> ChecklistCellData {
let (options, selected_ids): (Vec<_>, Vec<_>) = new_tasks
.into_iter()
.map(|new_task| {
let option = SelectOption::new(&new_task.name);
let selected_id = new_task.is_complete.then(|| option.id.clone());
(option, selected_id)
})
.unzip();
let selected_option_ids = selected_ids.into_iter().flatten().collect();
ChecklistCellData {
options,
selected_option_ids,
}
}
#[derive(Debug, Clone, Default)]
pub struct ChecklistCellChangeset {
pub insert_tasks: Vec<ChecklistCellInsertChangeset>,
pub delete_tasks: Vec<String>,
pub update_tasks: Vec<SelectOption>,
pub completed_task_ids: Vec<String>,
pub reorder: String,
}
impl From<ChecklistCellDataChangesetPB> for ChecklistCellChangeset {
fn from(value: ChecklistCellDataChangesetPB) -> Self {
ChecklistCellChangeset {
insert_tasks: value
.insert_task
.into_iter()
.map(|pb| ChecklistCellInsertChangeset {
name: pb.name,
is_complete: false,
index: pb.index,
})
.collect(),
delete_tasks: value.delete_tasks,
update_tasks: value
.update_tasks
.into_iter()
.map(SelectOption::from)
.collect(),
completed_task_ids: value.completed_tasks,
reorder: value.reorder,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct ChecklistCellInsertChangeset {
pub name: String,
pub is_complete: bool,
pub index: Option<i32>,
}
impl ChecklistCellInsertChangeset {
pub fn new(name: String, is_complete: bool) -> Self {
Self {
name,
is_complete,
index: None,
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn test() {
let a = 1;
let b = 2;
let c = (a as f32) / (b as f32);
println!("{}", c);
}
}

View file

@ -1,14 +1,16 @@
use crate::entities::{ChecklistCellDataPB, ChecklistFilterPB, SelectOptionPB};
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
use crate::services::field::checklist_type_option::{ChecklistCellChangeset, ChecklistCellData};
use crate::services::field::checklist_filter::{checklist_from_options, ChecklistCellChangeset};
use crate::services::field::{
TypeOption, TypeOptionCellData, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionCellDataSerde, TypeOptionTransform,
CellDataProtobufEncoder, TypeOption, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionTransform,
};
use crate::services::sort::SortCondition;
use collab_database::fields::checklist_type_option::ChecklistTypeOption;
use collab_database::fields::select_type_option::{SelectOption, SELECTION_IDS_SEPARATOR};
use collab_database::rows::Cell;
use collab_database::template::check_list_parse::ChecklistCellData;
use collab_database::template::util::TypeOptionCellData;
use flowy_error::FlowyResult;
use std::cmp::Ordering;
@ -19,7 +21,7 @@ impl TypeOption for ChecklistTypeOption {
type CellFilter = ChecklistFilterPB;
}
impl TypeOptionCellDataSerde for ChecklistTypeOption {
impl CellDataProtobufEncoder for ChecklistTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
@ -44,10 +46,6 @@ impl TypeOptionCellDataSerde for ChecklistTypeOption {
percentage,
}
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(ChecklistCellData::from(cell))
}
}
impl CellDataChangeset for ChecklistTypeOption {
@ -58,12 +56,12 @@ impl CellDataChangeset for ChecklistTypeOption {
) -> FlowyResult<(Cell, <Self as TypeOption>::CellData)> {
match cell {
Some(cell) => {
let mut cell_data = self.parse_cell(&cell)?;
let mut cell_data = self.decode_cell(&cell)?;
update_cell_data_with_changeset(&mut cell_data, changeset);
Ok((Cell::from(cell_data.clone()), cell_data))
},
None => {
let cell_data = ChecklistCellData::from_options(changeset.insert_tasks);
let cell_data = checklist_from_options(changeset.insert_tasks);
Ok((Cell::from(cell_data.clone()), cell_data))
},
}
@ -142,10 +140,6 @@ fn update_cell_data_with_changeset(
}
impl CellDataDecoder for ChecklistTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
self.parse_cell(cell)
}
fn stringify_cell_data(&self, cell_data: <Self as TypeOption>::CellData) -> String {
cell_data
.options
@ -154,11 +148,6 @@ impl CellDataDecoder for ChecklistTypeOption {
.collect::<Vec<_>>()
.join(SELECTION_IDS_SEPARATOR)
}
fn numeric_cell(&self, _cell: &Cell) -> Option<f64> {
// return the percentage complete if needed
None
}
}
impl TypeOptionCellDataFilter for ChecklistTypeOption {

View file

@ -1,6 +1,3 @@
#![allow(clippy::module_inception)]
mod checklist_entities;
mod checklist_filter;
mod checklist_type_option;
pub use checklist_entities::*;
pub mod checklist_filter;
pub mod checklist_type_option;

View file

@ -1,12 +1,17 @@
use crate::entities::{DateFilterConditionPB, DateFilterPB};
use crate::services::cell::insert_date_cell;
use crate::services::field::TimestampCellData;
use crate::services::filter::PreFillCellsWithFilter;
use bytes::Bytes;
use chrono::{Duration, Local, NaiveDate, TimeZone};
use collab_database::fields::date_type_option::DateCellData;
use collab_database::fields::Field;
use collab_database::rows::Cell;
use collab_database::template::timestamp_parse::TimestampCellData;
use flowy_error::{internal_error, FlowyResult};
use crate::entities::DateCellDataPB;
use crate::services::cell::CellProtobufBlobParser;
impl DateFilterPB {
/// Returns `None` if the DateFilterPB doesn't have the necessary data for
@ -179,6 +184,25 @@ impl PreFillCellsWithFilter for DateFilterPB {
}
}
#[derive(Clone, Debug, Default)]
pub struct DateCellChangeset {
pub timestamp: Option<i64>,
pub end_timestamp: Option<i64>,
pub include_time: Option<bool>,
pub is_range: Option<bool>,
pub clear_flag: Option<bool>,
pub reminder_id: Option<String>,
}
pub struct DateCellDataParser();
impl CellProtobufBlobParser for DateCellDataParser {
type Object = DateCellDataPB;
fn parser(bytes: &Bytes) -> FlowyResult<Self::Object> {
DateCellDataPB::try_from(bytes.as_ref()).map_err(internal_error)
}
}
#[cfg(test)]
mod tests {
use crate::entities::{DateFilterConditionPB, DateFilterPB};

View file

@ -3,7 +3,7 @@ mod tests {
use collab_database::rows::Cell;
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
use crate::services::field::DateCellChangeset;
use crate::services::field::date_type_option::date_filter::DateCellChangeset;
use collab_database::fields::date_type_option::{DateCellData, DateTypeOption};
#[test]

View file

@ -12,9 +12,10 @@ use tracing::info;
use crate::entities::{DateCellDataPB, DateFilterPB, FieldType};
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
use crate::services::field::date_type_option::date_filter::DateCellChangeset;
use crate::services::field::{
default_order, DateCellChangeset, TypeOption, TypeOptionCellDataCompare,
TypeOptionCellDataFilter, TypeOptionCellDataSerde, TypeOptionTransform, CELL_DATA,
default_order, CellDataProtobufEncoder, TypeOption, TypeOptionCellDataCompare,
TypeOptionCellDataFilter, TypeOptionTransform, CELL_DATA,
};
use crate::services::sort::SortCondition;
@ -25,7 +26,7 @@ impl TypeOption for DateTypeOption {
type CellFilter = DateFilterPB;
}
impl TypeOptionCellDataSerde for DateTypeOption {
impl CellDataProtobufEncoder for DateTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
@ -50,10 +51,6 @@ impl TypeOptionCellDataSerde for DateTypeOption {
reminder_id,
}
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(DateCellData::from(cell))
}
}
#[async_trait]
@ -104,10 +101,6 @@ impl TypeOptionTransform for DateTypeOption {
}
impl CellDataDecoder for DateTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
self.parse_cell(cell)
}
fn stringify_cell_data(&self, cell_data: <Self as TypeOption>::CellData) -> String {
let include_time = cell_data.include_time;
let timestamp = cell_data.timestamp;
@ -146,10 +139,6 @@ impl CellDataDecoder for DateTypeOption {
let timestamp = cast_string_to_timestamp(&s)?;
Some(DateCellData::from_timestamp(timestamp))
}
fn numeric_cell(&self, _cell: &Cell) -> Option<f64> {
None
}
}
impl CellDataChangeset for DateTypeOption {

View file

@ -1,33 +0,0 @@
#![allow(clippy::upper_case_acronyms)]
use bytes::Bytes;
use collab_database::fields::date_type_option::DateCellData;
use flowy_error::{internal_error, FlowyResult};
use crate::entities::DateCellDataPB;
use crate::services::cell::CellProtobufBlobParser;
use crate::services::field::TypeOptionCellData;
#[derive(Clone, Debug, Default)]
pub struct DateCellChangeset {
pub timestamp: Option<i64>,
pub end_timestamp: Option<i64>,
pub include_time: Option<bool>,
pub is_range: Option<bool>,
pub clear_flag: Option<bool>,
pub reminder_id: Option<String>,
}
impl TypeOptionCellData for DateCellData {
fn is_cell_empty(&self) -> bool {
self.timestamp.is_none()
}
}
pub struct DateCellDataParser();
impl CellProtobufBlobParser for DateCellDataParser {
type Object = DateCellDataPB;
fn parser(bytes: &Bytes) -> FlowyResult<Self::Object> {
DateCellDataPB::try_from(bytes.as_ref()).map_err(internal_error)
}
}

View file

@ -1,7 +1,4 @@
#![allow(clippy::module_inception)]
mod date_filter;
pub mod date_filter;
mod date_tests;
mod date_type_option;
mod date_type_option_entities;
pub use date_type_option_entities::*;
pub mod date_type_option;

View file

@ -8,19 +8,13 @@ use crate::{
services::{
cell::{CellDataChangeset, CellDataDecoder},
field::{
default_order, StringCellData, TypeOption, TypeOptionCellData, TypeOptionCellDataCompare,
TypeOptionCellDataFilter, TypeOptionCellDataSerde, TypeOptionTransform,
default_order, CellDataProtobufEncoder, TypeOption, TypeOptionCellData,
TypeOptionCellDataCompare, TypeOptionCellDataFilter, TypeOptionTransform,
},
sort::SortCondition,
},
};
impl TypeOptionCellData for MediaCellData {
fn is_cell_empty(&self) -> bool {
self.files.is_empty()
}
}
impl TypeOption for MediaTypeOption {
type CellData = MediaCellData;
type CellChangeset = MediaCellChangeset;
@ -30,24 +24,16 @@ impl TypeOption for MediaTypeOption {
impl TypeOptionTransform for MediaTypeOption {}
impl TypeOptionCellDataSerde for MediaTypeOption {
impl CellDataProtobufEncoder for MediaTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
) -> <Self as TypeOption>::CellProtobufType {
cell_data.into()
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(cell.into())
}
}
impl CellDataDecoder for MediaTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
self.parse_cell(cell)
}
fn decode_cell_with_transform(
&self,
_cell: &Cell,
@ -76,10 +62,6 @@ impl CellDataDecoder for MediaTypeOption {
fn stringify_cell_data(&self, cell_data: <Self as TypeOption>::CellData) -> String {
cell_data.to_string()
}
fn numeric_cell(&self, cell: &Cell) -> Option<f64> {
StringCellData::from(cell).0.parse::<f64>().ok()
}
}
impl CellDataChangeset for MediaTypeOption {

View file

@ -24,7 +24,7 @@ pub use relation_type_option::*;
pub use selection_type_option::*;
pub use text_type_option::*;
pub use time_type_option::*;
pub use timestamp_type_option::*;
pub use type_option::*;
pub use type_option_cell::*;
pub use url_type_option::*;

View file

@ -1,18 +1,17 @@
use async_trait::async_trait;
use collab::util::AnyMapExt;
use collab_database::database::Database;
use collab_database::fields::number_type_option::{
NumberCellFormat, NumberFormat, NumberTypeOption,
};
use collab_database::fields::{Field, TypeOptionData};
use collab_database::rows::{new_cell_builder, Cell};
use collab_database::rows::Cell;
use fancy_regex::Regex;
use flowy_error::FlowyResult;
use lazy_static::lazy_static;
use collab_database::template::number_parse::NumberCellData;
use std::cmp::Ordering;
use std::default::Default;
use tracing::info;
@ -20,52 +19,11 @@ use crate::entities::{FieldType, NumberFilterPB};
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
use crate::services::field::type_options::util::ProtobufStr;
use crate::services::field::{
TypeOption, TypeOptionCellData, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionCellDataSerde, TypeOptionTransform, CELL_DATA,
CellDataProtobufEncoder, TypeOption, TypeOptionCellData, TypeOptionCellDataCompare,
TypeOptionCellDataFilter, TypeOptionTransform,
};
use crate::services::sort::SortCondition;
#[derive(Clone, Debug, Default)]
pub struct NumberCellData(pub String);
impl TypeOptionCellData for NumberCellData {
fn is_cell_empty(&self) -> bool {
self.0.is_empty()
}
}
impl AsRef<str> for NumberCellData {
fn as_ref(&self) -> &str {
&self.0
}
}
impl From<&Cell> for NumberCellData {
fn from(cell: &Cell) -> Self {
Self(cell.get_as(CELL_DATA).unwrap_or_default())
}
}
impl From<NumberCellData> for Cell {
fn from(data: NumberCellData) -> Self {
let mut cell = new_cell_builder(FieldType::Number);
cell.insert(CELL_DATA.into(), data.0.into());
cell
}
}
impl std::convert::From<String> for NumberCellData {
fn from(s: String) -> Self {
Self(s)
}
}
impl ToString for NumberCellData {
fn to_string(&self) -> String {
self.0.clone()
}
}
impl TypeOption for NumberTypeOption {
type CellData = NumberCellData;
type CellChangeset = NumberCellChangeset;
@ -73,17 +31,13 @@ impl TypeOption for NumberTypeOption {
type CellFilter = NumberFilterPB;
}
impl TypeOptionCellDataSerde for NumberTypeOption {
impl CellDataProtobufEncoder for NumberTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
) -> <Self as TypeOption>::CellProtobufType {
ProtobufStr::from(cell_data.0)
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(NumberCellData::from(cell))
}
}
#[async_trait]
@ -112,7 +66,7 @@ impl TypeOptionTransform for NumberTypeOption {
);
for (row_id, cell_data) in rows {
if let Ok(num_cell) = self
.parse_cell(&cell_data)
.decode_cell(&cell_data)
.and_then(|num_cell_data| self.format_cell_data(num_cell_data).map_err(Into::into))
{
database
@ -134,7 +88,7 @@ impl TypeOptionTransform for NumberTypeOption {
impl CellDataDecoder for NumberTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
let num_cell_data = self.parse_cell(cell)?;
let num_cell_data = Self::CellData::from(cell);
Ok(NumberCellData::from(
self.format_cell_data(num_cell_data)?.to_string(),
))
@ -158,11 +112,6 @@ impl CellDataDecoder for NumberTypeOption {
self.format_cell_data(num_cell).ok()?.to_string(),
))
}
fn numeric_cell(&self, cell: &Cell) -> Option<f64> {
let num_cell_data = self.parse_cell(cell).ok()?;
num_cell_data.0.parse::<f64>().ok()
}
}
pub type NumberCellChangeset = String;

View file

@ -3,17 +3,18 @@ use std::cmp::Ordering;
use collab_database::fields::relation_type_option::RelationTypeOption;
use collab_database::rows::Cell;
use collab_database::template::relation_parse::RelationCellData;
use flowy_error::FlowyResult;
use crate::entities::{RelationCellDataPB, RelationFilterPB};
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
use crate::services::field::{
default_order, TypeOption, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionCellDataSerde, TypeOptionTransform,
default_order, CellDataProtobufEncoder, TypeOption, TypeOptionCellDataCompare,
TypeOptionCellDataFilter, TypeOptionTransform,
};
use crate::services::sort::SortCondition;
use super::{RelationCellChangeset, RelationCellData};
use super::RelationCellChangeset;
impl TypeOption for RelationTypeOption {
type CellData = RelationCellData;
@ -32,8 +33,7 @@ impl CellDataChangeset for RelationTypeOption {
let cell_data = RelationCellData {
row_ids: changeset.inserted_row_ids,
};
return Ok(((&cell_data).into(), cell_data));
return Ok(((cell_data.clone()).into(), cell_data));
}
let cell_data: RelationCellData = cell.as_ref().unwrap().into();
@ -51,22 +51,14 @@ impl CellDataChangeset for RelationTypeOption {
let cell_data = RelationCellData { row_ids };
Ok(((&cell_data).into(), cell_data))
Ok(((cell_data.clone()).into(), cell_data))
}
}
impl CellDataDecoder for RelationTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<RelationCellData> {
Ok(cell.into())
}
fn stringify_cell_data(&self, cell_data: RelationCellData) -> String {
cell_data.to_string()
}
fn numeric_cell(&self, _cell: &Cell) -> Option<f64> {
None
}
}
impl TypeOptionCellDataCompare for RelationTypeOption {
@ -88,12 +80,8 @@ impl TypeOptionCellDataFilter for RelationTypeOption {
impl TypeOptionTransform for RelationTypeOption {}
impl TypeOptionCellDataSerde for RelationTypeOption {
impl CellDataProtobufEncoder for RelationTypeOption {
fn protobuf_encode(&self, cell_data: RelationCellData) -> RelationCellDataPB {
cell_data.into()
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<RelationCellData> {
Ok(cell.into())
}
}

View file

@ -1,82 +1,4 @@
use std::sync::Arc;
use collab::preclude::Any;
use collab_database::rows::{new_cell_builder, Cell, RowId};
use crate::entities::FieldType;
use crate::services::field::{TypeOptionCellData, CELL_DATA};
#[derive(Debug, Clone, Default)]
pub struct RelationCellData {
pub row_ids: Vec<RowId>,
}
impl From<&Cell> for RelationCellData {
fn from(value: &Cell) -> Self {
let row_ids = match value.get(CELL_DATA) {
Some(Any::Array(array)) => array
.iter()
.flat_map(|item| {
if let Any::String(string) = item {
Some(RowId::from(string.clone().to_string()))
} else {
None
}
})
.collect(),
_ => vec![],
};
Self { row_ids }
}
}
impl From<&RelationCellData> for Cell {
fn from(value: &RelationCellData) -> Self {
let data = Any::Array(Arc::from(
value
.row_ids
.clone()
.into_iter()
.map(|id| Any::String(Arc::from(id.to_string())))
.collect::<Vec<_>>(),
));
let mut cell = new_cell_builder(FieldType::Relation);
cell.insert(CELL_DATA.into(), data);
cell
}
}
impl From<String> for RelationCellData {
fn from(s: String) -> Self {
if s.is_empty() {
return RelationCellData { row_ids: vec![] };
}
let ids = s
.split(", ")
.map(|id| id.to_string().into())
.collect::<Vec<_>>();
RelationCellData { row_ids: ids }
}
}
impl TypeOptionCellData for RelationCellData {
fn is_cell_empty(&self) -> bool {
self.row_ids.is_empty()
}
}
impl ToString for RelationCellData {
fn to_string(&self) -> String {
self
.row_ids
.iter()
.map(|id| id.to_string())
.collect::<Vec<_>>()
.join(", ")
}
}
use collab_database::rows::RowId;
#[derive(Debug, Clone, Default)]
pub struct RelationCellChangeset {

View file

@ -1,8 +1,8 @@
use crate::entities::{FieldType, SelectOptionCellDataPB, SelectOptionFilterPB};
use crate::services::cell::CellDataChangeset;
use crate::services::field::{
default_order, SelectOptionCellChangeset, SelectTypeOptionSharedAction, TypeOption,
TypeOptionCellDataCompare, TypeOptionCellDataFilter, TypeOptionCellDataSerde,
default_order, CellDataProtobufEncoder, SelectOptionCellChangeset, SelectTypeOptionSharedAction,
TypeOption, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
};
use crate::services::sort::SortCondition;
@ -22,17 +22,13 @@ impl TypeOption for MultiSelectTypeOption {
type CellFilter = SelectOptionFilterPB;
}
impl TypeOptionCellDataSerde for MultiSelectTypeOption {
impl CellDataProtobufEncoder for MultiSelectTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
) -> <Self as TypeOption>::CellProtobufType {
self.get_selected_options(cell_data).into()
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(SelectOptionIds::from(cell))
}
}
impl SelectTypeOptionSharedAction for MultiSelectTypeOption {
@ -89,7 +85,7 @@ impl CellDataChangeset for MultiSelectTypeOption {
},
};
Ok((
select_option_ids.to_cell_data(FieldType::MultiSelect),
select_option_ids.to_cell(FieldType::MultiSelect),
select_option_ids,
))
}

View file

@ -2,7 +2,7 @@ use crate::entities::{CheckboxCellDataPB, FieldType, SelectOptionCellDataPB};
use crate::services::cell::{CellDataDecoder, CellProtobufBlobParser};
use crate::services::field::selection_type_option::type_option_transform::SelectOptionTypeOptionTransformHelper;
use crate::services::field::{
StringCellData, TypeOption, TypeOptionCellData, TypeOptionCellDataSerde, TypeOptionTransform,
CellDataProtobufEncoder, StringCellData, TypeOption, TypeOptionTransform,
};
use async_trait::async_trait;
use bytes::Bytes;
@ -16,12 +16,6 @@ use collab_database::rows::Cell;
use flowy_error::{internal_error, ErrorCode, FlowyResult};
use std::str::FromStr;
impl TypeOptionCellData for SelectOptionIds {
fn is_cell_empty(&self) -> bool {
self.is_empty()
}
}
/// Defines the shared actions used by SingleSelect or Multi-Select.
pub trait SelectTypeOptionSharedAction: Send + Sync {
/// Returns `None` means there is no limited
@ -105,12 +99,8 @@ where
impl<T> CellDataDecoder for T
where
T:
SelectTypeOptionSharedAction + TypeOption<CellData = SelectOptionIds> + TypeOptionCellDataSerde,
SelectTypeOptionSharedAction + TypeOption<CellData = SelectOptionIds> + CellDataProtobufEncoder,
{
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
self.parse_cell(cell)
}
fn decode_cell_with_transform(
&self,
cell: &Cell,
@ -150,10 +140,6 @@ where
.collect::<Vec<String>>()
.join(SELECTION_IDS_SEPARATOR)
}
fn numeric_cell(&self, _cell: &Cell) -> Option<f64> {
None
}
}
pub fn select_type_option_from_field(

View file

@ -1,8 +1,8 @@
use crate::entities::{FieldType, SelectOptionCellDataPB, SelectOptionFilterPB};
use crate::services::cell::CellDataChangeset;
use crate::services::field::{
default_order, TypeOption, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionCellDataSerde,
default_order, CellDataProtobufEncoder, TypeOption, TypeOptionCellDataCompare,
TypeOptionCellDataFilter,
};
use crate::services::field::{SelectOptionCellChangeset, SelectTypeOptionSharedAction};
use crate::services::sort::SortCondition;
@ -25,17 +25,13 @@ impl TypeOption for SingleSelectTypeOption {
type CellFilter = SelectOptionFilterPB;
}
impl TypeOptionCellDataSerde for SingleSelectTypeOption {
impl CellDataProtobufEncoder for SingleSelectTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
) -> <Self as TypeOption>::CellProtobufType {
self.get_selected_options(cell_data).into()
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(SelectOptionIds::from(cell))
}
}
impl SelectTypeOptionSharedAction for SingleSelectTypeOption {
@ -84,7 +80,7 @@ impl CellDataChangeset for SingleSelectTypeOption {
SelectOptionIds::from(insert_option_ids)
};
Ok((
select_option_ids.to_cell_data(FieldType::SingleSelect),
select_option_ids.to_cell(FieldType::SingleSelect),
select_option_ids,
))
}
@ -168,6 +164,6 @@ mod tests {
// delete
let changeset = SelectOptionCellChangeset::from_delete_options(option_ids);
let select_option_ids = single_select.apply_changeset(changeset, None).unwrap().1;
assert!(select_option_ids.is_cell_empty());
assert!(select_option_ids.is_empty());
}
}

View file

@ -74,7 +74,7 @@ impl SelectOptionTypeOptionTransformHelper {
row.update_cells(|cell| {
cell.insert(
field_id,
SelectOptionIds::from(transformed_ids).to_cell_data(new_field_type),
SelectOptionIds::from(transformed_ids).to_cell(new_field_type),
);
});
})

View file

@ -1,2 +1 @@
pub mod summary;
pub mod summary_entities;

View file

@ -1,14 +1,14 @@
use crate::entities::TextFilterPB;
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
use crate::services::field::summary_type_option::summary_entities::SummaryCellData;
use crate::services::field::type_options::util::ProtobufStr;
use crate::services::field::{
TypeOption, TypeOptionCellData, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionCellDataSerde, TypeOptionTransform,
CellDataProtobufEncoder, TypeOption, TypeOptionCellData, TypeOptionCellDataCompare,
TypeOptionCellDataFilter, TypeOptionTransform,
};
use crate::services::sort::SortCondition;
use collab_database::fields::summary_type_option::SummarizationTypeOption;
use collab_database::rows::Cell;
use collab_database::template::summary_parse::SummaryCellData;
use flowy_error::FlowyResult;
use std::cmp::Ordering;
@ -60,29 +60,17 @@ impl TypeOptionCellDataCompare for SummarizationTypeOption {
}
impl CellDataDecoder for SummarizationTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<SummaryCellData> {
Ok(SummaryCellData::from(cell))
}
fn stringify_cell_data(&self, cell_data: SummaryCellData) -> String {
cell_data.to_string()
}
fn numeric_cell(&self, _cell: &Cell) -> Option<f64> {
None
}
}
impl TypeOptionTransform for SummarizationTypeOption {}
impl TypeOptionCellDataSerde for SummarizationTypeOption {
impl CellDataProtobufEncoder for SummarizationTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
) -> <Self as TypeOption>::CellProtobufType {
ProtobufStr::from(cell_data.0)
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(SummaryCellData::from(cell))
}
}

View file

@ -1,46 +0,0 @@
use crate::entities::FieldType;
use crate::services::field::{TypeOptionCellData, CELL_DATA};
use collab::util::AnyMapExt;
use collab_database::rows::{new_cell_builder, Cell};
#[derive(Default, Debug, Clone)]
pub struct SummaryCellData(pub String);
impl std::ops::Deref for SummaryCellData {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl TypeOptionCellData for SummaryCellData {
fn is_cell_empty(&self) -> bool {
self.0.is_empty()
}
}
impl From<&Cell> for SummaryCellData {
fn from(cell: &Cell) -> Self {
Self(cell.get_as::<String>(CELL_DATA).unwrap_or_default())
}
}
impl From<SummaryCellData> for Cell {
fn from(data: SummaryCellData) -> Self {
let mut cell = new_cell_builder(FieldType::Summary);
cell.insert(CELL_DATA.into(), data.0.into());
cell
}
}
impl ToString for SummaryCellData {
fn to_string(&self) -> String {
self.0.clone()
}
}
impl AsRef<str> for SummaryCellData {
fn as_ref(&self) -> &str {
&self.0
}
}

View file

@ -11,8 +11,8 @@ use crate::entities::{FieldType, TextFilterPB};
use crate::services::cell::{stringify_cell, CellDataChangeset, CellDataDecoder};
use crate::services::field::type_options::util::ProtobufStr;
use crate::services::field::{
TypeOption, TypeOptionCellData, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionCellDataSerde, TypeOptionTransform, CELL_DATA,
CellDataProtobufEncoder, TypeOption, TypeOptionCellData, TypeOptionCellDataCompare,
TypeOptionCellDataFilter, TypeOptionTransform, CELL_DATA,
};
use crate::services::sort::SortCondition;
@ -25,24 +25,16 @@ impl TypeOption for RichTextTypeOption {
impl TypeOptionTransform for RichTextTypeOption {}
impl TypeOptionCellDataSerde for RichTextTypeOption {
impl CellDataProtobufEncoder for RichTextTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
) -> <Self as TypeOption>::CellProtobufType {
ProtobufStr::from(cell_data.0)
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(StringCellData::from(cell))
}
}
impl CellDataDecoder for RichTextTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(StringCellData::from(cell))
}
fn decode_cell_with_transform(
&self,
cell: &Cell,
@ -71,10 +63,6 @@ impl CellDataDecoder for RichTextTypeOption {
fn stringify_cell_data(&self, cell_data: <Self as TypeOption>::CellData) -> String {
cell_data.to_string()
}
fn numeric_cell(&self, cell: &Cell) -> Option<f64> {
StringCellData::from(cell).0.parse::<f64>().ok()
}
}
impl CellDataChangeset for RichTextTypeOption {

View file

@ -1,6 +1,4 @@
mod time;
mod time_entities;
mod time_filter;
pub use time::*;
pub use time_entities::*;

View file

@ -1,8 +1,8 @@
use crate::entities::{TimeCellDataPB, TimeFilterPB};
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
use crate::services::field::{
TimeCellData, TypeOption, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionCellDataSerde, TypeOptionTransform,
CellDataProtobufEncoder, TypeOption, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionTransform,
};
use crate::services::sort::SortCondition;
use collab_database::fields::date_type_option::TimeTypeOption;
@ -10,6 +10,7 @@ use collab_database::fields::date_type_option::TimeTypeOption;
use collab_database::rows::Cell;
use flowy_error::FlowyResult;
use collab_database::template::time_parse::TimeCellData;
use std::cmp::Ordering;
impl TypeOption for TimeTypeOption {
@ -19,7 +20,7 @@ impl TypeOption for TimeTypeOption {
type CellFilter = TimeFilterPB;
}
impl TypeOptionCellDataSerde for TimeTypeOption {
impl CellDataProtobufEncoder for TimeTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
@ -31,30 +32,17 @@ impl TypeOptionCellDataSerde for TimeTypeOption {
time: i64::default(),
}
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(TimeCellData::from(cell))
}
}
impl TypeOptionTransform for TimeTypeOption {}
impl CellDataDecoder for TimeTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
self.parse_cell(cell)
}
fn stringify_cell_data(&self, cell_data: <Self as TypeOption>::CellData) -> String {
if let Some(time) = cell_data.0 {
return time.to_string();
}
"".to_string()
}
fn numeric_cell(&self, cell: &Cell) -> Option<f64> {
let time_cell_data = self.parse_cell(cell).ok()?;
Some(time_cell_data.0.unwrap() as f64)
}
}
pub type TimeCellChangeset = String;

View file

@ -1,47 +0,0 @@
use crate::entities::FieldType;
use crate::services::field::{TypeOptionCellData, CELL_DATA};
use collab::util::AnyMapExt;
use collab_database::rows::{new_cell_builder, Cell};
#[derive(Clone, Debug, Default)]
pub struct TimeCellData(pub Option<i64>);
impl TypeOptionCellData for TimeCellData {
fn is_cell_empty(&self) -> bool {
self.0.is_none()
}
}
impl From<&Cell> for TimeCellData {
fn from(cell: &Cell) -> Self {
Self(
cell
.get_as::<String>(CELL_DATA)
.and_then(|data| data.parse::<i64>().ok()),
)
}
}
impl std::convert::From<String> for TimeCellData {
fn from(s: String) -> Self {
Self(s.trim().to_string().parse::<i64>().ok())
}
}
impl ToString for TimeCellData {
fn to_string(&self) -> String {
if let Some(time) = self.0 {
time.to_string()
} else {
"".to_string()
}
}
}
impl From<&TimeCellData> for Cell {
fn from(data: &TimeCellData) -> Self {
let mut cell = new_cell_builder(FieldType::Time);
cell.insert(CELL_DATA.into(), data.to_string().into());
cell
}
}

View file

@ -1,5 +1,2 @@
#![allow(clippy::module_inception)]
mod timestamp_type_option;
mod timestamp_type_option_entities;
pub use timestamp_type_option_entities::*;

View file

@ -1,12 +1,13 @@
use crate::entities::{DateFilterPB, TimestampCellDataPB};
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
use crate::services::field::{
default_order, TimestampCellData, TypeOption, TypeOptionCellDataCompare,
TypeOptionCellDataFilter, TypeOptionCellDataSerde, TypeOptionTransform,
default_order, CellDataProtobufEncoder, TypeOption, TypeOptionCellDataCompare,
TypeOptionCellDataFilter, TypeOptionTransform,
};
use crate::services::sort::SortCondition;
use collab_database::fields::timestamp_type_option::TimestampTypeOption;
use collab_database::rows::Cell;
use collab_database::template::timestamp_parse::TimestampCellData;
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use std::cmp::Ordering;
@ -17,7 +18,7 @@ impl TypeOption for TimestampTypeOption {
type CellFilter = DateFilterPB;
}
impl TypeOptionCellDataSerde for TimestampTypeOption {
impl CellDataProtobufEncoder for TimestampTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
@ -30,19 +31,11 @@ impl TypeOptionCellDataSerde for TimestampTypeOption {
timestamp,
}
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(TimestampCellData::from(cell))
}
}
impl TypeOptionTransform for TimestampTypeOption {}
impl CellDataDecoder for TimestampTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
self.parse_cell(cell)
}
fn stringify_cell_data(&self, cell_data: <Self as TypeOption>::CellData) -> String {
let timestamp = cell_data.timestamp;
let (date_string, time_string) = self.formatted_date_time_from_timestamp(&timestamp);
@ -52,10 +45,6 @@ impl CellDataDecoder for TimestampTypeOption {
date_string
}
}
fn numeric_cell(&self, _cell: &Cell) -> Option<f64> {
None
}
}
impl CellDataChangeset for TimestampTypeOption {

View file

@ -1,69 +0,0 @@
use collab::util::AnyMapExt;
use collab_database::rows::{new_cell_builder, Cell};
use serde::Serialize;
use crate::{
entities::FieldType,
services::field::{TypeOptionCellData, CELL_DATA},
};
#[derive(Clone, Debug, Default, Serialize)]
pub struct TimestampCellData {
pub timestamp: Option<i64>,
}
impl TimestampCellData {
pub fn new(timestamp: i64) -> Self {
Self {
timestamp: Some(timestamp),
}
}
}
impl From<&Cell> for TimestampCellData {
fn from(cell: &Cell) -> Self {
let timestamp = cell
.get_as::<String>(CELL_DATA)
.and_then(|data| data.parse::<i64>().ok());
Self { timestamp }
}
}
/// Wrapper for DateCellData that also contains the field type.
/// Handy struct to use when you need to convert a DateCellData to a Cell.
pub struct TimestampCellDataWrapper {
data: TimestampCellData,
field_type: FieldType,
}
impl From<(FieldType, TimestampCellData)> for TimestampCellDataWrapper {
fn from((field_type, data): (FieldType, TimestampCellData)) -> Self {
Self { data, field_type }
}
}
impl From<TimestampCellDataWrapper> for Cell {
fn from(wrapper: TimestampCellDataWrapper) -> Self {
let (field_type, data) = (wrapper.field_type, wrapper.data);
let timestamp_string = data.timestamp.unwrap_or_default().to_string();
let mut cell = new_cell_builder(field_type);
cell.insert(CELL_DATA.into(), timestamp_string.into());
cell
}
}
impl From<TimestampCellData> for Cell {
fn from(data: TimestampCellData) -> Self {
let data: TimestampCellDataWrapper = (FieldType::LastEditedTime, data).into();
Cell::from(data)
}
}
impl TypeOptionCellData for TimestampCellData {}
impl ToString for TimestampCellData {
fn to_string(&self) -> String {
serde_json::to_string(self).unwrap()
}
}

View file

@ -1,2 +1 @@
pub mod translate;
pub mod translate_entities;

View file

@ -1,14 +1,14 @@
use crate::entities::TextFilterPB;
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
use crate::services::field::type_options::translate_type_option::translate_entities::TranslateCellData;
use crate::services::field::type_options::util::ProtobufStr;
use crate::services::field::{
TypeOption, TypeOptionCellData, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionCellDataSerde, TypeOptionTransform,
CellDataProtobufEncoder, TypeOption, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionTransform,
};
use crate::services::sort::SortCondition;
use collab_database::fields::translate_type_option::TranslateTypeOption;
use collab_database::rows::Cell;
use collab_database::template::translate_parse::TranslateCellData;
use flowy_error::FlowyResult;
use std::cmp::Ordering;
@ -47,7 +47,7 @@ impl TypeOptionCellDataCompare for TranslateTypeOption {
other_cell_data: &<Self as TypeOption>::CellData,
sort_condition: SortCondition,
) -> Ordering {
match (cell_data.is_cell_empty(), other_cell_data.is_cell_empty()) {
match (cell_data.is_empty(), other_cell_data.is_empty()) {
(true, true) => Ordering::Equal,
(true, false) => Ordering::Greater,
(false, true) => Ordering::Less,
@ -60,29 +60,17 @@ impl TypeOptionCellDataCompare for TranslateTypeOption {
}
impl CellDataDecoder for TranslateTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<TranslateCellData> {
Ok(TranslateCellData::from(cell))
}
fn stringify_cell_data(&self, cell_data: TranslateCellData) -> String {
cell_data.to_string()
}
fn numeric_cell(&self, _cell: &Cell) -> Option<f64> {
None
}
}
impl TypeOptionTransform for TranslateTypeOption {}
impl TypeOptionCellDataSerde for TranslateTypeOption {
impl CellDataProtobufEncoder for TranslateTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
) -> <Self as TypeOption>::CellProtobufType {
ProtobufStr::from(cell_data.0)
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(TranslateCellData::from(cell))
}
}

View file

@ -1,46 +0,0 @@
use crate::entities::FieldType;
use crate::services::field::{TypeOptionCellData, CELL_DATA};
use collab::util::AnyMapExt;
use collab_database::rows::{new_cell_builder, Cell};
#[derive(Default, Debug, Clone)]
pub struct TranslateCellData(pub String);
impl std::ops::Deref for TranslateCellData {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl TypeOptionCellData for TranslateCellData {
fn is_cell_empty(&self) -> bool {
self.0.is_empty()
}
}
impl From<&Cell> for TranslateCellData {
fn from(cell: &Cell) -> Self {
Self(cell.get_as(CELL_DATA).unwrap_or_default())
}
}
impl From<TranslateCellData> for Cell {
fn from(data: TranslateCellData) -> Self {
let mut cell = new_cell_builder(FieldType::Translate);
cell.insert(CELL_DATA.into(), data.0.into());
cell
}
}
impl ToString for TranslateCellData {
fn to_string(&self) -> String {
self.0.clone()
}
}
impl AsRef<str> for TranslateCellData {
fn as_ref(&self) -> &str {
&self.0
}
}

View file

@ -22,14 +22,14 @@ use collab_database::fields::text_type_option::RichTextTypeOption;
use collab_database::fields::timestamp_type_option::TimestampTypeOption;
use collab_database::fields::translate_type_option::TranslateTypeOption;
use collab_database::fields::url_type_option::URLTypeOption;
use collab_database::fields::TypeOptionData;
use collab_database::fields::{TypeOptionCellReader, TypeOptionData};
use collab_database::rows::Cell;
use flowy_error::FlowyResult;
pub use collab_database::template::util::TypeOptionCellData;
use protobuf::ProtobufError;
use std::cmp::Ordering;
use std::fmt::Debug;
pub trait TypeOption: From<TypeOptionData> + Into<TypeOptionData> {
pub trait TypeOption: From<TypeOptionData> + Into<TypeOptionData> + TypeOptionCellReader {
/// `CellData` represents the decoded model for the current type option. Each of them must
/// implement the From<&Cell> trait. If the `Cell` cannot be decoded into this type, the default
/// value will be returned.
@ -71,7 +71,7 @@ pub trait TypeOption: From<TypeOptionData> + Into<TypeOptionData> {
///
/// This trait ensures that a type which implements both `TypeOption` and `TypeOptionCellDataSerde` can
/// be converted to and from a corresponding `Protobuf struct`, and can be parsed from an opaque [Cell] structure.
pub trait TypeOptionCellDataSerde: TypeOption {
pub trait CellDataProtobufEncoder: TypeOption {
/// Encode the cell data into corresponding `Protobuf struct`.
/// For example:
/// FieldType::URL => URLCellDataPB
@ -80,20 +80,6 @@ pub trait TypeOptionCellDataSerde: TypeOption {
&self,
cell_data: <Self as TypeOption>::CellData,
) -> <Self as TypeOption>::CellProtobufType;
/// Parse the opaque [Cell] to corresponding data struct.
/// The [Cell] is a map that stores list of key/value data. Each [TypeOption::CellData]
/// should implement the From<&Cell> trait to parse the [Cell] to corresponding data struct.
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData>;
}
/// This trait that provides methods to extend the [TypeOption::CellData] functionalities.
pub trait TypeOptionCellData {
/// Checks if the cell content is considered empty based on certain criteria. e.g. empty text,
/// no date selected, no selected options
fn is_cell_empty(&self) -> bool {
false
}
}
#[async_trait]

View file

@ -1,8 +1,8 @@
use crate::entities::FieldType;
use crate::services::cell::{CellCache, CellDataChangeset, CellDataDecoder, CellProtobufBlob};
use crate::services::field::{
TypeOption, TypeOptionCellData, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionCellDataSerde, TypeOptionTransform,
CellDataProtobufEncoder, TypeOption, TypeOptionCellData, TypeOptionCellDataCompare,
TypeOptionCellDataFilter, TypeOptionTransform,
};
use crate::services::sort::SortCondition;
use collab::preclude::Any;
@ -95,7 +95,7 @@ pub trait TypeOptionCellDataHandler: Send + Sync + 'static {
fn handle_numeric_cell(&self, cell: &Cell) -> Option<f64>;
fn handle_is_cell_empty(&self, cell: &Cell, field: &Field) -> bool;
fn handle_is_empty(&self, cell: &Cell, field: &Field) -> bool;
}
#[derive(Debug)]
@ -155,7 +155,7 @@ where
T: TypeOption
+ CellDataDecoder
+ CellDataChangeset
+ TypeOptionCellDataSerde
+ CellDataProtobufEncoder
+ TypeOptionTransform
+ TypeOptionCellDataFilter
+ TypeOptionCellDataCompare
@ -251,7 +251,7 @@ where
T: TypeOption
+ CellDataDecoder
+ CellDataChangeset
+ TypeOptionCellDataSerde
+ CellDataProtobufEncoder
+ TypeOptionTransform
+ TypeOptionCellDataFilter
+ TypeOptionCellDataCompare
@ -270,7 +270,6 @@ where
field_rev: &Field,
) -> FlowyResult<CellProtobufBlob> {
let cell_data = self.get_cell_data(cell, field_rev).unwrap_or_default();
CellProtobufBlob::from(self.protobuf_encode(cell_data))
}
@ -345,7 +344,7 @@ where
self.numeric_cell(cell)
}
fn handle_is_cell_empty(&self, cell: &Cell, field: &Field) -> bool {
fn handle_is_empty(&self, cell: &Cell, field: &Field) -> bool {
let cell_data = self.get_cell_data(cell, field).unwrap_or_default();
cell_data.is_cell_empty()

View file

@ -1,7 +1,7 @@
use crate::entities::{FieldType, TextFilterPB, URLCellDataPB};
use crate::services::cell::{CellDataChangeset, CellDataDecoder};
use crate::services::field::{
TypeOption, TypeOptionCellDataCompare, TypeOptionCellDataFilter, TypeOptionCellDataSerde,
CellDataProtobufEncoder, TypeOption, TypeOptionCellDataCompare, TypeOptionCellDataFilter,
TypeOptionTransform,
};
use crate::services::sort::SortCondition;
@ -63,23 +63,16 @@ impl TypeOptionTransform for URLTypeOption {
}
}
impl TypeOptionCellDataSerde for URLTypeOption {
impl CellDataProtobufEncoder for URLTypeOption {
fn protobuf_encode(
&self,
cell_data: <Self as TypeOption>::CellData,
) -> <Self as TypeOption>::CellProtobufType {
cell_data.into()
}
fn parse_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
Ok(URLCellData::from(cell))
}
}
impl CellDataDecoder for URLTypeOption {
fn decode_cell(&self, cell: &Cell) -> FlowyResult<<Self as TypeOption>::CellData> {
self.parse_cell(cell)
}
fn decode_cell_with_transform(
&self,
cell: &Cell,
@ -95,10 +88,6 @@ impl CellDataDecoder for URLTypeOption {
fn stringify_cell_data(&self, cell_data: <Self as TypeOption>::CellData) -> String {
cell_data.data
}
fn numeric_cell(&self, _cell: &Cell) -> Option<f64> {
None
}
}
pub type URLCellChangeset = String;

View file

@ -6,13 +6,6 @@ use flowy_error::{internal_error, FlowyResult};
use crate::entities::URLCellDataPB;
use crate::services::cell::CellProtobufBlobParser;
use crate::services::field::TypeOptionCellData;
impl TypeOptionCellData for URLCellData {
fn is_cell_empty(&self) -> bool {
self.data.is_empty()
}
}
impl From<URLCellData> for URLCellDataPB {
fn from(data: URLCellData) -> Self {

View file

@ -7,6 +7,7 @@ use collab::lock::RwLock;
use collab_database::database::gen_database_filter_id;
use collab_database::fields::Field;
use collab_database::rows::{Cell, Cells, Row, RowDetail, RowId};
use collab_database::template::timestamp_parse::TimestampCellData;
use dashmap::DashMap;
use flowy_error::FlowyResult;
use lib_infra::priority_task::{QualityOfService, Task, TaskContent, TaskDispatcher};
@ -20,7 +21,7 @@ use crate::entities::filter_entities::*;
use crate::entities::{FieldType, InsertedRowPB, RowMetaPB};
use crate::services::cell::CellCache;
use crate::services::database_view::{DatabaseViewChanged, DatabaseViewChangedNotifier};
use crate::services::field::{TimestampCellData, TimestampCellDataWrapper, TypeOptionCellExt};
use crate::services::field::TypeOptionCellExt;
use crate::services::filter::{Filter, FilterChangeset, FilterInner, FilterResultNotification};
#[async_trait]
@ -523,9 +524,8 @@ fn apply_filter(
} else {
row.modified_at
};
let cell =
TimestampCellDataWrapper::from((*field_type, TimestampCellData::new(timestamp)));
Some(cell.into())
let cell = TimestampCellData::new(Some(timestamp)).to_cell(field.field_type);
Some(cell)
},
_ => None,
};

View file

@ -12,7 +12,8 @@ use crate::entities::{
FieldType, GroupPB, GroupRowsNotificationPB, InsertedGroupPB, InsertedRowPB, RowMetaPB,
};
use crate::services::cell::insert_date_cell;
use crate::services::field::{DateCellDataParser, TypeOption};
use crate::services::field::date_filter::DateCellDataParser;
use crate::services::field::TypeOption;
use crate::services::group::action::GroupCustomize;
use crate::services::group::configuration::GroupControllerContext;
use crate::services::group::controller::BaseGroupController;

View file

@ -1,6 +1,7 @@
use collab_database::database::Database;
use collab_database::fields::Field;
use collab_database::rows::Cell;
use collab_database::template::timestamp_parse::TimestampCellData;
use futures::StreamExt;
use indexmap::IndexMap;
@ -8,7 +9,6 @@ use flowy_error::{FlowyError, FlowyResult};
use crate::entities::FieldType;
use crate::services::cell::stringify_cell;
use crate::services::field::{TimestampCellData, TimestampCellDataWrapper};
#[derive(Debug, Clone, Copy)]
pub enum CSVFormat {
@ -72,7 +72,7 @@ impl CSVExport {
} else {
TimestampCellData::new(row.modified_at)
};
let cell = Cell::from(TimestampCellDataWrapper::from((field_type, cell_data)));
let cell = cell_data.to_cell(field.field_type);
stringify(&cell, field, style)
},
_ => match row.cells.get(field_id) {

View file

@ -6,7 +6,7 @@ use std::sync::Arc;
use collab_database::fields::Field;
use collab_database::rows::{Cell, Row, RowId};
use collab_database::template::timestamp_parse::TimestampCellData;
use rayon::prelude::ParallelSliceMut;
use serde::{Deserialize, Serialize};
use tokio::sync::RwLock as TokioRwLock;
@ -18,9 +18,7 @@ use crate::entities::SortChangesetNotificationPB;
use crate::entities::{FieldType, SortWithIndexPB};
use crate::services::cell::CellCache;
use crate::services::database_view::{DatabaseViewChanged, DatabaseViewChangedNotifier};
use crate::services::field::{
default_order, TimestampCellData, TimestampCellDataWrapper, TypeOptionCellExt,
};
use crate::services::field::{default_order, TypeOptionCellExt};
use crate::services::sort::{
ReorderAllRowsResult, ReorderSingleRowResult, Sort, SortChangeset, SortCondition,
};
@ -308,10 +306,10 @@ fn cmp_row(
(left.modified_at, right.modified_at)
};
let (left_cell, right_cell) = (
TimestampCellDataWrapper::from((field_type, TimestampCellData::new(left_cell))),
TimestampCellDataWrapper::from((field_type, TimestampCellData::new(right_cell))),
TimestampCellData::new(left_cell).to_cell(field_rev.field_type),
TimestampCellData::new(right_cell).to_cell(field_rev.field_type),
);
Some((Some(left_cell.into()), Some(right_cell.into())))
Some((Some(left_cell), Some(right_cell)))
},
_ => None,
};

View file

@ -3,10 +3,14 @@ use collab_database::fields::date_type_option::DateCellData;
use collab_database::fields::media_type_option::{MediaFile, MediaFileType, MediaUploadType};
use collab_database::fields::select_type_option::{MultiSelectTypeOption, SingleSelectTypeOption};
use collab_database::fields::url_type_option::URLCellData;
use collab_database::template::time_parse::TimeCellData;
use flowy_database2::entities::{FieldType, MediaCellChangeset};
use flowy_database2::services::field::checklist_filter::{
ChecklistCellChangeset, ChecklistCellInsertChangeset,
};
use flowy_database2::services::field::date_filter::DateCellChangeset;
use flowy_database2::services::field::{
ChecklistCellChangeset, ChecklistCellInsertChangeset, DateCellChangeset, RelationCellChangeset,
SelectOptionCellChangeset, StringCellData, TimeCellData,
RelationCellChangeset, SelectOptionCellChangeset, StringCellData,
};
use lib_infra::box_any::BoxAny;
use std::time::Duration;

View file

@ -17,7 +17,7 @@ use event_integration_test::EventIntegrationTest;
use flowy_database2::entities::{DatabasePB, FieldType, FilterPB, RowMetaPB};
use flowy_database2::services::database::DatabaseEditor;
use flowy_database2::services::field::checklist_type_option::ChecklistCellChangeset;
use flowy_database2::services::field::checklist_filter::ChecklistCellChangeset;
use flowy_database2::services::field::SelectOptionCellChangeset;
use flowy_database2::services::share::csv::{CSVFormat, ImportResult};
use flowy_error::FlowyResult;

View file

@ -78,6 +78,7 @@ pub fn create_timestamp_field(grid_id: &str, field_type: FieldType) -> (CreateFi
time_format: TimeFormat::TwentyFourHour,
include_time: true,
field_type: field_type.into(),
timezone: None,
};
let field: Field = match field_type {

View file

@ -1,6 +1,6 @@
use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged};
use collab_database::template::check_list_parse::ChecklistCellData;
use flowy_database2::entities::{ChecklistFilterConditionPB, ChecklistFilterPB, FieldType};
use flowy_database2::services::field::checklist_type_option::ChecklistCellData;
use lib_infra::box_any::BoxAny;
#[tokio::test]

View file

@ -60,6 +60,7 @@ pub fn make_test_board() -> DatabaseData {
time_format: TimeFormat::TwentyFourHour,
include_time: true,
field_type: field_type.into(),
timezone: None,
};
let name = match field_type {
FieldType::LastEditedTime => "Last Modified",

View file

@ -19,7 +19,8 @@ use strum::IntoEnumIterator;
use crate::database::mock_data::{COMPLETED, FACEBOOK, GOOGLE, PAUSED, PLANNED, TWITTER};
use event_integration_test::database_event::TestRowBuilder;
use flowy_database2::entities::FieldType;
use flowy_database2::services::field::{ChecklistCellInsertChangeset, FieldBuilder};
use flowy_database2::services::field::checklist_filter::ChecklistCellInsertChangeset;
use flowy_database2::services::field::FieldBuilder;
use flowy_database2::services::field_settings::default_field_settings_for_fields;
pub fn make_test_grid() -> DatabaseData {
@ -67,6 +68,7 @@ pub fn make_test_grid() -> DatabaseData {
time_format: TimeFormat::TwentyFourHour,
include_time: true,
field_type: field_type.into(),
timezone: None,
};
let name = match field_type {
FieldType::LastEditedTime => "Last Modified",