field_entities.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. #![allow(clippy::upper_case_acronyms)]
  2. use std::fmt::{Display, Formatter};
  3. use std::sync::Arc;
  4. use collab_database::fields::Field;
  5. use collab_database::views::FieldOrder;
  6. use serde_repr::*;
  7. use strum_macros::{EnumCount as EnumCountMacro, EnumIter};
  8. use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
  9. use flowy_error::ErrorCode;
  10. use crate::entities::parser::NotEmptyStr;
  11. use crate::impl_into_field_type;
  12. /// [FieldPB] defines a Field's attributes. Such as the name, field_type, and width. etc.
  13. #[derive(Debug, Clone, Default, ProtoBuf)]
  14. pub struct FieldPB {
  15. #[pb(index = 1)]
  16. pub id: String,
  17. #[pb(index = 2)]
  18. pub name: String,
  19. #[pb(index = 3)]
  20. pub field_type: FieldType,
  21. #[pb(index = 4)]
  22. pub visibility: bool,
  23. #[pb(index = 5)]
  24. pub width: i32,
  25. #[pb(index = 6)]
  26. pub is_primary: bool,
  27. }
  28. impl std::convert::From<Field> for FieldPB {
  29. fn from(field: Field) -> Self {
  30. Self {
  31. id: field.id,
  32. name: field.name,
  33. field_type: FieldType::from(field.field_type),
  34. visibility: field.visibility,
  35. width: field.width as i32,
  36. is_primary: field.is_primary,
  37. }
  38. }
  39. }
  40. /// [FieldIdPB] id of the [Field]
  41. #[derive(Debug, Clone, Default, ProtoBuf)]
  42. pub struct FieldIdPB {
  43. #[pb(index = 1)]
  44. pub field_id: String,
  45. }
  46. impl std::convert::From<&str> for FieldIdPB {
  47. fn from(s: &str) -> Self {
  48. FieldIdPB {
  49. field_id: s.to_owned(),
  50. }
  51. }
  52. }
  53. impl std::convert::From<String> for FieldIdPB {
  54. fn from(s: String) -> Self {
  55. FieldIdPB { field_id: s }
  56. }
  57. }
  58. impl From<FieldOrder> for FieldIdPB {
  59. fn from(field_order: FieldOrder) -> Self {
  60. Self {
  61. field_id: field_order.id,
  62. }
  63. }
  64. }
  65. impl std::convert::From<&Arc<Field>> for FieldIdPB {
  66. fn from(field_rev: &Arc<Field>) -> Self {
  67. Self {
  68. field_id: field_rev.id.clone(),
  69. }
  70. }
  71. }
  72. #[derive(Debug, Clone, Default, ProtoBuf)]
  73. pub struct DatabaseFieldChangesetPB {
  74. #[pb(index = 1)]
  75. pub view_id: String,
  76. #[pb(index = 2)]
  77. pub inserted_fields: Vec<IndexFieldPB>,
  78. #[pb(index = 3)]
  79. pub deleted_fields: Vec<FieldIdPB>,
  80. #[pb(index = 4)]
  81. pub updated_fields: Vec<FieldPB>,
  82. }
  83. impl DatabaseFieldChangesetPB {
  84. pub fn insert(database_id: &str, inserted_fields: Vec<IndexFieldPB>) -> Self {
  85. Self {
  86. view_id: database_id.to_owned(),
  87. inserted_fields,
  88. deleted_fields: vec![],
  89. updated_fields: vec![],
  90. }
  91. }
  92. pub fn delete(database_id: &str, deleted_fields: Vec<FieldIdPB>) -> Self {
  93. Self {
  94. view_id: database_id.to_string(),
  95. inserted_fields: vec![],
  96. deleted_fields,
  97. updated_fields: vec![],
  98. }
  99. }
  100. pub fn update(database_id: &str, updated_fields: Vec<FieldPB>) -> Self {
  101. Self {
  102. view_id: database_id.to_string(),
  103. inserted_fields: vec![],
  104. deleted_fields: vec![],
  105. updated_fields,
  106. }
  107. }
  108. }
  109. #[derive(Debug, Clone, Default, ProtoBuf)]
  110. pub struct IndexFieldPB {
  111. #[pb(index = 1)]
  112. pub field: FieldPB,
  113. #[pb(index = 2)]
  114. pub index: i32,
  115. }
  116. impl IndexFieldPB {
  117. pub fn from_field(field: Field, index: usize) -> Self {
  118. Self {
  119. field: FieldPB::from(field),
  120. index: index as i32,
  121. }
  122. }
  123. }
  124. #[derive(Debug, Default, ProtoBuf)]
  125. pub struct CreateFieldPayloadPB {
  126. #[pb(index = 1)]
  127. pub view_id: String,
  128. #[pb(index = 2)]
  129. pub field_type: FieldType,
  130. #[pb(index = 3, one_of)]
  131. pub type_option_data: Option<Vec<u8>>,
  132. }
  133. #[derive(Clone)]
  134. pub struct CreateFieldParams {
  135. pub view_id: String,
  136. pub field_type: FieldType,
  137. pub type_option_data: Option<Vec<u8>>,
  138. }
  139. impl TryInto<CreateFieldParams> for CreateFieldPayloadPB {
  140. type Error = ErrorCode;
  141. fn try_into(self) -> Result<CreateFieldParams, Self::Error> {
  142. let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
  143. Ok(CreateFieldParams {
  144. view_id: view_id.0,
  145. field_type: self.field_type,
  146. type_option_data: self.type_option_data,
  147. })
  148. }
  149. }
  150. #[derive(Debug, Default, ProtoBuf)]
  151. pub struct UpdateFieldTypePayloadPB {
  152. #[pb(index = 1)]
  153. pub view_id: String,
  154. #[pb(index = 2)]
  155. pub field_id: String,
  156. #[pb(index = 3)]
  157. pub field_type: FieldType,
  158. #[pb(index = 4)]
  159. pub create_if_not_exist: bool,
  160. }
  161. pub struct EditFieldParams {
  162. pub view_id: String,
  163. pub field_id: String,
  164. pub field_type: FieldType,
  165. }
  166. impl TryInto<EditFieldParams> for UpdateFieldTypePayloadPB {
  167. type Error = ErrorCode;
  168. fn try_into(self) -> Result<EditFieldParams, Self::Error> {
  169. let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
  170. let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  171. Ok(EditFieldParams {
  172. view_id: view_id.0,
  173. field_id: field_id.0,
  174. field_type: self.field_type,
  175. })
  176. }
  177. }
  178. #[derive(Debug, Default, ProtoBuf)]
  179. pub struct TypeOptionPathPB {
  180. #[pb(index = 1)]
  181. pub view_id: String,
  182. #[pb(index = 2)]
  183. pub field_id: String,
  184. #[pb(index = 3)]
  185. pub field_type: FieldType,
  186. }
  187. pub struct TypeOptionPathParams {
  188. pub view_id: String,
  189. pub field_id: String,
  190. pub field_type: FieldType,
  191. }
  192. impl TryInto<TypeOptionPathParams> for TypeOptionPathPB {
  193. type Error = ErrorCode;
  194. fn try_into(self) -> Result<TypeOptionPathParams, Self::Error> {
  195. let database_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
  196. let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  197. Ok(TypeOptionPathParams {
  198. view_id: database_id.0,
  199. field_id: field_id.0,
  200. field_type: self.field_type,
  201. })
  202. }
  203. }
  204. #[derive(Debug, Default, ProtoBuf)]
  205. pub struct TypeOptionPB {
  206. #[pb(index = 1)]
  207. pub view_id: String,
  208. #[pb(index = 2)]
  209. pub field: FieldPB,
  210. #[pb(index = 3)]
  211. pub type_option_data: Vec<u8>,
  212. }
  213. /// Collection of the [FieldPB]
  214. #[derive(Debug, Default, ProtoBuf)]
  215. pub struct RepeatedFieldPB {
  216. #[pb(index = 1)]
  217. pub items: Vec<FieldPB>,
  218. }
  219. impl std::ops::Deref for RepeatedFieldPB {
  220. type Target = Vec<FieldPB>;
  221. fn deref(&self) -> &Self::Target {
  222. &self.items
  223. }
  224. }
  225. impl std::ops::DerefMut for RepeatedFieldPB {
  226. fn deref_mut(&mut self) -> &mut Self::Target {
  227. &mut self.items
  228. }
  229. }
  230. impl std::convert::From<Vec<FieldPB>> for RepeatedFieldPB {
  231. fn from(items: Vec<FieldPB>) -> Self {
  232. Self { items }
  233. }
  234. }
  235. #[derive(Debug, Clone, Default, ProtoBuf)]
  236. pub struct RepeatedFieldIdPB {
  237. #[pb(index = 1)]
  238. pub items: Vec<FieldIdPB>,
  239. }
  240. impl std::ops::Deref for RepeatedFieldIdPB {
  241. type Target = Vec<FieldIdPB>;
  242. fn deref(&self) -> &Self::Target {
  243. &self.items
  244. }
  245. }
  246. impl std::convert::From<Vec<FieldIdPB>> for RepeatedFieldIdPB {
  247. fn from(items: Vec<FieldIdPB>) -> Self {
  248. RepeatedFieldIdPB { items }
  249. }
  250. }
  251. impl std::convert::From<String> for RepeatedFieldIdPB {
  252. fn from(s: String) -> Self {
  253. RepeatedFieldIdPB {
  254. items: vec![FieldIdPB::from(s)],
  255. }
  256. }
  257. }
  258. /// [TypeOptionChangesetPB] is used to update the type-option data.
  259. #[derive(ProtoBuf, Default)]
  260. pub struct TypeOptionChangesetPB {
  261. #[pb(index = 1)]
  262. pub view_id: String,
  263. #[pb(index = 2)]
  264. pub field_id: String,
  265. /// Check out [TypeOptionPB] for more details.
  266. #[pb(index = 3)]
  267. pub type_option_data: Vec<u8>,
  268. }
  269. #[derive(Clone)]
  270. pub struct TypeOptionChangesetParams {
  271. pub view_id: String,
  272. pub field_id: String,
  273. pub type_option_data: Vec<u8>,
  274. }
  275. impl TryInto<TypeOptionChangesetParams> for TypeOptionChangesetPB {
  276. type Error = ErrorCode;
  277. fn try_into(self) -> Result<TypeOptionChangesetParams, Self::Error> {
  278. let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
  279. let _ = NotEmptyStr::parse(self.field_id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  280. Ok(TypeOptionChangesetParams {
  281. view_id: view_id.0,
  282. field_id: self.field_id,
  283. type_option_data: self.type_option_data,
  284. })
  285. }
  286. }
  287. #[derive(ProtoBuf, Default)]
  288. pub struct GetFieldPayloadPB {
  289. #[pb(index = 1)]
  290. pub view_id: String,
  291. #[pb(index = 2, one_of)]
  292. pub field_ids: Option<RepeatedFieldIdPB>,
  293. }
  294. pub struct GetFieldParams {
  295. pub view_id: String,
  296. pub field_ids: Option<Vec<String>>,
  297. }
  298. impl TryInto<GetFieldParams> for GetFieldPayloadPB {
  299. type Error = ErrorCode;
  300. fn try_into(self) -> Result<GetFieldParams, Self::Error> {
  301. let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
  302. let field_ids = self.field_ids.map(|repeated| {
  303. repeated
  304. .items
  305. .into_iter()
  306. .map(|item| item.field_id)
  307. .collect::<Vec<String>>()
  308. });
  309. Ok(GetFieldParams {
  310. view_id: view_id.0,
  311. field_ids,
  312. })
  313. }
  314. }
  315. /// [FieldChangesetPB] is used to modify the corresponding field. It defines which properties of
  316. /// the field can be modified.
  317. ///
  318. /// Pass in None if you don't want to modify a property
  319. /// Pass in Some(Value) if you want to modify a property
  320. ///
  321. #[derive(Debug, Clone, Default, ProtoBuf)]
  322. pub struct FieldChangesetPB {
  323. #[pb(index = 1)]
  324. pub field_id: String,
  325. #[pb(index = 2)]
  326. pub view_id: String,
  327. #[pb(index = 3, one_of)]
  328. pub name: Option<String>,
  329. #[pb(index = 4, one_of)]
  330. pub desc: Option<String>,
  331. #[pb(index = 5, one_of)]
  332. pub field_type: Option<FieldType>,
  333. #[pb(index = 6, one_of)]
  334. pub frozen: Option<bool>,
  335. #[pb(index = 7, one_of)]
  336. pub visibility: Option<bool>,
  337. #[pb(index = 8, one_of)]
  338. pub width: Option<i32>,
  339. // #[pb(index = 9, one_of)]
  340. // pub type_option_data: Option<Vec<u8>>,
  341. }
  342. impl TryInto<FieldChangesetParams> for FieldChangesetPB {
  343. type Error = ErrorCode;
  344. fn try_into(self) -> Result<FieldChangesetParams, Self::Error> {
  345. let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
  346. let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  347. let field_type = self.field_type.map(FieldType::from);
  348. // if let Some(type_option_data) = self.type_option_data.as_ref() {
  349. // if type_option_data.is_empty() {
  350. // return Err(ErrorCode::TypeOptionDataIsEmpty);
  351. // }
  352. // }
  353. Ok(FieldChangesetParams {
  354. field_id: field_id.0,
  355. view_id: view_id.0,
  356. name: self.name,
  357. desc: self.desc,
  358. field_type,
  359. frozen: self.frozen,
  360. visibility: self.visibility,
  361. width: self.width,
  362. // type_option_data: self.type_option_data,
  363. })
  364. }
  365. }
  366. #[derive(Debug, Clone, Default)]
  367. pub struct FieldChangesetParams {
  368. pub field_id: String,
  369. pub view_id: String,
  370. pub name: Option<String>,
  371. pub desc: Option<String>,
  372. pub field_type: Option<FieldType>,
  373. pub frozen: Option<bool>,
  374. pub visibility: Option<bool>,
  375. pub width: Option<i32>,
  376. // pub type_option_data: Option<Vec<u8>>,
  377. }
  378. /// Certain field types have user-defined options such as color, date format, number format,
  379. /// or a list of values for a multi-select list. These options are defined within a specialization
  380. /// of the FieldTypeOption class.
  381. ///
  382. /// You could check [this](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/frontend/grid#fieldtype)
  383. /// for more information.
  384. ///
  385. /// The order of the enum can't be changed. If you want to add a new type,
  386. /// it would be better to append it to the end of the list.
  387. #[derive(
  388. Debug,
  389. Clone,
  390. PartialEq,
  391. Hash,
  392. Eq,
  393. ProtoBuf_Enum,
  394. EnumCountMacro,
  395. EnumIter,
  396. Serialize_repr,
  397. Deserialize_repr,
  398. )]
  399. #[repr(u8)]
  400. pub enum FieldType {
  401. RichText = 0,
  402. Number = 1,
  403. DateTime = 2,
  404. SingleSelect = 3,
  405. MultiSelect = 4,
  406. Checkbox = 5,
  407. URL = 6,
  408. Checklist = 7,
  409. LastEditedTime = 8,
  410. CreatedTime = 9,
  411. }
  412. impl std::default::Default for FieldType {
  413. fn default() -> Self {
  414. FieldType::RichText
  415. }
  416. }
  417. impl Display for FieldType {
  418. fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
  419. let value: i64 = self.clone().into();
  420. f.write_fmt(format_args!("{}", value))
  421. }
  422. }
  423. impl AsRef<FieldType> for FieldType {
  424. fn as_ref(&self) -> &FieldType {
  425. self
  426. }
  427. }
  428. impl From<&FieldType> for FieldType {
  429. fn from(field_type: &FieldType) -> Self {
  430. field_type.clone()
  431. }
  432. }
  433. impl FieldType {
  434. pub fn value(&self) -> i64 {
  435. self.clone().into()
  436. }
  437. pub fn default_cell_width(&self) -> i32 {
  438. match self {
  439. FieldType::DateTime | FieldType::LastEditedTime | FieldType::CreatedTime => 180,
  440. _ => 150,
  441. }
  442. }
  443. pub fn default_name(&self) -> String {
  444. let s = match self {
  445. FieldType::RichText => "Text",
  446. FieldType::Number => "Number",
  447. FieldType::DateTime => "Date",
  448. FieldType::SingleSelect => "Single Select",
  449. FieldType::MultiSelect => "Multi Select",
  450. FieldType::Checkbox => "Checkbox",
  451. FieldType::URL => "URL",
  452. FieldType::Checklist => "Checklist",
  453. FieldType::LastEditedTime => "Last edited time",
  454. FieldType::CreatedTime => "Created time",
  455. };
  456. s.to_string()
  457. }
  458. pub fn is_number(&self) -> bool {
  459. matches!(self, FieldType::Number)
  460. }
  461. pub fn is_text(&self) -> bool {
  462. matches!(self, FieldType::RichText)
  463. }
  464. pub fn is_checkbox(&self) -> bool {
  465. matches!(self, FieldType::Checkbox)
  466. }
  467. pub fn is_date(&self) -> bool {
  468. matches!(self, FieldType::DateTime)
  469. || matches!(self, FieldType::LastEditedTime)
  470. || matches!(self, FieldType::CreatedTime)
  471. }
  472. pub fn is_single_select(&self) -> bool {
  473. matches!(self, FieldType::SingleSelect)
  474. }
  475. pub fn is_multi_select(&self) -> bool {
  476. matches!(self, FieldType::MultiSelect)
  477. }
  478. pub fn is_last_edited_time(&self) -> bool {
  479. matches!(self, FieldType::LastEditedTime)
  480. }
  481. pub fn is_created_time(&self) -> bool {
  482. matches!(self, FieldType::CreatedTime)
  483. }
  484. pub fn is_url(&self) -> bool {
  485. matches!(self, FieldType::URL)
  486. }
  487. pub fn is_select_option(&self) -> bool {
  488. self.is_single_select() || self.is_multi_select()
  489. }
  490. pub fn is_checklist(&self) -> bool {
  491. matches!(self, FieldType::Checklist)
  492. }
  493. pub fn can_be_group(&self) -> bool {
  494. self.is_select_option() || self.is_checkbox() || self.is_url()
  495. }
  496. pub fn is_auto_update(&self) -> bool {
  497. self.is_last_edited_time()
  498. }
  499. }
  500. impl_into_field_type!(i64);
  501. impl_into_field_type!(u8);
  502. impl From<FieldType> for i64 {
  503. fn from(ty: FieldType) -> Self {
  504. (ty as u8) as i64
  505. }
  506. }
  507. impl From<&FieldType> for i64 {
  508. fn from(ty: &FieldType) -> Self {
  509. i64::from(ty.clone())
  510. }
  511. }
  512. #[derive(Debug, Clone, Default, ProtoBuf)]
  513. pub struct DuplicateFieldPayloadPB {
  514. #[pb(index = 1)]
  515. pub field_id: String,
  516. #[pb(index = 2)]
  517. pub view_id: String,
  518. }
  519. // #[derive(Debug, Clone, Default, ProtoBuf)]
  520. // pub struct GridFieldIdentifierPayloadPB {
  521. // #[pb(index = 1)]
  522. // pub field_id: String,
  523. //
  524. // #[pb(index = 2)]
  525. // pub view_id: String,
  526. // }
  527. impl TryInto<FieldIdParams> for DuplicateFieldPayloadPB {
  528. type Error = ErrorCode;
  529. fn try_into(self) -> Result<FieldIdParams, Self::Error> {
  530. let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
  531. let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  532. Ok(FieldIdParams {
  533. view_id: view_id.0,
  534. field_id: field_id.0,
  535. })
  536. }
  537. }
  538. #[derive(Debug, Clone, Default, ProtoBuf)]
  539. pub struct DeleteFieldPayloadPB {
  540. #[pb(index = 1)]
  541. pub field_id: String,
  542. #[pb(index = 2)]
  543. pub view_id: String,
  544. }
  545. impl TryInto<FieldIdParams> for DeleteFieldPayloadPB {
  546. type Error = ErrorCode;
  547. fn try_into(self) -> Result<FieldIdParams, Self::Error> {
  548. let view_id = NotEmptyStr::parse(self.view_id).map_err(|_| ErrorCode::DatabaseIdIsEmpty)?;
  549. let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  550. Ok(FieldIdParams {
  551. view_id: view_id.0,
  552. field_id: field_id.0,
  553. })
  554. }
  555. }
  556. pub struct FieldIdParams {
  557. pub field_id: String,
  558. pub view_id: String,
  559. }