field_entities.rs 17 KB

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