field_entities.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  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 serde_repr::*;
  6. use std::sync::Arc;
  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 { field_id: s.to_owned() }
  57. }
  58. }
  59. impl std::convert::From<String> for FieldIdPB {
  60. fn from(s: String) -> Self {
  61. FieldIdPB { field_id: s }
  62. }
  63. }
  64. impl std::convert::From<&Arc<FieldRevision>> for FieldIdPB {
  65. fn from(field_rev: &Arc<FieldRevision>) -> Self {
  66. Self {
  67. field_id: field_rev.id.clone(),
  68. }
  69. }
  70. }
  71. #[derive(Debug, Clone, Default, ProtoBuf)]
  72. pub struct FieldChangesetPB {
  73. #[pb(index = 1)]
  74. pub grid_id: String,
  75. #[pb(index = 2)]
  76. pub inserted_fields: Vec<IndexFieldPB>,
  77. #[pb(index = 3)]
  78. pub deleted_fields: Vec<FieldIdPB>,
  79. #[pb(index = 4)]
  80. pub updated_fields: Vec<FieldPB>,
  81. }
  82. impl FieldChangesetPB {
  83. pub fn insert(grid_id: &str, inserted_fields: Vec<IndexFieldPB>) -> Self {
  84. Self {
  85. grid_id: grid_id.to_owned(),
  86. inserted_fields,
  87. deleted_fields: vec![],
  88. updated_fields: vec![],
  89. }
  90. }
  91. pub fn delete(grid_id: &str, deleted_fields: Vec<FieldIdPB>) -> Self {
  92. Self {
  93. grid_id: grid_id.to_string(),
  94. inserted_fields: vec![],
  95. deleted_fields,
  96. updated_fields: vec![],
  97. }
  98. }
  99. pub fn update(grid_id: &str, updated_fields: Vec<FieldPB>) -> Self {
  100. Self {
  101. grid_id: grid_id.to_string(),
  102. inserted_fields: vec![],
  103. deleted_fields: vec![],
  104. updated_fields,
  105. }
  106. }
  107. }
  108. #[derive(Debug, Clone, Default, ProtoBuf)]
  109. pub struct IndexFieldPB {
  110. #[pb(index = 1)]
  111. pub field: FieldPB,
  112. #[pb(index = 2)]
  113. pub index: i32,
  114. }
  115. impl IndexFieldPB {
  116. pub fn from_field_rev(field_rev: &Arc<FieldRevision>, index: usize) -> Self {
  117. Self {
  118. field: FieldPB::from(field_rev.as_ref().clone()),
  119. index: index as i32,
  120. }
  121. }
  122. }
  123. #[derive(Debug, Default, ProtoBuf)]
  124. pub struct GetEditFieldContextPayloadPB {
  125. #[pb(index = 1)]
  126. pub grid_id: String,
  127. #[pb(index = 2, one_of)]
  128. pub field_id: Option<String>,
  129. #[pb(index = 3)]
  130. pub field_type: FieldType,
  131. }
  132. #[derive(Debug, Default, ProtoBuf)]
  133. pub struct CreateFieldPayloadPB {
  134. #[pb(index = 1)]
  135. pub grid_id: String,
  136. #[pb(index = 2)]
  137. pub field_type: FieldType,
  138. #[pb(index = 3, one_of)]
  139. pub type_option_data: Option<Vec<u8>>,
  140. }
  141. #[derive(Clone)]
  142. pub struct CreateFieldParams {
  143. pub grid_id: String,
  144. pub field_type: FieldType,
  145. pub type_option_data: Option<Vec<u8>>,
  146. }
  147. impl TryInto<CreateFieldParams> for CreateFieldPayloadPB {
  148. type Error = ErrorCode;
  149. fn try_into(self) -> Result<CreateFieldParams, Self::Error> {
  150. let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
  151. Ok(CreateFieldParams {
  152. grid_id: grid_id.0,
  153. field_type: self.field_type,
  154. type_option_data: self.type_option_data,
  155. })
  156. }
  157. }
  158. #[derive(Debug, Default, ProtoBuf)]
  159. pub struct EditFieldPayloadPB {
  160. #[pb(index = 1)]
  161. pub grid_id: String,
  162. #[pb(index = 2)]
  163. pub field_id: String,
  164. #[pb(index = 3)]
  165. pub field_type: FieldType,
  166. #[pb(index = 4)]
  167. pub create_if_not_exist: bool,
  168. }
  169. pub struct EditFieldParams {
  170. pub grid_id: String,
  171. pub field_id: String,
  172. pub field_type: FieldType,
  173. }
  174. impl TryInto<EditFieldParams> for EditFieldPayloadPB {
  175. type Error = ErrorCode;
  176. fn try_into(self) -> Result<EditFieldParams, Self::Error> {
  177. let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
  178. let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  179. Ok(EditFieldParams {
  180. grid_id: grid_id.0,
  181. field_id: field_id.0,
  182. field_type: self.field_type,
  183. })
  184. }
  185. }
  186. #[derive(Debug, Default, ProtoBuf)]
  187. pub struct FieldTypeOptionIdPB {
  188. #[pb(index = 1)]
  189. pub grid_id: String,
  190. #[pb(index = 2)]
  191. pub field_id: String,
  192. #[pb(index = 3)]
  193. pub field_type: FieldType,
  194. }
  195. pub struct FieldTypeOptionIdParams {
  196. pub grid_id: String,
  197. pub field_id: String,
  198. pub field_type: FieldType,
  199. }
  200. impl TryInto<FieldTypeOptionIdParams> for FieldTypeOptionIdPB {
  201. type Error = ErrorCode;
  202. fn try_into(self) -> Result<FieldTypeOptionIdParams, Self::Error> {
  203. let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
  204. let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  205. Ok(FieldTypeOptionIdParams {
  206. grid_id: grid_id.0,
  207. field_id: field_id.0,
  208. field_type: self.field_type,
  209. })
  210. }
  211. }
  212. #[derive(Debug, Default, ProtoBuf)]
  213. pub struct FieldTypeOptionDataPB {
  214. #[pb(index = 1)]
  215. pub grid_id: String,
  216. #[pb(index = 2)]
  217. pub field: FieldPB,
  218. #[pb(index = 3)]
  219. pub type_option_data: Vec<u8>,
  220. }
  221. /// Collection of the [FieldPB]
  222. #[derive(Debug, Default, ProtoBuf)]
  223. pub struct RepeatedFieldPB {
  224. #[pb(index = 1)]
  225. pub items: Vec<FieldPB>,
  226. }
  227. impl std::ops::Deref for RepeatedFieldPB {
  228. type Target = Vec<FieldPB>;
  229. fn deref(&self) -> &Self::Target {
  230. &self.items
  231. }
  232. }
  233. impl std::ops::DerefMut for RepeatedFieldPB {
  234. fn deref_mut(&mut self) -> &mut Self::Target {
  235. &mut self.items
  236. }
  237. }
  238. impl std::convert::From<Vec<FieldPB>> for RepeatedFieldPB {
  239. fn from(items: Vec<FieldPB>) -> Self {
  240. Self { items }
  241. }
  242. }
  243. #[derive(Debug, Clone, Default, ProtoBuf)]
  244. pub struct RepeatedFieldIdPB {
  245. #[pb(index = 1)]
  246. pub items: Vec<FieldIdPB>,
  247. }
  248. impl std::ops::Deref for RepeatedFieldIdPB {
  249. type Target = Vec<FieldIdPB>;
  250. fn deref(&self) -> &Self::Target {
  251. &self.items
  252. }
  253. }
  254. impl std::convert::From<Vec<FieldIdPB>> for RepeatedFieldIdPB {
  255. fn from(items: Vec<FieldIdPB>) -> Self {
  256. RepeatedFieldIdPB { items }
  257. }
  258. }
  259. impl std::convert::From<String> for RepeatedFieldIdPB {
  260. fn from(s: String) -> Self {
  261. RepeatedFieldIdPB {
  262. items: vec![FieldIdPB::from(s)],
  263. }
  264. }
  265. }
  266. /// [UpdateFieldTypeOptionPayloadPB] is used to update the type-option data.
  267. #[derive(ProtoBuf, Default)]
  268. pub struct UpdateFieldTypeOptionPayloadPB {
  269. #[pb(index = 1)]
  270. pub grid_id: String,
  271. #[pb(index = 2)]
  272. pub field_id: String,
  273. /// Check out [FieldTypeOptionDataPB] for more details.
  274. #[pb(index = 3)]
  275. pub type_option_data: Vec<u8>,
  276. }
  277. #[derive(Clone)]
  278. pub struct UpdateFieldTypeOptionParams {
  279. pub grid_id: String,
  280. pub field_id: String,
  281. pub type_option_data: Vec<u8>,
  282. }
  283. impl TryInto<UpdateFieldTypeOptionParams> for UpdateFieldTypeOptionPayloadPB {
  284. type Error = ErrorCode;
  285. fn try_into(self) -> Result<UpdateFieldTypeOptionParams, Self::Error> {
  286. let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
  287. let _ = NotEmptyStr::parse(self.field_id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  288. Ok(UpdateFieldTypeOptionParams {
  289. grid_id: grid_id.0,
  290. field_id: self.field_id,
  291. type_option_data: self.type_option_data,
  292. })
  293. }
  294. }
  295. #[derive(ProtoBuf, Default)]
  296. pub struct QueryFieldPayloadPB {
  297. #[pb(index = 1)]
  298. pub grid_id: String,
  299. #[pb(index = 2)]
  300. pub field_ids: RepeatedFieldIdPB,
  301. }
  302. pub struct QueryFieldParams {
  303. pub grid_id: String,
  304. pub field_ids: RepeatedFieldIdPB,
  305. }
  306. impl TryInto<QueryFieldParams> for QueryFieldPayloadPB {
  307. type Error = ErrorCode;
  308. fn try_into(self) -> Result<QueryFieldParams, Self::Error> {
  309. let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
  310. Ok(QueryFieldParams {
  311. grid_id: grid_id.0,
  312. field_ids: self.field_ids,
  313. })
  314. }
  315. }
  316. /// [FieldChangesetPayloadPB] 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 FieldChangesetPayloadPB {
  324. #[pb(index = 1)]
  325. pub field_id: String,
  326. #[pb(index = 2)]
  327. pub grid_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 FieldChangesetPayloadPB {
  344. type Error = ErrorCode;
  345. fn try_into(self) -> Result<FieldChangesetParams, Self::Error> {
  346. let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
  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. grid_id: grid_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 grid_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. }
  412. pub const RICH_TEXT_FIELD: FieldType = FieldType::RichText;
  413. pub const NUMBER_FIELD: FieldType = FieldType::Number;
  414. pub const DATE_FIELD: FieldType = FieldType::DateTime;
  415. pub const SINGLE_SELECT_FIELD: FieldType = FieldType::SingleSelect;
  416. pub const MULTI_SELECT_FIELD: FieldType = FieldType::MultiSelect;
  417. pub const CHECKBOX_FIELD: FieldType = FieldType::Checkbox;
  418. pub const URL_FIELD: FieldType = FieldType::URL;
  419. impl std::default::Default for FieldType {
  420. fn default() -> Self {
  421. FieldType::RichText
  422. }
  423. }
  424. impl AsRef<FieldType> for FieldType {
  425. fn as_ref(&self) -> &FieldType {
  426. self
  427. }
  428. }
  429. impl From<&FieldType> for FieldType {
  430. fn from(field_type: &FieldType) -> Self {
  431. field_type.clone()
  432. }
  433. }
  434. impl FieldType {
  435. pub fn type_id(&self) -> String {
  436. (self.clone() as u8).to_string()
  437. }
  438. pub fn default_cell_width(&self) -> i32 {
  439. match self {
  440. FieldType::DateTime => 180,
  441. _ => 150,
  442. }
  443. }
  444. pub fn is_number(&self) -> bool {
  445. self == &NUMBER_FIELD
  446. }
  447. pub fn is_text(&self) -> bool {
  448. self == &RICH_TEXT_FIELD
  449. }
  450. pub fn is_checkbox(&self) -> bool {
  451. self == &CHECKBOX_FIELD
  452. }
  453. pub fn is_date(&self) -> bool {
  454. self == &DATE_FIELD
  455. }
  456. pub fn is_single_select(&self) -> bool {
  457. self == &SINGLE_SELECT_FIELD
  458. }
  459. pub fn is_multi_select(&self) -> bool {
  460. self == &MULTI_SELECT_FIELD
  461. }
  462. pub fn is_url(&self) -> bool {
  463. self == &URL_FIELD
  464. }
  465. pub fn is_select_option(&self) -> bool {
  466. self == &MULTI_SELECT_FIELD || self == &SINGLE_SELECT_FIELD
  467. }
  468. pub fn can_be_group(&self) -> bool {
  469. self.is_select_option()
  470. }
  471. }
  472. impl std::convert::From<&FieldType> for FieldTypeRevision {
  473. fn from(ty: &FieldType) -> Self {
  474. ty.clone() as u8
  475. }
  476. }
  477. impl std::convert::From<FieldType> for FieldTypeRevision {
  478. fn from(ty: FieldType) -> Self {
  479. ty as u8
  480. }
  481. }
  482. impl std::convert::From<&FieldTypeRevision> for FieldType {
  483. fn from(ty: &FieldTypeRevision) -> Self {
  484. FieldType::from(*ty)
  485. }
  486. }
  487. impl std::convert::From<FieldTypeRevision> for FieldType {
  488. fn from(ty: FieldTypeRevision) -> Self {
  489. match ty {
  490. 0 => FieldType::RichText,
  491. 1 => FieldType::Number,
  492. 2 => FieldType::DateTime,
  493. 3 => FieldType::SingleSelect,
  494. 4 => FieldType::MultiSelect,
  495. 5 => FieldType::Checkbox,
  496. 6 => FieldType::URL,
  497. _ => {
  498. tracing::error!("Can't parser FieldTypeRevision: {} to FieldType", ty);
  499. FieldType::RichText
  500. }
  501. }
  502. }
  503. }
  504. #[derive(Debug, Clone, Default, ProtoBuf)]
  505. pub struct DuplicateFieldPayloadPB {
  506. #[pb(index = 1)]
  507. pub field_id: String,
  508. #[pb(index = 2)]
  509. pub grid_id: String,
  510. }
  511. #[derive(Debug, Clone, Default, ProtoBuf)]
  512. pub struct GridFieldIdentifierPayloadPB {
  513. #[pb(index = 1)]
  514. pub field_id: String,
  515. #[pb(index = 2)]
  516. pub grid_id: String,
  517. }
  518. impl TryInto<FieldIdParams> for DuplicateFieldPayloadPB {
  519. type Error = ErrorCode;
  520. fn try_into(self) -> Result<FieldIdParams, Self::Error> {
  521. let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
  522. let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  523. Ok(FieldIdParams {
  524. grid_id: grid_id.0,
  525. field_id: field_id.0,
  526. })
  527. }
  528. }
  529. #[derive(Debug, Clone, Default, ProtoBuf)]
  530. pub struct DeleteFieldPayloadPB {
  531. #[pb(index = 1)]
  532. pub field_id: String,
  533. #[pb(index = 2)]
  534. pub grid_id: String,
  535. }
  536. impl TryInto<FieldIdParams> for DeleteFieldPayloadPB {
  537. type Error = ErrorCode;
  538. fn try_into(self) -> Result<FieldIdParams, Self::Error> {
  539. let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
  540. let field_id = NotEmptyStr::parse(self.field_id).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
  541. Ok(FieldIdParams {
  542. grid_id: grid_id.0,
  543. field_id: field_id.0,
  544. })
  545. }
  546. }
  547. pub struct FieldIdParams {
  548. pub field_id: String,
  549. pub grid_id: String,
  550. }