Skip to content

Commit 65db13c

Browse files
committed
feat: add default type option data from type
1 parent 699d6e3 commit 65db13c

File tree

7 files changed

+285
-2
lines changed

7 files changed

+285
-2
lines changed

collab-database/src/entity.rs

Lines changed: 152 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
#![allow(clippy::upper_case_acronyms)]
22
use crate::database::{gen_database_id, gen_database_view_id, gen_row_id, timestamp, DatabaseData};
33
use crate::error::DatabaseError;
4-
use crate::fields::Field;
4+
use crate::fields::checkbox_type_option::CheckboxTypeOption;
5+
use crate::fields::checklist_type_option::ChecklistTypeOption;
6+
use crate::fields::date_type_option::{DateTypeOption, TimeTypeOption};
7+
use crate::fields::media_type_option::MediaTypeOption;
8+
use crate::fields::number_type_option::NumberTypeOption;
9+
use crate::fields::relation_type_option::RelationTypeOption;
10+
use crate::fields::select_type_option::{MultiSelectTypeOption, SingleSelectTypeOption};
11+
use crate::fields::summary_type_option::SummarizationTypeOption;
12+
use crate::fields::text_type_option::RichTextTypeOption;
13+
use crate::fields::timestamp_type_option::TimestampTypeOption;
14+
use crate::fields::translate_type_option::TranslateTypeOption;
15+
use crate::fields::url_type_option::URLTypeOption;
16+
use crate::fields::{Field, TypeOptionData};
517
use crate::rows::CreateRowParams;
618
use crate::views::{
719
DatabaseLayout, FieldOrder, FieldSettingsByFieldIdMap, FieldSettingsMap, FilterMap,
@@ -13,6 +25,7 @@ use collab_entity::CollabType;
1325
use serde::{Deserialize, Serialize};
1426
use serde_repr::{Deserialize_repr, Serialize_repr};
1527
use std::collections::HashMap;
28+
use std::fmt::{Display, Formatter};
1629
use tracing::error;
1730
use yrs::{Any, Out};
1831

@@ -254,7 +267,7 @@ impl CreateDatabaseParams {
254267
}
255268
}
256269

257-
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize_repr, Deserialize_repr)]
270+
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Serialize_repr, Deserialize_repr)]
258271
#[repr(u8)]
259272
pub enum FieldType {
260273
RichText = 0,
@@ -297,6 +310,120 @@ impl TryFrom<yrs::Out> for FieldType {
297310
}
298311
}
299312

