field_entities.rs 15 KB

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