mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: insert cell content when creating card
This commit is contained in:
parent
f0914cd6f1
commit
43eaa2748d
@ -52,8 +52,8 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
_startListening();
|
||||
await _loadGrid(emit);
|
||||
},
|
||||
createRow: () async {
|
||||
final result = await _dataController.createRow();
|
||||
createRow: (groupId) async {
|
||||
final result = await _dataController.createBoardCard(groupId);
|
||||
result.fold(
|
||||
(rowPB) {
|
||||
emit(state.copyWith(editingRow: some(rowPB)));
|
||||
@ -153,7 +153,7 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
||||
@freezed
|
||||
class BoardEvent with _$BoardEvent {
|
||||
const factory BoardEvent.initial() = InitialGrid;
|
||||
const factory BoardEvent.createRow() = _CreateRow;
|
||||
const factory BoardEvent.createRow(String groupId) = _CreateRow;
|
||||
const factory BoardEvent.endEditRow(String rowId) = _EndEditRow;
|
||||
const factory BoardEvent.didReceiveGroups(List<GroupPB> groups) =
|
||||
_DidReceiveGroup;
|
||||
|
@ -21,7 +21,7 @@ typedef OnError = void Function(FlowyError);
|
||||
|
||||
class BoardDataController {
|
||||
final String gridId;
|
||||
final GridService _gridFFIService;
|
||||
final GridFFIService _gridFFIService;
|
||||
final GridFieldCache fieldCache;
|
||||
|
||||
// key: the block id
|
||||
@ -45,7 +45,7 @@ class BoardDataController {
|
||||
BoardDataController({required ViewPB view})
|
||||
: gridId = view.id,
|
||||
_blocks = LinkedHashMap.new(),
|
||||
_gridFFIService = GridService(gridId: view.id),
|
||||
_gridFFIService = GridFFIService(gridId: view.id),
|
||||
fieldCache = GridFieldCache(gridId: view.id);
|
||||
|
||||
void addListener({
|
||||
@ -88,8 +88,8 @@ class BoardDataController {
|
||||
);
|
||||
}
|
||||
|
||||
Future<Either<RowPB, FlowyError>> createRow() {
|
||||
return _gridFFIService.createRow();
|
||||
Future<Either<RowPB, FlowyError>> createBoardCard(String groupId) {
|
||||
return _gridFFIService.createBoardCard(groupId);
|
||||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
|
@ -88,7 +88,7 @@ class BoardContent extends StatelessWidget {
|
||||
height: 50,
|
||||
margin: config.columnItemPadding,
|
||||
onAddButtonClick: () {
|
||||
context.read<BoardBloc>().add(const BoardEvent.createRow());
|
||||
context.read<BoardBloc>().add(BoardEvent.createRow(columnData.id));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ typedef ListenOnRowChangedCondition = bool Function();
|
||||
|
||||
class GridDataController {
|
||||
final String gridId;
|
||||
final GridService _gridFFIService;
|
||||
final GridFFIService _gridFFIService;
|
||||
final GridFieldCache fieldCache;
|
||||
|
||||
// key: the block id
|
||||
@ -47,7 +47,7 @@ class GridDataController {
|
||||
GridDataController({required ViewPB view})
|
||||
: gridId = view.id,
|
||||
_blocks = LinkedHashMap.new(),
|
||||
_gridFFIService = GridService(gridId: view.id),
|
||||
_gridFFIService = GridFFIService(gridId: view.id),
|
||||
fieldCache = GridFieldCache(gridId: view.id);
|
||||
|
||||
void addListener({
|
||||
|
@ -3,14 +3,15 @@ import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/board_card.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/group.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-grid/row_entities.pb.dart';
|
||||
|
||||
class GridService {
|
||||
class GridFFIService {
|
||||
final String gridId;
|
||||
GridService({
|
||||
GridFFIService({
|
||||
required this.gridId,
|
||||
});
|
||||
|
||||
@ -27,6 +28,13 @@ class GridService {
|
||||
return GridEventCreateRow(payload).send();
|
||||
}
|
||||
|
||||
Future<Either<RowPB, FlowyError>> createBoardCard(String groupId) {
|
||||
CreateBoardCardPayloadPB payload = CreateBoardCardPayloadPB.create()
|
||||
..gridId = gridId
|
||||
..groupId = groupId;
|
||||
return GridEventCreateBoardCard(payload).send();
|
||||
}
|
||||
|
||||
Future<Either<RepeatedFieldPB, FlowyError>> getFields(
|
||||
{required List<FieldIdPB> fieldIds}) {
|
||||
final payload = QueryFieldPayloadPB.create()
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::entities::RowPB;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::ErrorCode;
|
||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||
@ -27,3 +28,43 @@ impl TryInto<CreateBoardCardParams> for CreateBoardCardPayloadPB {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf)]
|
||||
pub struct BoardCardChangesetPB {
|
||||
#[pb(index = 1)]
|
||||
pub group_id: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub inserted_cards: Vec<RowPB>,
|
||||
|
||||
#[pb(index = 3)]
|
||||
pub deleted_cards: Vec<String>,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub updated_cards: Vec<RowPB>,
|
||||
}
|
||||
impl BoardCardChangesetPB {
|
||||
pub fn insert(group_id: String, inserted_cards: Vec<RowPB>) -> Self {
|
||||
Self {
|
||||
group_id,
|
||||
inserted_cards,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delete(group_id: String, deleted_cards: Vec<String>) -> Self {
|
||||
Self {
|
||||
group_id,
|
||||
deleted_cards,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(group_id: String, updated_cards: Vec<RowPB>) -> Self {
|
||||
Self {
|
||||
group_id,
|
||||
updated_cards,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -424,6 +424,6 @@ pub(crate) async fn create_board_card_handler(
|
||||
) -> DataResult<RowPB, FlowyError> {
|
||||
let params: CreateBoardCardParams = data.into_inner().try_into()?;
|
||||
let editor = manager.get_grid_editor(params.grid_id.as_ref())?;
|
||||
let row = editor.create_board_card().await?;
|
||||
let row = editor.create_board_card(¶ms.group_id).await?;
|
||||
data_result(row)
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ pub fn create(grid_manager: Arc<GridManager>) -> Module {
|
||||
// Date
|
||||
.event(GridEvent::UpdateDateCell, update_date_cell_handler)
|
||||
// Group
|
||||
.event(GridEvent::CreateBoardCard, create_row_handler)
|
||||
.event(GridEvent::CreateBoardCard, create_board_card_handler)
|
||||
.event(GridEvent::GetGroup, get_groups_handler);
|
||||
|
||||
module
|
||||
|
@ -135,6 +135,47 @@ pub fn try_decode_cell_data(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_text_cell(s: String, field_rev: &FieldRevision) -> CellRevision {
|
||||
let data = apply_cell_data_changeset(s, None, field_rev).unwrap();
|
||||
CellRevision::new(data)
|
||||
}
|
||||
|
||||
pub fn insert_number_cell(num: i64, field_rev: &FieldRevision) -> CellRevision {
|
||||
let data = apply_cell_data_changeset(num, None, field_rev).unwrap();
|
||||
CellRevision::new(data)
|
||||
}
|
||||
|
||||
pub fn insert_url_cell(url: String, field_rev: &FieldRevision) -> CellRevision {
|
||||
let data = apply_cell_data_changeset(url, None, field_rev).unwrap();
|
||||
CellRevision::new(data)
|
||||
}
|
||||
|
||||
pub fn insert_checkbox_cell(is_check: bool, field_rev: &FieldRevision) -> CellRevision {
|
||||
let s = if is_check {
|
||||
CHECK.to_string()
|
||||
} else {
|
||||
UNCHECK.to_string()
|
||||
};
|
||||
let data = apply_cell_data_changeset(s, None, field_rev).unwrap();
|
||||
CellRevision::new(data)
|
||||
}
|
||||
|
||||
pub fn insert_date_cell(timestamp: i64, field_rev: &FieldRevision) -> CellRevision {
|
||||
let cell_data = serde_json::to_string(&DateCellChangesetPB {
|
||||
date: Some(timestamp.to_string()),
|
||||
time: None,
|
||||
})
|
||||
.unwrap();
|
||||
let data = apply_cell_data_changeset(cell_data, None, field_rev).unwrap();
|
||||
CellRevision::new(data)
|
||||
}
|
||||
|
||||
pub fn insert_select_option_cell(option_id: String, field_rev: &FieldRevision) -> CellRevision {
|
||||
let cell_data = SelectOptionCellChangeset::from_insert(&option_id).to_str();
|
||||
let data = apply_cell_data_changeset(cell_data, None, field_rev).unwrap();
|
||||
CellRevision::new(data)
|
||||
}
|
||||
|
||||
/// If the cell data is not String type, it should impl this trait.
|
||||
/// Deserialize the String into cell specific data type.
|
||||
pub trait FromCellString {
|
||||
|
@ -552,9 +552,15 @@ impl GridRevisionEditor {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn create_board_card(&self) -> FlowyResult<RowPB> {
|
||||
pub async fn create_board_card(&self, group_id: &str) -> FlowyResult<RowPB> {
|
||||
let mut row_rev = self.create_row_rev().await?;
|
||||
let _ = self.group_service.write().await.create_board_card(&mut row_rev).await;
|
||||
let _ = self
|
||||
.group_service
|
||||
.write()
|
||||
.await
|
||||
.create_board_card(&mut row_rev, group_id)
|
||||
.await;
|
||||
|
||||
self.create_row_pb(row_rev, None).await
|
||||
}
|
||||
|
||||
@ -573,6 +579,7 @@ impl GridRevisionEditor {
|
||||
Ok(row_rev)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip_all, err)]
|
||||
async fn create_row_pb(&self, row_rev: RowRevision, start_row_id: Option<String>) -> FlowyResult<RowPB> {
|
||||
let row_pb = RowPB::from(&row_rev);
|
||||
let block_id = row_rev.block_id.clone();
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::entities::{CheckboxGroupConfigurationPB, RowPB};
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_grid_data_model::revision::RowRevision;
|
||||
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::services::field::{CheckboxCellData, CheckboxCellDataParser, CheckboxTypeOptionPB, CHECK, UNCHECK};
|
||||
use crate::services::group::{
|
||||
@ -19,15 +20,19 @@ impl Groupable for CheckboxGroupController {
|
||||
}
|
||||
|
||||
impl GroupActionHandler for CheckboxGroupController {
|
||||
fn field_id(&self) -> &str {
|
||||
&self.field_id
|
||||
}
|
||||
|
||||
fn get_groups(&self) -> Vec<Group> {
|
||||
self.groups()
|
||||
self.make_groups()
|
||||
}
|
||||
|
||||
fn group_row(&mut self, row_rev: &RowRevision) -> FlowyResult<()> {
|
||||
self.handle_row(row_rev)
|
||||
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
|
||||
self.handle_rows(row_revs, field_rev)
|
||||
}
|
||||
|
||||
fn create_card(&self, row_rev: &mut RowRevision) {
|
||||
fn create_card(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
use crate::entities::{GroupPB, RowPB};
|
||||
use crate::services::cell::{decode_any_cell_data, CellBytesParser};
|
||||
use bytes::Bytes;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::revision::{
|
||||
FieldRevision, GroupConfigurationRevision, RowRevision, TypeOptionDataDeserializer,
|
||||
};
|
||||
use futures::future::BoxFuture;
|
||||
use indexmap::IndexMap;
|
||||
use lib_infra::future::{BoxResultFuture, FutureResult};
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -34,15 +36,14 @@ pub trait Groupable {
|
||||
}
|
||||
|
||||
pub trait GroupActionHandler: Send + Sync {
|
||||
fn field_id(&self) -> &str;
|
||||
fn get_groups(&self) -> Vec<Group>;
|
||||
fn group_row(&mut self, row_rev: &RowRevision) -> FlowyResult<()>;
|
||||
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>]) -> FlowyResult<()> {
|
||||
for row_rev in row_revs {
|
||||
let _ = self.group_row(row_rev)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn create_card(&self, row_rev: &mut RowRevision);
|
||||
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()>;
|
||||
fn create_card(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
|
||||
}
|
||||
|
||||
pub trait GroupActionHandler2: Send + Sync {
|
||||
fn create_card(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
|
||||
}
|
||||
|
||||
const DEFAULT_GROUP_ID: &str = "default_group";
|
||||
@ -52,8 +53,8 @@ const DEFAULT_GROUP_ID: &str = "default_group";
|
||||
/// G: the group container generator
|
||||
/// P: the parser that impl [CellBytesParser] for the CellBytes
|
||||
pub struct GroupController<C, T, G, P> {
|
||||
pub field_rev: Arc<FieldRevision>,
|
||||
groups: IndexMap<String, Group>,
|
||||
pub field_id: String,
|
||||
pub groups_map: IndexMap<String, Group>,
|
||||
default_group: Group,
|
||||
pub type_option: Option<T>,
|
||||
pub configuration: Option<C>,
|
||||
@ -86,7 +87,7 @@ where
|
||||
G: GroupGenerator<ConfigurationType = C, TypeOptionType = T>,
|
||||
{
|
||||
pub fn new(
|
||||
field_rev: Arc<FieldRevision>,
|
||||
field_rev: &Arc<FieldRevision>,
|
||||
configuration: GroupConfigurationRevision,
|
||||
cell_content_provider: &dyn GroupCellContentProvider,
|
||||
) -> FlowyResult<Self> {
|
||||
@ -106,8 +107,8 @@ where
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
field_rev,
|
||||
groups: groups.into_iter().map(|group| (group.id.clone(), group)).collect(),
|
||||
field_id: field_rev.id.clone(),
|
||||
groups_map: groups.into_iter().map(|group| (group.id.clone(), group)).collect(),
|
||||
default_group,
|
||||
type_option,
|
||||
configuration,
|
||||
@ -116,9 +117,9 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub fn groups(&self) -> Vec<Group> {
|
||||
pub fn make_groups(&self) -> Vec<Group> {
|
||||
let default_group = self.default_group.clone();
|
||||
let mut groups: Vec<Group> = self.groups.values().cloned().collect();
|
||||
let mut groups: Vec<Group> = self.groups_map.values().cloned().collect();
|
||||
if !default_group.rows.is_empty() {
|
||||
groups.push(default_group);
|
||||
}
|
||||
@ -131,34 +132,38 @@ where
|
||||
P: CellBytesParser,
|
||||
Self: Groupable<CellDataType = P::Object>,
|
||||
{
|
||||
pub fn handle_row(&mut self, row: &RowRevision) -> FlowyResult<()> {
|
||||
pub fn handle_rows(&mut self, rows: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
|
||||
// The field_rev might be None if corresponding field_rev is deleted.
|
||||
if self.configuration.is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(cell_rev) = row.cells.get(&self.field_rev.id) {
|
||||
let mut records: Vec<GroupRecord> = vec![];
|
||||
let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), &self.field_rev);
|
||||
let cell_data = cell_bytes.parser::<P>()?;
|
||||
for group in self.groups.values() {
|
||||
if self.can_group(&group.content, &cell_data) {
|
||||
records.push(GroupRecord {
|
||||
row: row.into(),
|
||||
group_id: group.id.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if records.is_empty() {
|
||||
self.default_group.rows.push(row.into());
|
||||
} else {
|
||||
for record in records {
|
||||
if let Some(group) = self.groups.get_mut(&record.group_id) {
|
||||
group.rows.push(record.row);
|
||||
for row in rows {
|
||||
if let Some(cell_rev) = row.cells.get(&self.field_id) {
|
||||
let mut records: Vec<GroupRecord> = vec![];
|
||||
let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), &field_rev);
|
||||
let cell_data = cell_bytes.parser::<P>()?;
|
||||
for group in self.groups_map.values() {
|
||||
if self.can_group(&group.content, &cell_data) {
|
||||
records.push(GroupRecord {
|
||||
row: row.into(),
|
||||
group_id: group.id.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if records.is_empty() {
|
||||
self.default_group.rows.push(row.into());
|
||||
} else {
|
||||
for record in records {
|
||||
if let Some(group) = self.groups_map.get_mut(&record.group_id) {
|
||||
group.rows.push(record.row);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.default_group.rows.push(row.into());
|
||||
}
|
||||
} else {
|
||||
self.default_group.rows.push(row.into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -166,7 +171,7 @@ where
|
||||
|
||||
pub fn group_rows(&mut self, rows: &[Arc<RowRevision>]) -> FlowyResult<()> {
|
||||
for row in rows {
|
||||
let _ = self.handle_row(row)?;
|
||||
// let _ = self.handle_row(row)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
use crate::entities::{RowPB, SelectOptionGroupConfigurationPB};
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_grid_data_model::revision::RowRevision;
|
||||
use crate::services::cell::insert_select_option_cell;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
||||
use lib_infra::future::FutureResult;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::services::field::{
|
||||
MultiSelectTypeOptionPB, SelectOptionCellDataPB, SelectOptionCellDataParser, SingleSelectTypeOptionPB,
|
||||
@ -25,16 +28,27 @@ impl Groupable for SingleSelectGroupController {
|
||||
}
|
||||
|
||||
impl GroupActionHandler for SingleSelectGroupController {
|
||||
fn field_id(&self) -> &str {
|
||||
&self.field_id
|
||||
}
|
||||
|
||||
fn get_groups(&self) -> Vec<Group> {
|
||||
self.groups()
|
||||
self.make_groups()
|
||||
}
|
||||
|
||||
fn group_row(&mut self, row_rev: &RowRevision) -> FlowyResult<()> {
|
||||
self.handle_row(row_rev)
|
||||
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
|
||||
self.handle_rows(row_revs, field_rev)
|
||||
}
|
||||
|
||||
fn create_card(&self, row_rev: &mut RowRevision) {
|
||||
todo!()
|
||||
fn create_card(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
||||
let group: Option<&Group> = self.groups_map.get(group_id);
|
||||
match group {
|
||||
None => {}
|
||||
Some(group) => {
|
||||
let cell_rev = insert_select_option_cell(group.id.clone(), field_rev);
|
||||
row_rev.cells.insert(field_rev.id.clone(), cell_rev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,16 +93,27 @@ impl Groupable for MultiSelectGroupController {
|
||||
}
|
||||
|
||||
impl GroupActionHandler for MultiSelectGroupController {
|
||||
fn field_id(&self) -> &str {
|
||||
&self.field_id
|
||||
}
|
||||
|
||||
fn get_groups(&self) -> Vec<Group> {
|
||||
self.groups()
|
||||
self.make_groups()
|
||||
}
|
||||
|
||||
fn group_row(&mut self, row_rev: &RowRevision) -> FlowyResult<()> {
|
||||
self.handle_row(row_rev)
|
||||
fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
|
||||
self.handle_rows(row_revs, field_rev)
|
||||
}
|
||||
|
||||
fn create_card(&self, row_rev: &mut RowRevision) {
|
||||
todo!()
|
||||
fn create_card(&self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str) {
|
||||
let group: Option<&Group> = self.groups_map.get(group_id);
|
||||
match group {
|
||||
None => tracing::warn!("Can not find the group: {}", group_id),
|
||||
Some(group) => {
|
||||
let cell_rev = insert_select_option_cell(group.id.clone(), field_rev);
|
||||
row_rev.cells.insert(field_rev.id.clone(), cell_rev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ use bytes::Bytes;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_grid_data_model::revision::{gen_grid_group_id, FieldRevision, GroupConfigurationRevision, RowRevision};
|
||||
use flowy_sync::client_grid::GridRevisionPad;
|
||||
use futures::future::BoxFuture;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
@ -61,9 +62,24 @@ impl GridGroupService {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn create_board_card(&self, row_rev: &mut RowRevision) {
|
||||
#[tracing::instrument(level = "debug", skip(self, row_rev))]
|
||||
pub(crate) async fn create_board_card(&self, row_rev: &mut RowRevision, group_id: &str) {
|
||||
if let Some(group_action_handler) = self.group_action_handler.as_ref() {
|
||||
group_action_handler.write().await.create_card(row_rev);
|
||||
match self
|
||||
.grid_pad
|
||||
.read()
|
||||
.await
|
||||
.get_field_rev(group_action_handler.read().await.field_id())
|
||||
{
|
||||
None => tracing::warn!("Fail to create card because the field does not exist"),
|
||||
Some((_, field_rev)) => {
|
||||
tracing::trace!("Create card");
|
||||
group_action_handler
|
||||
.write()
|
||||
.await
|
||||
.create_card(row_rev, field_rev, group_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,15 +116,15 @@ impl GridGroupService {
|
||||
// let generator = GroupGenerator::<DateGroupConfigurationPB>::from_configuration(configuration);
|
||||
}
|
||||
FieldType::SingleSelect => {
|
||||
let controller = SingleSelectGroupController::new(field_rev.clone(), configuration, &self.grid_pad)?;
|
||||
let controller = SingleSelectGroupController::new(field_rev, configuration, &self.grid_pad)?;
|
||||
self.group_action_handler = Some(Arc::new(RwLock::new(controller)));
|
||||
}
|
||||
FieldType::MultiSelect => {
|
||||
let controller = MultiSelectGroupController::new(field_rev.clone(), configuration, &self.grid_pad)?;
|
||||
let controller = MultiSelectGroupController::new(field_rev, configuration, &self.grid_pad)?;
|
||||
self.group_action_handler = Some(Arc::new(RwLock::new(controller)));
|
||||
}
|
||||
FieldType::Checkbox => {
|
||||
let controller = CheckboxGroupController::new(field_rev.clone(), configuration, &self.grid_pad)?;
|
||||
let controller = CheckboxGroupController::new(field_rev, configuration, &self.grid_pad)?;
|
||||
self.group_action_handler = Some(Arc::new(RwLock::new(controller)));
|
||||
}
|
||||
FieldType::URL => {
|
||||
@ -119,7 +135,7 @@ impl GridGroupService {
|
||||
let mut groups = vec![];
|
||||
if let Some(group_action_handler) = self.group_action_handler.as_ref() {
|
||||
let mut write_guard = group_action_handler.write().await;
|
||||
let _ = write_guard.group_rows(&row_revs)?;
|
||||
let _ = write_guard.group_rows(&row_revs, field_rev)?;
|
||||
groups = write_guard.get_groups();
|
||||
drop(write_guard);
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
use crate::services::cell::apply_cell_data_changeset;
|
||||
use crate::services::cell::{
|
||||
apply_cell_data_changeset, insert_checkbox_cell, insert_date_cell, insert_number_cell, insert_select_option_cell,
|
||||
insert_text_cell, insert_url_cell,
|
||||
};
|
||||
use crate::services::field::{DateCellChangesetPB, SelectOptionCellChangeset};
|
||||
use flowy_grid_data_model::revision::{gen_row_id, CellRevision, FieldRevision, RowRevision, DEFAULT_ROW_HEIGHT};
|
||||
use indexmap::IndexMap;
|
||||
@ -34,47 +37,68 @@ impl<'a> RowRevisionBuilder<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_cell(&mut self, field_id: &str, data: String) {
|
||||
pub fn insert_text_cell(&mut self, field_id: &str, data: String) {
|
||||
match self.field_rev_map.get(&field_id.to_owned()) {
|
||||
None => {
|
||||
tracing::warn!("Can't find the field with id: {}", field_id);
|
||||
}
|
||||
None => tracing::warn!("Can't find the text field with id: {}", field_id),
|
||||
Some(field_rev) => {
|
||||
let data = apply_cell_data_changeset(data, None, field_rev).unwrap();
|
||||
let cell = CellRevision::new(data);
|
||||
self.payload.cell_by_field_id.insert(field_id.to_owned(), cell);
|
||||
self.payload
|
||||
.cell_by_field_id
|
||||
.insert(field_id.to_owned(), insert_text_cell(data, field_rev));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_url_cell(&mut self, field_id: &str, data: String) {
|
||||
match self.field_rev_map.get(&field_id.to_owned()) {
|
||||
None => tracing::warn!("Can't find the url field with id: {}", field_id),
|
||||
Some(field_rev) => {
|
||||
self.payload
|
||||
.cell_by_field_id
|
||||
.insert(field_id.to_owned(), insert_url_cell(data, field_rev));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_number_cell(&mut self, field_id: &str, num: i64) {
|
||||
match self.field_rev_map.get(&field_id.to_owned()) {
|
||||
None => tracing::warn!("Can't find the number field with id: {}", field_id),
|
||||
Some(field_rev) => {
|
||||
self.payload
|
||||
.cell_by_field_id
|
||||
.insert(field_id.to_owned(), insert_number_cell(num, field_rev));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_checkbox_cell(&mut self, field_id: &str, is_check: bool) {
|
||||
match self.field_rev_map.get(&field_id.to_owned()) {
|
||||
None => tracing::warn!("Can't find the checkbox field with id: {}", field_id),
|
||||
Some(field_rev) => {
|
||||
self.payload
|
||||
.cell_by_field_id
|
||||
.insert(field_id.to_owned(), insert_checkbox_cell(is_check, field_rev));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_date_cell(&mut self, field_id: &str, timestamp: i64) {
|
||||
match self.field_rev_map.get(&field_id.to_owned()) {
|
||||
None => {
|
||||
tracing::warn!("Invalid field_id: {}", field_id);
|
||||
}
|
||||
None => tracing::warn!("Can't find the date field with id: {}", field_id),
|
||||
Some(field_rev) => {
|
||||
let cell_data = serde_json::to_string(&DateCellChangesetPB {
|
||||
date: Some(timestamp.to_string()),
|
||||
time: None,
|
||||
})
|
||||
.unwrap();
|
||||
let data = apply_cell_data_changeset(cell_data, None, field_rev).unwrap();
|
||||
let cell = CellRevision::new(data);
|
||||
self.payload.cell_by_field_id.insert(field_id.to_owned(), cell);
|
||||
self.payload
|
||||
.cell_by_field_id
|
||||
.insert(field_id.to_owned(), insert_date_cell(timestamp, field_rev));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_select_option_cell(&mut self, field_id: &str, data: String) {
|
||||
match self.field_rev_map.get(&field_id.to_owned()) {
|
||||
None => {
|
||||
tracing::warn!("Invalid field_id: {}", field_id);
|
||||
}
|
||||
None => tracing::warn!("Can't find the select option field with id: {}", field_id),
|
||||
Some(field_rev) => {
|
||||
let cell_data = SelectOptionCellChangeset::from_insert(&data).to_str();
|
||||
let data = apply_cell_data_changeset(cell_data, None, field_rev).unwrap();
|
||||
let cell = CellRevision::new(data);
|
||||
self.payload.cell_by_field_id.insert(field_id.to_owned(), cell);
|
||||
self.payload
|
||||
.cell_by_field_id
|
||||
.insert(field_id.to_owned(), insert_select_option_cell(data, field_rev));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,20 +114,15 @@ pub fn make_default_board() -> BuildGridContext {
|
||||
row_builder.insert_select_option_cell(&multi_select_field_id, apple_option.id.clone());
|
||||
row_builder.insert_select_option_cell(&multi_select_field_id, banana_option.id.clone());
|
||||
// insert text
|
||||
row_builder.insert_cell(&text_field_id, format!("Card {}", i));
|
||||
row_builder.insert_text_cell(&text_field_id, format!("Card {}", i));
|
||||
// insert date
|
||||
row_builder.insert_date_cell(&date_field_id, timestamp);
|
||||
// number
|
||||
row_builder.insert_cell(&number_field_id, format!("{}", i));
|
||||
row_builder.insert_number_cell(&number_field_id, i);
|
||||
// checkbox
|
||||
let is_check = if i % 2 == 0 {
|
||||
CHECK.to_string()
|
||||
} else {
|
||||
UNCHECK.to_string()
|
||||
};
|
||||
row_builder.insert_cell(&checkbox_field_id, is_check);
|
||||
row_builder.insert_checkbox_cell(&checkbox_field_id, i % 2 == 0);
|
||||
// url
|
||||
row_builder.insert_cell(&url_field_id, "https://appflowy.io".to_string());
|
||||
row_builder.insert_url_cell(&url_field_id, "https://appflowy.io".to_string());
|
||||
|
||||
let row = row_builder.build();
|
||||
grid_builder.add_row(row);
|
||||
|
@ -26,14 +26,14 @@ impl<'a> GridRowTestBuilder<'a> {
|
||||
|
||||
pub fn insert_text_cell(&mut self, data: &str) -> String {
|
||||
let text_field = self.field_rev_with_type(&FieldType::RichText);
|
||||
self.inner_builder.insert_cell(&text_field.id, data.to_string());
|
||||
self.inner_builder.insert_text_cell(&text_field.id, data.to_string());
|
||||
|
||||
text_field.id.clone()
|
||||
}
|
||||
|
||||
pub fn insert_number_cell(&mut self, data: &str) -> String {
|
||||
let number_field = self.field_rev_with_type(&FieldType::Number);
|
||||
self.inner_builder.insert_cell(&number_field.id, data.to_string());
|
||||
self.inner_builder.insert_text_cell(&number_field.id, data.to_string());
|
||||
number_field.id.clone()
|
||||
}
|
||||
|
||||
@ -44,20 +44,21 @@ impl<'a> GridRowTestBuilder<'a> {
|
||||
})
|
||||
.unwrap();
|
||||
let date_field = self.field_rev_with_type(&FieldType::DateTime);
|
||||
self.inner_builder.insert_cell(&date_field.id, value);
|
||||
self.inner_builder.insert_text_cell(&date_field.id, value);
|
||||
date_field.id.clone()
|
||||
}
|
||||
|
||||
pub fn insert_checkbox_cell(&mut self, data: &str) -> String {
|
||||
let checkbox_field = self.field_rev_with_type(&FieldType::Checkbox);
|
||||
self.inner_builder.insert_cell(&checkbox_field.id, data.to_string());
|
||||
self.inner_builder
|
||||
.insert_text_cell(&checkbox_field.id, data.to_string());
|
||||
|
||||
checkbox_field.id.clone()
|
||||
}
|
||||
|
||||
pub fn insert_url_cell(&mut self, data: &str) -> String {
|
||||
let url_field = self.field_rev_with_type(&FieldType::URL);
|
||||
self.inner_builder.insert_cell(&url_field.id, data.to_string());
|
||||
self.inner_builder.insert_text_cell(&url_field.id, data.to_string());
|
||||
url_field.id.clone()
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ impl GridRevisionPad {
|
||||
.blocks
|
||||
.iter()
|
||||
.map(|block| {
|
||||
let mut duplicated_block = (&*block.clone()).clone();
|
||||
let mut duplicated_block = (&**block).clone();
|
||||
duplicated_block.block_id = gen_block_id();
|
||||
duplicated_block
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user