select_option.rs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. use crate::entities::{CellChangeset, CellIdentifier, CellIdentifierPayload, FieldType};
  2. use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOption};
  3. use crate::services::row::AnyCellData;
  4. use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
  5. use flowy_error::{ErrorCode, FlowyError, FlowyResult};
  6. use flowy_grid_data_model::parser::NotEmptyStr;
  7. use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataEntry};
  8. use nanoid::nanoid;
  9. use serde::{Deserialize, Serialize};
  10. pub const SELECTION_IDS_SEPARATOR: &str = ",";
  11. #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, ProtoBuf)]
  12. pub struct SelectOption {
  13. #[pb(index = 1)]
  14. pub id: String,
  15. #[pb(index = 2)]
  16. pub name: String,
  17. #[pb(index = 3)]
  18. pub color: SelectOptionColor,
  19. }
  20. impl SelectOption {
  21. pub fn new(name: &str) -> Self {
  22. SelectOption {
  23. id: nanoid!(4),
  24. name: name.to_owned(),
  25. color: SelectOptionColor::default(),
  26. }
  27. }
  28. pub fn with_color(name: &str, color: SelectOptionColor) -> Self {
  29. SelectOption {
  30. id: nanoid!(4),
  31. name: name.to_owned(),
  32. color,
  33. }
  34. }
  35. }
  36. #[derive(ProtoBuf_Enum, PartialEq, Eq, Serialize, Deserialize, Debug, Clone)]
  37. #[repr(u8)]
  38. pub enum SelectOptionColor {
  39. Purple = 0,
  40. Pink = 1,
  41. LightPink = 2,
  42. Orange = 3,
  43. Yellow = 4,
  44. Lime = 5,
  45. Green = 6,
  46. Aqua = 7,
  47. Blue = 8,
  48. }
  49. impl std::default::Default for SelectOptionColor {
  50. fn default() -> Self {
  51. SelectOptionColor::Purple
  52. }
  53. }
  54. pub fn make_selected_select_options<T: TryInto<AnyCellData>>(
  55. any_cell_data: T,
  56. options: &[SelectOption],
  57. ) -> Vec<SelectOption> {
  58. if let Ok(type_option_cell_data) = any_cell_data.try_into() {
  59. let ids = SelectOptionIds::from(type_option_cell_data.cell_data);
  60. ids.iter()
  61. .flat_map(|option_id| options.iter().find(|option| &option.id == option_id).cloned())
  62. .collect()
  63. } else {
  64. vec![]
  65. }
  66. }
  67. pub trait SelectOptionOperation: TypeOptionDataEntry + Send + Sync {
  68. fn insert_option(&mut self, new_option: SelectOption) {
  69. let options = self.mut_options();
  70. if let Some(index) = options
  71. .iter()
  72. .position(|option| option.id == new_option.id || option.name == new_option.name)
  73. {
  74. options.remove(index);
  75. options.insert(index, new_option);
  76. } else {
  77. options.insert(0, new_option);
  78. }
  79. }
  80. fn delete_option(&mut self, delete_option: SelectOption) {
  81. let options = self.mut_options();
  82. if let Some(index) = options.iter().position(|option| option.id == delete_option.id) {
  83. options.remove(index);
  84. }
  85. }
  86. fn create_option(&self, name: &str) -> SelectOption {
  87. let color = select_option_color_from_index(self.options().len());
  88. SelectOption::with_color(name, color)
  89. }
  90. fn selected_select_option(&self, any_cell_data: AnyCellData) -> SelectOptionCellData;
  91. fn options(&self) -> &Vec<SelectOption>;
  92. fn mut_options(&mut self) -> &mut Vec<SelectOption>;
  93. }
  94. pub fn select_option_operation(field_rev: &FieldRevision) -> FlowyResult<Box<dyn SelectOptionOperation>> {
  95. let field_type: FieldType = field_rev.field_type_rev.into();
  96. match &field_type {
  97. FieldType::SingleSelect => {
  98. let type_option = SingleSelectTypeOption::from(field_rev);
  99. Ok(Box::new(type_option))
  100. }
  101. FieldType::MultiSelect => {
  102. let type_option = MultiSelectTypeOption::from(field_rev);
  103. Ok(Box::new(type_option))
  104. }
  105. ty => {
  106. tracing::error!("Unsupported field type: {:?} for this handler", ty);
  107. Err(ErrorCode::FieldInvalidOperation.into())
  108. }
  109. }
  110. }
  111. pub fn select_option_color_from_index(index: usize) -> SelectOptionColor {
  112. match index % 8 {
  113. 0 => SelectOptionColor::Purple,
  114. 1 => SelectOptionColor::Pink,
  115. 2 => SelectOptionColor::LightPink,
  116. 3 => SelectOptionColor::Orange,
  117. 4 => SelectOptionColor::Yellow,
  118. 5 => SelectOptionColor::Lime,
  119. 6 => SelectOptionColor::Green,
  120. 7 => SelectOptionColor::Aqua,
  121. 8 => SelectOptionColor::Blue,
  122. _ => SelectOptionColor::Purple,
  123. }
  124. }
  125. pub struct SelectOptionIds(Vec<String>);
  126. impl SelectOptionIds {
  127. pub fn into_inner(self) -> Vec<String> {
  128. self.0
  129. }
  130. }
  131. impl std::convert::TryFrom<AnyCellData> for SelectOptionIds {
  132. type Error = FlowyError;
  133. fn try_from(value: AnyCellData) -> Result<Self, Self::Error> {
  134. Ok(Self::from(value.cell_data))
  135. }
  136. }
  137. impl std::convert::From<String> for SelectOptionIds {
  138. fn from(s: String) -> Self {
  139. let ids = s
  140. .split(SELECTION_IDS_SEPARATOR)
  141. .map(|id| id.to_string())
  142. .collect::<Vec<String>>();
  143. Self(ids)
  144. }
  145. }
  146. impl std::convert::From<Option<String>> for SelectOptionIds {
  147. fn from(s: Option<String>) -> Self {
  148. match s {
  149. None => Self { 0: vec![] },
  150. Some(s) => Self::from(s),
  151. }
  152. }
  153. }
  154. impl std::ops::Deref for SelectOptionIds {
  155. type Target = Vec<String>;
  156. fn deref(&self) -> &Self::Target {
  157. &self.0
  158. }
  159. }
  160. impl std::ops::DerefMut for SelectOptionIds {
  161. fn deref_mut(&mut self) -> &mut Self::Target {
  162. &mut self.0
  163. }
  164. }
  165. #[derive(Clone, Debug, Default, ProtoBuf)]
  166. pub struct SelectOptionCellChangesetPayload {
  167. #[pb(index = 1)]
  168. pub cell_identifier: CellIdentifierPayload,
  169. #[pb(index = 2, one_of)]
  170. pub insert_option_id: Option<String>,
  171. #[pb(index = 3, one_of)]
  172. pub delete_option_id: Option<String>,
  173. }
  174. pub struct SelectOptionCellChangesetParams {
  175. pub cell_identifier: CellIdentifier,
  176. pub insert_option_id: Option<String>,
  177. pub delete_option_id: Option<String>,
  178. }
  179. impl std::convert::From<SelectOptionCellChangesetParams> for CellChangeset {
  180. fn from(params: SelectOptionCellChangesetParams) -> Self {
  181. let changeset = SelectOptionCellContentChangeset {
  182. insert_option_id: params.insert_option_id,
  183. delete_option_id: params.delete_option_id,
  184. };
  185. let s = serde_json::to_string(&changeset).unwrap();
  186. CellChangeset {
  187. grid_id: params.cell_identifier.grid_id,
  188. row_id: params.cell_identifier.row_id,
  189. field_id: params.cell_identifier.field_id,
  190. cell_content_changeset: Some(s),
  191. }
  192. }
  193. }
  194. impl TryInto<SelectOptionCellChangesetParams> for SelectOptionCellChangesetPayload {
  195. type Error = ErrorCode;
  196. fn try_into(self) -> Result<SelectOptionCellChangesetParams, Self::Error> {
  197. let cell_identifier: CellIdentifier = self.cell_identifier.try_into()?;
  198. let insert_option_id = match self.insert_option_id {
  199. None => None,
  200. Some(insert_option_id) => Some(
  201. NotEmptyStr::parse(insert_option_id)
  202. .map_err(|_| ErrorCode::OptionIdIsEmpty)?
  203. .0,
  204. ),
  205. };
  206. let delete_option_id = match self.delete_option_id {
  207. None => None,
  208. Some(delete_option_id) => Some(
  209. NotEmptyStr::parse(delete_option_id)
  210. .map_err(|_| ErrorCode::OptionIdIsEmpty)?
  211. .0,
  212. ),
  213. };
  214. Ok(SelectOptionCellChangesetParams {
  215. cell_identifier,
  216. insert_option_id,
  217. delete_option_id,
  218. })
  219. }
  220. }
  221. #[derive(Clone, Serialize, Deserialize)]
  222. pub struct SelectOptionCellContentChangeset {
  223. pub insert_option_id: Option<String>,
  224. pub delete_option_id: Option<String>,
  225. }
  226. impl SelectOptionCellContentChangeset {
  227. pub fn from_insert(option_id: &str) -> Self {
  228. SelectOptionCellContentChangeset {
  229. insert_option_id: Some(option_id.to_string()),
  230. delete_option_id: None,
  231. }
  232. }
  233. pub fn from_delete(option_id: &str) -> Self {
  234. SelectOptionCellContentChangeset {
  235. insert_option_id: None,
  236. delete_option_id: Some(option_id.to_string()),
  237. }
  238. }
  239. pub fn to_str(&self) -> String {
  240. serde_json::to_string(self).unwrap()
  241. }
  242. }
  243. #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)]
  244. pub struct SelectOptionCellData {
  245. #[pb(index = 1)]
  246. pub options: Vec<SelectOption>,
  247. #[pb(index = 2)]
  248. pub select_options: Vec<SelectOption>,
  249. }
  250. #[derive(Clone, Debug, Default, ProtoBuf)]
  251. pub struct SelectOptionChangesetPayload {
  252. #[pb(index = 1)]
  253. pub cell_identifier: CellIdentifierPayload,
  254. #[pb(index = 2, one_of)]
  255. pub insert_option: Option<SelectOption>,
  256. #[pb(index = 3, one_of)]
  257. pub update_option: Option<SelectOption>,
  258. #[pb(index = 4, one_of)]
  259. pub delete_option: Option<SelectOption>,
  260. }
  261. pub struct SelectOptionChangeset {
  262. pub cell_identifier: CellIdentifier,
  263. pub insert_option: Option<SelectOption>,
  264. pub update_option: Option<SelectOption>,
  265. pub delete_option: Option<SelectOption>,
  266. }
  267. impl TryInto<SelectOptionChangeset> for SelectOptionChangesetPayload {
  268. type Error = ErrorCode;
  269. fn try_into(self) -> Result<SelectOptionChangeset, Self::Error> {
  270. let cell_identifier = self.cell_identifier.try_into()?;
  271. Ok(SelectOptionChangeset {
  272. cell_identifier,
  273. insert_option: self.insert_option,
  274. update_option: self.update_option,
  275. delete_option: self.delete_option,
  276. })
  277. }
  278. }
  279. pub struct SelectedSelectOptions {
  280. pub(crate) options: Vec<SelectOption>,
  281. }
  282. impl std::convert::From<SelectOptionCellData> for SelectedSelectOptions {
  283. fn from(data: SelectOptionCellData) -> Self {
  284. Self {
  285. options: data.select_options,
  286. }
  287. }
  288. }