313+
impl Display for FieldType {
314+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
315+
let value: i64 = (*self).into();
316+
f.write_fmt(format_args!("{}", value))
317+
}
318+
}
319+
320+
impl AsRef<FieldType> for FieldType {
321+
fn as_ref(&self) -> &FieldType {
322+
self
323+
}
324+
}
325+
326+
impl From<&FieldType> for FieldType {
327+
fn from(field_type: &FieldType) -> Self {
328+
*field_type
329+
}
330+
}
331+
332+
impl FieldType {
333+
pub fn value(&self) -> i64 {
334+
(*self).into()
335+
}
336+
337+
pub fn default_name(&self) -> String {
338+
let s = match self {
339+
FieldType::RichText => "Text",
340+
FieldType::Number => "Number",
341+
FieldType::DateTime => "Date",
342+
FieldType::SingleSelect => "Single Select",
343+
FieldType::MultiSelect => "Multi Select",
344+
FieldType::Checkbox => "Checkbox",
345+
FieldType::URL => "URL",
346+
FieldType::Checklist => "Checklist",
347+
FieldType::LastEditedTime => "Last modified",
348+
FieldType::CreatedTime => "Created time",
349+
FieldType::Relation => "Relation",
350+
FieldType::Summary => "Summarize",
351+
FieldType::Translate => "Translate",
352+
FieldType::Time => "Time",
353+
FieldType::Media => "Media",
354+
};
355+
s.to_string()
356+
}
357+
358+
pub fn is_ai_field(&self) -> bool {
359+
matches!(self, FieldType::Summary | FieldType::Translate)
360+
}
361+
362+
pub fn is_number(&self) -> bool {
363+
matches!(self, FieldType::Number)
364+
}
365+
366+
pub fn is_text(&self) -> bool {
367+
matches!(self, FieldType::RichText)
368+
}
369+
370+
pub fn is_checkbox(&self) -> bool {
371+
matches!(self, FieldType::Checkbox)
372+
}
373+
374+
pub fn is_date(&self) -> bool {
375+
matches!(self, FieldType::DateTime)
376+
}
377+
378+
pub fn is_single_select(&self) -> bool {
379+
matches!(self, FieldType::SingleSelect)
380+
}
381+
382+
pub fn is_multi_select(&self) -> bool {
383+
matches!(self, FieldType::MultiSelect)
384+
}
385+
386+
pub fn is_last_edited_time(&self) -> bool {
387+
matches!(self, FieldType::LastEditedTime)
388+
}
389+
390+
pub fn is_created_time(&self) -> bool {
391+
matches!(self, FieldType::CreatedTime)
392+
}
393+
394+
pub fn is_url(&self) -> bool {
395+
matches!(self, FieldType::URL)
396+
}
397+
398+
pub fn is_select_option(&self) -> bool {
399+
self.is_single_select() || self.is_multi_select()
400+
}
401+
402+
pub fn is_checklist(&self) -> bool {
403+
matches!(self, FieldType::Checklist)
404+
}
405+
406+
pub fn is_relation(&self) -> bool {
407+
matches!(self, FieldType::Relation)
408+
}
409+
410+
pub fn is_time(&self) -> bool {
411+
matches!(self, FieldType::Time)
412+
}
413+
414+
pub fn is_media(&self) -> bool {
415+
matches!(self, FieldType::Media)
416+
}
417+
418+
pub fn can_be_group(&self) -> bool {
419+
self.is_select_option() || self.is_checkbox() || self.is_url()
420+
}
421+
422+
pub fn is_auto_update(&self) -> bool {
423+
self.is_last_edited_time()
424+
}
425+
}
426+
300427
impl From<i64> for FieldType {
301428
fn from(index: i64) -> Self {
302429
match index {
@@ -323,6 +450,29 @@ impl From<i64> for FieldType {
323450
}
324451
}
325452

453+
pub fn default_type_option_data_from_type(field_type: FieldType) -> TypeOptionData {
454+
match field_type {
455+
FieldType::RichText => RichTextTypeOption.into(),
456+
FieldType::Number => NumberTypeOption::default().into(),
457+
FieldType::DateTime => DateTypeOption::default().into(),
458+
FieldType::LastEditedTime | FieldType::CreatedTime => TimestampTypeOption {
459+
field_type: field_type.into(),
460+
..Default::default()
461+
}
462+
.into(),
463+
FieldType::SingleSelect => SingleSelectTypeOption::default().into(),
464+
FieldType::MultiSelect => MultiSelectTypeOption::default().into(),
465+
FieldType::Checkbox => CheckboxTypeOption.into(),
466+
FieldType::URL => URLTypeOption::default().into(),
467+
FieldType::Time => TimeTypeOption.into(),
468+
FieldType::Media => MediaTypeOption::default().into(),
469+
FieldType::Checklist => ChecklistTypeOption.into(),
470+
FieldType::Relation => RelationTypeOption::default().into(),
471+
FieldType::Summary => SummarizationTypeOption::default().into(),
472+
FieldType::Translate => TranslateTypeOption::default().into(),
473+
}
474+
}
475+
326476
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize_repr, Deserialize_repr)]
327477
#[repr(u8)]
328478
pub enum FileUploadType {

collab-database/src/fields/field.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use serde::{Deserialize, Serialize};
22

33
use collab::preclude::{Any, Map, MapExt, MapRef, ReadTxn, TransactionMut, YrsValue};
44

5+
use crate::database::gen_field_id;
6+
use crate::entity::{default_type_option_data_from_type, FieldType};
57
use crate::fields::{TypeOptionData, TypeOptions, TypeOptionsUpdate};
68
use crate::{impl_bool_update, impl_i64_update, impl_str_update};
79

@@ -37,6 +39,17 @@ impl Field {
3739
self
3840
}
3941

42+
pub fn from_field_type(name: &str, field_type: FieldType, is_primary: bool) -> Self {
43+
let new_field = Self {
44+
id: gen_field_id(),
45+
name: name.to_string(),
46+
field_type: field_type.into(),
47+
is_primary,
48+
..Default::default()
49+
};
50+
new_field.with_type_option_data(field_type, default_type_option_data_from_type(field_type))
51+
}
52+
4053
pub fn get_type_option<T: From<TypeOptionData>>(&self, type_id: impl ToString) -> Option<T> {
4154
let type_option_data = self.type_options.get(&type_id.to_string())?.clone();
4255
Some(T::from(type_option_data))
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
use super::{TypeOptionData, TypeOptionDataBuilder};
4+
5+
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
6+
pub struct ChecklistTypeOption;
7+
8+
impl From<TypeOptionData> for ChecklistTypeOption {
9+
fn from(_data: TypeOptionData) -> Self {
10+
Self
11+
}
12+
}
13+
14+
impl From<ChecklistTypeOption> for TypeOptionData {
15+
fn from(_data: ChecklistTypeOption) -> Self {
16+
TypeOptionDataBuilder::default()
17+
}
18+
}

collab-database/src/fields/type_option/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
pub mod checkbox_type_option;
2+
pub mod checklist_type_option;
23
pub mod date_type_option;
34
pub mod media_type_option;
45
pub mod number_type_option;
6+
pub mod relation_type_option;
57
pub mod select_type_option;
8+
pub mod summary_type_option;
69
pub mod text_type_option;
710
pub mod timestamp_type_option;
11+
pub mod translate_type_option;
812
pub mod url_type_option;
913

1014
use std::collections::HashMap;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use collab::util::AnyMapExt;
2+
use serde::{Deserialize, Serialize};
3+
4+
use super::{TypeOptionData, TypeOptionDataBuilder};
5+
6+
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
7+
pub struct RelationTypeOption {
8+
pub database_id: String,
9+
}
10+
11+
impl From<TypeOptionData> for RelationTypeOption {
12+
fn from(data: TypeOptionData) -> Self {
13+
let database_id: String = data.get_as("database_id").unwrap_or_default();
14+
Self { database_id }
15+
}
16+
}
17+
18+
impl From<RelationTypeOption> for TypeOptionData {
19+
fn from(data: RelationTypeOption) -> Self {
20+
TypeOptionDataBuilder::from([("database_id".into(), data.database_id.into())])
21+
}
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use collab::util::AnyMapExt;
2+
use serde::{Deserialize, Serialize};
3+
4+
use super::{TypeOptionData, TypeOptionDataBuilder};
5+
6+
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
7+
pub struct SummarizationTypeOption {
8+
pub auto_fill: bool,
9+
}
10+
11+
impl From<TypeOptionData> for SummarizationTypeOption {
12+
fn from(data: TypeOptionData) -> Self {
13+
let auto_fill: bool = data.get_as("auto_fill").unwrap_or_default();
14+
Self { auto_fill }
15+
}
16+
}
17+
18+
impl From<SummarizationTypeOption> for TypeOptionData {
19+
fn from(data: SummarizationTypeOption) -> Self {
20+
TypeOptionDataBuilder::from([("auto_fill".into(), data.auto_fill.into())])
21+
}
22+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use serde::{Deserialize, Serialize};
2+
use yrs::{encoding::serde::from_any, Any};
3+
4+
use super::{TypeOptionData, TypeOptionDataBuilder};
5+
6+
#[derive(Debug, Clone, Serialize, Deserialize)]
7+
pub struct TranslateTypeOption {
8+
#[serde(default)]
9+
pub auto_fill: bool,
10+
/// Use [TranslateTypeOption::language_from_type] to get the language name
11+
#[serde(default, rename = "language")]
12+
pub language_type: i64,
13+
}
14+
15+
impl TranslateTypeOption {
16+
pub fn language_from_type(language_type: i64) -> &'static str {
17+
match language_type {
18+
0 => "Traditional Chinese",
19+
1 => "English",
20+
2 => "French",
21+
3 => "German",
22+
4 => "Hindi",
23+
5 => "Spanish",
24+
6 => "Portuguese",
25+
7 => "Standard Arabic",
26+
8 => "Simplified Chinese",
27+
_ => "English",
28+
}
29+
}
30+
}
31+
32+
impl Default for TranslateTypeOption {
33+
fn default() -> Self {
34+
Self {
35+
auto_fill: false,
36+
language_type: 1,
37+
}
38+
}
39+
}
40+
41+
impl From<TypeOptionData> for TranslateTypeOption {
42+
fn from(data: TypeOptionData) -> Self {
43+
from_any(&Any::from(data)).unwrap()
44+
}
45+
}
46+
47+
impl From<TranslateTypeOption> for TypeOptionData {
48+
fn from(value: TranslateTypeOption) -> Self {
49+
TypeOptionDataBuilder::from([
50+
("auto_fill".into(), value.auto_fill.into()),
51+
("language".into(), Any::BigInt(value.language_type)),
52+
])
53+
}
54+
}

0 commit comments

Comments
 (0)