mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: add documentation
This commit is contained in:
parent
a0d0a13030
commit
3a7660108c
@ -1,5 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
|
@ -8,7 +8,7 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
|
||||
|
@ -4,7 +4,7 @@ import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_servic
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
|
@ -3,7 +3,7 @@ import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
|
||||
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_service.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'cell_service/cell_service.dart';
|
||||
|
||||
class SelectOptionService {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
@ -6,8 +6,10 @@ import 'package:protobuf/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
part 'edit_select_option_bloc.freezed.dart';
|
||||
|
||||
class EditSelectOptionBloc extends Bloc<EditSelectOptionEvent, EditSelectOptionState> {
|
||||
EditSelectOptionBloc({required SelectOptionPB option}) : super(EditSelectOptionState.initial(option)) {
|
||||
class EditSelectOptionBloc
|
||||
extends Bloc<EditSelectOptionEvent, EditSelectOptionState> {
|
||||
EditSelectOptionBloc({required SelectOptionPB option})
|
||||
: super(EditSelectOptionState.initial(option)) {
|
||||
on<EditSelectOptionEvent>(
|
||||
(event, emit) async {
|
||||
event.map(
|
||||
@ -48,7 +50,8 @@ class EditSelectOptionBloc extends Bloc<EditSelectOptionEvent, EditSelectOptionS
|
||||
@freezed
|
||||
class EditSelectOptionEvent with _$EditSelectOptionEvent {
|
||||
const factory EditSelectOptionEvent.updateName(String name) = _UpdateName;
|
||||
const factory EditSelectOptionEvent.updateColor(SelectOptionColorPB color) = _UpdateColor;
|
||||
const factory EditSelectOptionEvent.updateColor(SelectOptionColorPB color) =
|
||||
_UpdateColor;
|
||||
const factory EditSelectOptionEvent.delete() = _Delete;
|
||||
}
|
||||
|
||||
@ -59,7 +62,8 @@ class EditSelectOptionState with _$EditSelectOptionState {
|
||||
required Option<bool> deleted,
|
||||
}) = _EditSelectOptionState;
|
||||
|
||||
factory EditSelectOptionState.initial(SelectOptionPB option) => EditSelectOptionState(
|
||||
factory EditSelectOptionState.initial(SelectOptionPB option) =>
|
||||
EditSelectOptionState(
|
||||
option: option,
|
||||
deleted: none(),
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/multi_select_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'dart:async';
|
||||
import 'select_option_type_option_bloc.dart';
|
||||
import 'type_option_context.dart';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'dart:async';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/single_select_type_option.pb.dart';
|
||||
import 'dart:async';
|
||||
import 'package:protobuf/protobuf.dart';
|
||||
|
@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
|
||||
class TypeOptionFFIService {
|
||||
final String gridId;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
|
@ -7,7 +7,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
// ignore: unused_import
|
||||
import 'package:flowy_sdk/log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
@ -10,7 +10,7 @@ import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
@ -2,7 +2,7 @@ import 'dart:collection';
|
||||
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:app_flowy/generated/locale_keys.g.dart';
|
||||
|
@ -6,7 +6,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
@ -6,7 +6,7 @@ import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/select_type_option.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
@ -2,7 +2,7 @@ use crate::entities::*;
|
||||
use crate::manager::GridManager;
|
||||
use crate::services::cell::AnyCellData;
|
||||
use crate::services::field::{
|
||||
default_type_option_builder_from_type, select_option_operation, type_option_builder_from_json_str,
|
||||
default_type_option_builder_from_type, select_type_option_from_field_rev, type_option_builder_from_json_str,
|
||||
DateChangesetParams, DateChangesetPayloadPB, SelectOptionCellChangeset, SelectOptionCellChangesetParams,
|
||||
SelectOptionCellChangesetPayloadPB, SelectOptionCellDataPB, SelectOptionChangeset, SelectOptionChangesetPayloadPB,
|
||||
SelectOptionPB,
|
||||
@ -321,7 +321,7 @@ pub(crate) async fn new_select_option_handler(
|
||||
match editor.get_field_rev(¶ms.field_id).await {
|
||||
None => Err(ErrorCode::InvalidData.into()),
|
||||
Some(field_rev) => {
|
||||
let type_option = select_option_operation(&field_rev)?;
|
||||
let type_option = select_type_option_from_field_rev(&field_rev)?;
|
||||
let select_option = type_option.create_option(¶ms.option_name);
|
||||
data_result(select_option)
|
||||
}
|
||||
@ -338,7 +338,7 @@ pub(crate) async fn update_select_option_handler(
|
||||
|
||||
let _ = editor
|
||||
.modify_field_rev(&changeset.cell_identifier.field_id, |field_rev| {
|
||||
let mut type_option = select_option_operation(field_rev)?;
|
||||
let mut type_option = select_type_option_from_field_rev(field_rev)?;
|
||||
let mut cell_content_changeset = None;
|
||||
let mut is_changed = None;
|
||||
|
||||
@ -400,7 +400,7 @@ pub(crate) async fn get_select_option_handler(
|
||||
Some(field_rev) => {
|
||||
//
|
||||
let cell_rev = editor.get_cell_rev(¶ms.row_id, ¶ms.field_id).await?;
|
||||
let type_option = select_option_operation(&field_rev)?;
|
||||
let type_option = select_type_option_from_field_rev(&field_rev)?;
|
||||
let any_cell_data: AnyCellData = match cell_rev {
|
||||
None => AnyCellData {
|
||||
data: "".to_string(),
|
||||
@ -408,8 +408,8 @@ pub(crate) async fn get_select_option_handler(
|
||||
},
|
||||
Some(cell_rev) => cell_rev.try_into()?,
|
||||
};
|
||||
let option_context = type_option.selected_select_option(any_cell_data.into());
|
||||
data_result(option_context)
|
||||
let selected_options = type_option.get_selected_options(any_cell_data.into());
|
||||
data_result(selected_options)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,30 @@ pub trait CellGroupOperation {
|
||||
|
||||
/// Return object that describes the cell.
|
||||
pub trait CellDisplayable<CD> {
|
||||
/// Serialize the cell data into `CellBytes` that will be posted to `Dart` side
|
||||
/// Serialize the cell data into `CellBytes` that will be posted to the `Dart` side. Using the
|
||||
/// corresponding protobuf struct implement in `Dart` to deserialize the data.
|
||||
///
|
||||
/// Using `utf8` to encode the cell data if the cell data using `String` as its data container.
|
||||
/// Using `protobuf` to encode the cell data if the cell data using `Protobuf struct` as its data container.
|
||||
/// Using `utf8` to encode the cell data if the cell data use `String` as its data container.
|
||||
/// Using `protobuf` to encode the cell data if the cell data use `Protobuf struct` as its data container.
|
||||
///
|
||||
/// When switching the field type of the `FieldRevision` to another field type. The `field_type`
|
||||
/// of the `FieldRevision` is not equal to the `decoded_field_type`. The cell data is need to do
|
||||
/// some custom transformation.
|
||||
///
|
||||
/// For example, the current field type of the `FieldRevision` is a checkbox. When switching the field
|
||||
/// type from the checkbox to single select, the `TypeOptionBuilder`'s transform method gets called.
|
||||
/// It will create two new options,`Yes` and `No`, if they don't exist. But the cell data didn't change,
|
||||
/// because we can't iterate all the rows to transform the cell data that can be parsed by the current
|
||||
/// field type. One approach is to transform the cell data when it get read. For the moment,
|
||||
/// the cell data is a string, `Yes` or `No`. It needs to compare with the option's name, if match
|
||||
/// return the id of the option. Otherwise, return a default value of `CellBytes`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `cell_data`: the generic annotation `CD` represents as the deserialize data type of the cell.
|
||||
/// * `decoded_field_type`: the field type of the cell_data when doing serialization
|
||||
///
|
||||
/// returns: Result<CellBytes, FlowyError>
|
||||
///
|
||||
fn displayed_cell_bytes(
|
||||
&self,
|
||||
@ -35,10 +55,10 @@ pub trait CellDisplayable<CD> {
|
||||
/// The cell data is not readable which means it can't display the cell data directly to user.
|
||||
/// For example,
|
||||
/// 1. the cell data is timestamp if its field type is FieldType::Date that is not readable.
|
||||
/// it needs to be parsed as the date string.
|
||||
/// It needs to be parsed as the date string.
|
||||
///
|
||||
/// 2. the cell data is a commas separated id if its field type if FieldType::MultiSelect that is not readable.
|
||||
/// it needs to be parsed as a commas separated option name.
|
||||
/// It needs to be parsed as a commas separated option name.
|
||||
///
|
||||
fn displayed_cell_string(
|
||||
&self,
|
||||
@ -48,16 +68,19 @@ pub trait CellDisplayable<CD> {
|
||||
) -> FlowyResult<String>;
|
||||
}
|
||||
|
||||
// CD: Short for CellData. This type is the type return by apply_changeset function.
|
||||
// CS: Short for Changeset. Parse the string into specific Changeset type.
|
||||
pub trait CellDataOperation<CD, CS> {
|
||||
/// Decode the cell data into `CD` that is certain type of data.
|
||||
/// The generic annotation `CD` represents as the deserialize data type of the cell data.
|
||||
/// The Serialize/Deserialize struct of the cell is base on the field type of the cell.
|
||||
///
|
||||
/// Each `CD` type represents as a specific field type data. For example:
|
||||
/// For example:
|
||||
/// FieldType::URL => URLCellData
|
||||
/// FieldType::Date=> DateCellData
|
||||
///
|
||||
/// `decoded_field_type`: the field type of the cell data
|
||||
/// Each cell data is a opaque data, it needs to deserialized to a concrete data struct
|
||||
///
|
||||
/// `cell_data`: the opaque data of the cell.
|
||||
/// `decoded_field_type`: the field type of the cell data when doing serialization
|
||||
/// `field_rev`: the field of the cell data
|
||||
///
|
||||
/// Returns the error if the cell data can't be parsed into `CD`.
|
||||
///
|
||||
@ -68,9 +91,12 @@ pub trait CellDataOperation<CD, CS> {
|
||||
field_rev: &FieldRevision,
|
||||
) -> FlowyResult<CellBytes>;
|
||||
|
||||
/// The changeset is able to parse into the specific data if CS impl the FromCellChangeset trait.
|
||||
/// The changeset is able to parse into the concrete data struct if CS implements
|
||||
/// the `FromCellChangeset` trait.
|
||||
///
|
||||
/// For example:
|
||||
/// SelectOptionCellChangeset,DateCellChangeset. etc.
|
||||
/// SelectOptionCellChangeset,DateCellChangeset. etc.
|
||||
///
|
||||
fn apply_changeset(&self, changeset: CellDataChangeset<CS>, cell_rev: Option<CellRevision>) -> FlowyResult<String>;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,10 @@ use bytes::Bytes;
|
||||
use flowy_grid_data_model::revision::TypeOptionDataSerializer;
|
||||
|
||||
pub trait TypeOptionBuilder {
|
||||
/// Returns the type of the type-option data
|
||||
fn field_type(&self) -> FieldType;
|
||||
|
||||
/// Returns a serializer that can be used to serialize the type-option data
|
||||
fn serializer(&self) -> &dyn TypeOptionDataSerializer;
|
||||
|
||||
/// Transform the data from passed-in type-option to current type-option
|
||||
|
@ -1,7 +1,7 @@
|
||||
mod multi_select_type_option;
|
||||
mod select_option;
|
||||
mod select_type_option;
|
||||
mod single_select_type_option;
|
||||
|
||||
pub use multi_select_type_option::*;
|
||||
pub use select_option::*;
|
||||
pub use select_type_option::*;
|
||||
pub use single_select_type_option::*;
|
||||
|
@ -3,8 +3,8 @@ use crate::impl_type_option;
|
||||
use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable};
|
||||
use crate::services::field::type_options::util::get_cell_data;
|
||||
use crate::services::field::{
|
||||
make_selected_select_options, BoxTypeOptionBuilder, SelectOptionCellChangeset, SelectOptionCellDataPB,
|
||||
SelectOptionColorPB, SelectOptionIds, SelectOptionOperation, SelectOptionPB, TypeOptionBuilder, CHECK, UNCHECK,
|
||||
BoxTypeOptionBuilder, SelectOptionCellChangeset, SelectOptionIds, SelectOptionPB, SelectTypeOptionSharedAction,
|
||||
TypeOptionBuilder,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::ProtoBuf;
|
||||
@ -25,13 +25,9 @@ pub struct MultiSelectTypeOptionPB {
|
||||
}
|
||||
impl_type_option!(MultiSelectTypeOptionPB, FieldType::MultiSelect);
|
||||
|
||||
impl SelectOptionOperation for MultiSelectTypeOptionPB {
|
||||
fn selected_select_option(&self, cell_data: CellData<SelectOptionIds>) -> SelectOptionCellDataPB {
|
||||
let select_options = make_selected_select_options(cell_data, &self.options);
|
||||
SelectOptionCellDataPB {
|
||||
options: self.options.clone(),
|
||||
select_options,
|
||||
}
|
||||
impl SelectTypeOptionSharedAction for MultiSelectTypeOptionPB {
|
||||
fn number_of_max_options(&self) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
|
||||
fn options(&self) -> &Vec<SelectOptionPB> {
|
||||
@ -113,23 +109,8 @@ impl TypeOptionBuilder for MultiSelectTypeOptionBuilder {
|
||||
&self.0
|
||||
}
|
||||
|
||||
fn transform(&mut self, field_type: &FieldType, _type_option_data: String) {
|
||||
match field_type {
|
||||
FieldType::Checkbox => {
|
||||
//Add Yes and No options if it's not exist.
|
||||
if !self.0.options.iter().any(|option| option.name == CHECK) {
|
||||
let check_option = SelectOptionPB::with_color(CHECK, SelectOptionColorPB::Green);
|
||||
self.0.options.push(check_option);
|
||||
}
|
||||
|
||||
if !self.0.options.iter().any(|option| option.name == UNCHECK) {
|
||||
let uncheck_option = SelectOptionPB::with_color(UNCHECK, SelectOptionColorPB::Yellow);
|
||||
self.0.options.push(uncheck_option);
|
||||
}
|
||||
}
|
||||
FieldType::SingleSelect => {}
|
||||
_ => {}
|
||||
}
|
||||
fn transform(&mut self, field_type: &FieldType, type_option_data: String) {
|
||||
self.0.transform_type_option(field_type, type_option_data);
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
@ -154,6 +135,8 @@ mod tests {
|
||||
debug_assert_eq!(multi_select.0.options.len(), 2);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
|
||||
#[test]
|
||||
fn multi_select_insert_multi_option_test() {
|
||||
let google = SelectOptionPB::new("Google");
|
||||
|
@ -2,7 +2,7 @@ use crate::entities::{CellChangesetPB, FieldType, GridCellIdPB, GridCellIdParams
|
||||
use crate::services::cell::{
|
||||
CellBytes, CellBytesParser, CellData, CellDataIsEmpty, CellDisplayable, FromCellChangeset, FromCellString,
|
||||
};
|
||||
use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
|
||||
use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB, CHECK, UNCHECK};
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
||||
@ -64,10 +64,7 @@ impl std::default::Default for SelectOptionColorPB {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_selected_select_options(
|
||||
cell_data: CellData<SelectOptionIds>,
|
||||
options: &[SelectOptionPB],
|
||||
) -> Vec<SelectOptionPB> {
|
||||
pub fn make_selected_options(cell_data: CellData<SelectOptionIds>, options: &[SelectOptionPB]) -> Vec<SelectOptionPB> {
|
||||
if let Ok(ids) = cell_data.try_into_inner() {
|
||||
ids.iter()
|
||||
.flat_map(|option_id| options.iter().find(|option| &option.id == option_id).cloned())
|
||||
@ -76,8 +73,11 @@ pub fn make_selected_select_options(
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
/// Defines the shared actions used by SingleSelect or Multi-Select.
|
||||
pub trait SelectTypeOptionSharedAction: TypeOptionDataSerializer + Send + Sync {
|
||||
/// Returns `None` means there is no limited
|
||||
fn number_of_max_options(&self) -> Option<usize>;
|
||||
|
||||
pub trait SelectOptionOperation: TypeOptionDataSerializer + Send + Sync {
|
||||
/// Insert the `SelectOptionPB` into corresponding type option.
|
||||
fn insert_option(&mut self, new_option: SelectOptionPB) {
|
||||
let options = self.mut_options();
|
||||
@ -104,7 +104,60 @@ pub trait SelectOptionOperation: TypeOptionDataSerializer + Send + Sync {
|
||||
SelectOptionPB::with_color(name, color)
|
||||
}
|
||||
|
||||
fn selected_select_option(&self, cell_data: CellData<SelectOptionIds>) -> SelectOptionCellDataPB;
|
||||
/// Return a list of options that are selected by user
|
||||
fn get_selected_options(&self, cell_data: CellData<SelectOptionIds>) -> SelectOptionCellDataPB {
|
||||
let mut select_options = make_selected_options(cell_data, self.options());
|
||||
match self.number_of_max_options() {
|
||||
None => {}
|
||||
Some(number_of_max_options) => {
|
||||
select_options.truncate(number_of_max_options);
|
||||
}
|
||||
}
|
||||
SelectOptionCellDataPB {
|
||||
options: self.options().clone(),
|
||||
select_options,
|
||||
}
|
||||
}
|
||||
|
||||
fn transform_type_option(&mut self, field_type: &FieldType, _type_option_data: String) {
|
||||
match field_type {
|
||||
FieldType::Checkbox => {
|
||||
//add Yes and No options if it's not exist.
|
||||
if !self.options().iter().any(|option| option.name == CHECK) {
|
||||
let check_option = SelectOptionPB::with_color(CHECK, SelectOptionColorPB::Green);
|
||||
self.mut_options().push(check_option);
|
||||
}
|
||||
|
||||
if !self.options().iter().any(|option| option.name == UNCHECK) {
|
||||
let uncheck_option = SelectOptionPB::with_color(UNCHECK, SelectOptionColorPB::Yellow);
|
||||
self.mut_options().push(uncheck_option);
|
||||
}
|
||||
}
|
||||
FieldType::MultiSelect => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn transform_cell_data(
|
||||
&self,
|
||||
cell_data: CellData<SelectOptionIds>,
|
||||
decoded_field_type: &FieldType,
|
||||
_field_rev: &FieldRevision,
|
||||
) -> FlowyResult<CellBytes> {
|
||||
match decoded_field_type {
|
||||
FieldType::SingleSelect | FieldType::MultiSelect => {
|
||||
// Do nothing
|
||||
}
|
||||
FieldType::Checkbox => {
|
||||
// transform the cell data to the option id
|
||||
}
|
||||
_ => {
|
||||
return Ok(CellBytes::default());
|
||||
}
|
||||
}
|
||||
|
||||
CellBytes::from(self.get_selected_options(cell_data))
|
||||
}
|
||||
|
||||
fn options(&self) -> &Vec<SelectOptionPB>;
|
||||
|
||||
@ -113,19 +166,15 @@ pub trait SelectOptionOperation: TypeOptionDataSerializer + Send + Sync {
|
||||
|
||||
impl<T> CellDisplayable<SelectOptionIds> for T
|
||||
where
|
||||
T: SelectOptionOperation,
|
||||
T: SelectTypeOptionSharedAction,
|
||||
{
|
||||
fn displayed_cell_bytes(
|
||||
&self,
|
||||
cell_data: CellData<SelectOptionIds>,
|
||||
decoded_field_type: &FieldType,
|
||||
_field_rev: &FieldRevision,
|
||||
field_rev: &FieldRevision,
|
||||
) -> FlowyResult<CellBytes> {
|
||||
if !decoded_field_type.is_select_option() {
|
||||
return Ok(CellBytes::default());
|
||||
}
|
||||
|
||||
CellBytes::from(self.selected_select_option(cell_data))
|
||||
self.transform_cell_data(cell_data, decoded_field_type, field_rev)
|
||||
}
|
||||
|
||||
fn displayed_cell_string(
|
||||
@ -135,7 +184,7 @@ where
|
||||
_field_rev: &FieldRevision,
|
||||
) -> FlowyResult<String> {
|
||||
Ok(self
|
||||
.selected_select_option(cell_data)
|
||||
.get_selected_options(cell_data)
|
||||
.select_options
|
||||
.into_iter()
|
||||
.map(|option| option.name)
|
||||
@ -144,7 +193,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_option_operation(field_rev: &FieldRevision) -> FlowyResult<Box<dyn SelectOptionOperation>> {
|
||||
pub fn select_type_option_from_field_rev(
|
||||
field_rev: &FieldRevision,
|
||||
) -> FlowyResult<Box<dyn SelectTypeOptionSharedAction>> {
|
||||
let field_type: FieldType = field_rev.ty.into();
|
||||
match &field_type {
|
||||
FieldType::SingleSelect => {
|
@ -1,11 +1,10 @@
|
||||
use crate::entities::FieldType;
|
||||
use crate::impl_type_option;
|
||||
use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable};
|
||||
use crate::services::field::{
|
||||
make_selected_select_options, SelectOptionCellChangeset, SelectOptionCellDataPB, SelectOptionColorPB,
|
||||
SelectOptionIds, SelectOptionOperation, SelectOptionPB, CHECK, UNCHECK,
|
||||
};
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use crate::services::field::{
|
||||
SelectOptionCellChangeset, SelectOptionIds, SelectOptionPB, SelectTypeOptionSharedAction,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
@ -25,15 +24,9 @@ pub struct SingleSelectTypeOptionPB {
|
||||
}
|
||||
impl_type_option!(SingleSelectTypeOptionPB, FieldType::SingleSelect);
|
||||
|
||||
impl SelectOptionOperation for SingleSelectTypeOptionPB {
|
||||
fn selected_select_option(&self, cell_data: CellData<SelectOptionIds>) -> SelectOptionCellDataPB {
|
||||
let mut select_options = make_selected_select_options(cell_data, &self.options);
|
||||
// only keep option in single select
|
||||
select_options.truncate(1);
|
||||
SelectOptionCellDataPB {
|
||||
options: self.options.clone(),
|
||||
select_options,
|
||||
}
|
||||
impl SelectTypeOptionSharedAction for SingleSelectTypeOptionPB {
|
||||
fn number_of_max_options(&self) -> Option<usize> {
|
||||
Some(1)
|
||||
}
|
||||
|
||||
fn options(&self) -> &Vec<SelectOptionPB> {
|
||||
@ -102,23 +95,8 @@ impl TypeOptionBuilder for SingleSelectTypeOptionBuilder {
|
||||
&self.0
|
||||
}
|
||||
|
||||
fn transform(&mut self, field_type: &FieldType, _type_option_data: String) {
|
||||
match field_type {
|
||||
FieldType::Checkbox => {
|
||||
//add Yes and No options if it's not exist.
|
||||
if !self.0.options.iter().any(|option| option.name == CHECK) {
|
||||
let check_option = SelectOptionPB::with_color(CHECK, SelectOptionColorPB::Green);
|
||||
self.0.options.push(check_option);
|
||||
}
|
||||
|
||||
if !self.0.options.iter().any(|option| option.name == UNCHECK) {
|
||||
let uncheck_option = SelectOptionPB::with_color(UNCHECK, SelectOptionColorPB::Yellow);
|
||||
self.0.options.push(uncheck_option);
|
||||
}
|
||||
}
|
||||
FieldType::MultiSelect => {}
|
||||
_ => {}
|
||||
}
|
||||
fn transform(&mut self, field_type: &FieldType, type_option_data: String) {
|
||||
self.0.transform_type_option(field_type, type_option_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
use crate::entities::{SelectOptionCondition, SelectOptionFilterConfigurationPB};
|
||||
use crate::services::cell::{AnyCellData, CellFilterOperation};
|
||||
use crate::services::field::{MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
|
||||
use crate::services::field::{SelectOptionOperation, SelectedSelectOptions};
|
||||
use crate::services::field::{SelectTypeOptionSharedAction, SelectedSelectOptions};
|
||||
use flowy_error::FlowyResult;
|
||||
|
||||
impl SelectOptionFilterConfigurationPB {
|
||||
@ -49,7 +49,7 @@ impl CellFilterOperation<SelectOptionFilterConfigurationPB> for MultiSelectTypeO
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let selected_options = SelectedSelectOptions::from(self.selected_select_option(any_cell_data.into()));
|
||||
let selected_options = SelectedSelectOptions::from(self.get_selected_options(any_cell_data.into()));
|
||||
Ok(filter.is_visible(&selected_options))
|
||||
}
|
||||
}
|
||||
@ -63,7 +63,7 @@ impl CellFilterOperation<SelectOptionFilterConfigurationPB> for SingleSelectType
|
||||
if !any_cell_data.is_single_select() {
|
||||
return Ok(true);
|
||||
}
|
||||
let selected_options = SelectedSelectOptions::from(self.selected_select_option(any_cell_data.into()));
|
||||
let selected_options = SelectedSelectOptions::from(self.get_selected_options(any_cell_data.into()));
|
||||
Ok(filter.is_visible(&selected_options))
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use flowy_grid::entities::{
|
||||
};
|
||||
use flowy_grid::services::cell::{delete_select_option_cell, insert_select_option_cell};
|
||||
use flowy_grid::services::field::{
|
||||
edit_single_select_type_option, SelectOptionOperation, SelectOptionPB, SingleSelectTypeOptionPB,
|
||||
edit_single_select_type_option, SelectOptionPB, SelectTypeOptionSharedAction, SingleSelectTypeOptionPB,
|
||||
};
|
||||
use flowy_grid_data_model::revision::{FieldRevision, RowChangeset};
|
||||
use std::sync::Arc;
|
||||
|
Loading…
Reference in New Issue
Block a user