diff --git a/crates/controller/base/src/traits/block_ref.rs b/crates/controller/base/src/traits/block_ref.rs index be79a291..f5e71dae 100644 --- a/crates/controller/base/src/traits/block_ref.rs +++ b/crates/controller/base/src/traits/block_ref.rs @@ -1,7 +1,7 @@ use crate::{BlockCellId, SheetId}; pub trait BlockRefTrait { - fn get_all_keys(&self, ref_name: &str) -> Vec; + fn get_all_keys(&self, ref_name: &str) -> Vec<(String, SheetId, BlockCellId)>; fn get_all_fields(&self, ref_name: &str) -> Vec; fn resolve( &self, diff --git a/crates/controller/src/api/worksheet.rs b/crates/controller/src/api/worksheet.rs index f400c4d1..74b1ab53 100644 --- a/crates/controller/src/api/worksheet.rs +++ b/crates/controller/src/api/worksheet.rs @@ -24,7 +24,9 @@ use crate::{ }; use crate::{CellInfo, ColInfo, Comment, MergeCell, RowInfo, Style, Value}; use logisheets_base::errors::BasicError; -use logisheets_base::{BlockCellId, BlockId, CellId, ColId, DiyCellId, RowId, SheetId, StyleId}; +use logisheets_base::{ + BlockCellId, BlockId, CellId, ColId, DiyCellId, RowId, SheetId, StyleId, TextId, +}; use logisheets_parser::unparse; use super::workbook::CellPositionerDefault; @@ -959,19 +961,36 @@ impl<'a> Worksheet<'a> { .schemas .get(&(self.sheet_id, id)) .map(|s| { + let text_fetcher = |id: TextId| { + self.controller + .status + .text_id_manager + .get_string(&id) + .unwrap_or_default() + .clone() + }; + let key_value = |cell_id: BlockCellId| { + self.controller + .status + .container + .get_cell(self.sheet_id, &CellId::BlockCell(cell_id)) + .map(|cell| cell.value.to_string(&text_fetcher)) + .unwrap_or_default() + }; + let (keys, fields, random_entries) = match s { Schema::RowSchema(schema) => { let keys = schema - .keys - .iter() - .map(|(k, row_id)| { + .get_all_key_cell_ids(id) + .into_iter() + .map(|cell_id| { let idx = block_place - .rows + .cols .iter() - .position(|id| id == row_id) + .position(|col_id| col_id == &cell_id.col) .unwrap(); crate::controller::display::BlockSchemaKeyEntry { - key: k.clone(), + key: key_value(cell_id), idx, } }) @@ -996,16 +1015,16 @@ impl<'a> Worksheet<'a> { } Schema::ColSchema(schema) => { let keys = schema - .keys - .iter() - .map(|(k, col_id)| { + .get_all_key_cell_ids(id) + .into_iter() + .map(|cell_id| { let idx = block_place - .cols + .rows .iter() - .position(|id| id == col_id) + .position(|row_id| row_id == &cell_id.row) .unwrap(); crate::controller::display::BlockSchemaKeyEntry { - key: k.clone(), + key: key_value(cell_id), idx, } }) @@ -1032,7 +1051,7 @@ impl<'a> Worksheet<'a> { let random_entries = schema .key_field .iter() - .map(|(k, f, row_id, col_id, render_id)| { + .map(|(k, row_id, col_id, render_id)| { let row = block_place .rows .iter() @@ -1045,7 +1064,6 @@ impl<'a> Worksheet<'a> { .unwrap(); BlockSchemaRandomEntry { key: k.clone(), - field: f.clone(), row, col, render_id: render_id.clone(), @@ -1405,16 +1423,36 @@ impl<'a> Worksheet<'a> { .schemas .get(&(self.sheet_id, block_id)) .map(|s| { + let text_fetcher = |id: TextId| { + self.controller + .status + .text_id_manager + .get_string(&id) + .unwrap_or_default() + .clone() + }; + let key_value = |cell_id: BlockCellId| { + self.controller + .status + .container + .get_cell(self.sheet_id, &CellId::BlockCell(cell_id)) + .map(|cell| cell.value.to_string(&text_fetcher)) + .unwrap_or_default() + }; + let (keys, fields, random_entries) = match s { Schema::RowSchema(schema) => { let keys = schema - .keys - .iter() - .map(|(k, row_id)| { - let idx = - block_place.rows.iter().position(|id| id == row_id).unwrap(); + .get_all_key_cell_ids(block_id) + .into_iter() + .map(|cell_id| { + let idx = block_place + .cols + .iter() + .position(|id| id == &cell_id.col) + .unwrap(); crate::controller::display::BlockSchemaKeyEntry { - key: k.clone(), + key: key_value(cell_id), idx, } }) @@ -1436,13 +1474,16 @@ impl<'a> Worksheet<'a> { } Schema::ColSchema(schema) => { let keys = schema - .keys - .iter() - .map(|(k, col_id)| { - let idx = - block_place.cols.iter().position(|id| id == col_id).unwrap(); + .get_all_key_cell_ids(block_id) + .into_iter() + .map(|cell_id| { + let idx = block_place + .rows + .iter() + .position(|id| id == &cell_id.row) + .unwrap(); crate::controller::display::BlockSchemaKeyEntry { - key: k.clone(), + key: key_value(cell_id), idx, } }) @@ -1466,14 +1507,13 @@ impl<'a> Worksheet<'a> { let random_entries = schema .key_field .iter() - .map(|(k, f, row_id, col_id, render_id)| { + .map(|(k, row_id, col_id, render_id)| { let row = block_place.rows.iter().position(|id| id == row_id).unwrap(); let col = block_place.cols.iter().position(|id| id == col_id).unwrap(); BlockSchemaRandomEntry { key: k.clone(), - field: f.clone(), row, col, render_id: render_id.clone(), diff --git a/crates/controller/src/block_manager/schema_manager/executor.rs b/crates/controller/src/block_manager/schema_manager/executor.rs index 0b9d2760..49fd89ee 100644 --- a/crates/controller/src/block_manager/schema_manager/executor.rs +++ b/crates/controller/src/block_manager/schema_manager/executor.rs @@ -53,27 +53,22 @@ impl BlockSchemaExecutor { }; fields.push((field, (id, render_id))); } - let mut keys = Vec::new(); - - for (j, k) in p.keys.into_iter().enumerate() { - let idx = j + p.key_from; - let id = if p.row { - ctx.fetch_block_cell_id(&sheet_id, &block_id, idx, 0)?.row - } else { - ctx.fetch_block_cell_id(&sheet_id, &block_id, 0, idx)?.col - }; - keys.push((k, id)); - } let schema = if p.row { + let key = ctx + .fetch_block_cell_id(&sheet_id, &block_id, p.key_idx, 0)? + .row; Schema::RowSchema(RowSchema { fields, - keys, + key, name: p.ref_name.clone(), }) } else { + let key = ctx + .fetch_block_cell_id(&sheet_id, &block_id, 0, p.key_idx)? + .col; Schema::ColSchema(ColSchema { fields, - keys, + key, name: p.ref_name.clone(), }) }; @@ -108,13 +103,7 @@ impl BlockSchemaExecutor { let r = unit.row; let c = unit.col; let cell_id = ctx.fetch_block_cell_id(&sheet_id, &block_id, r, c)?; - key_field.push(( - unit.key, - unit.field, - cell_id.row, - cell_id.col, - unit.render_id, - )); + key_field.push((unit.key, cell_id.row, cell_id.col, unit.render_id)); } let schema = Schema::RandomSchema(RandomSchema { key_field, diff --git a/crates/controller/src/block_manager/schema_manager/manager.rs b/crates/controller/src/block_manager/schema_manager/manager.rs index e64e95aa..b7b12f8e 100644 --- a/crates/controller/src/block_manager/schema_manager/manager.rs +++ b/crates/controller/src/block_manager/schema_manager/manager.rs @@ -1,7 +1,7 @@ use imbl::HashMap; -use logisheets_base::{BlockCellId, BlockId, ColId, RowId, SheetId}; +use logisheets_base::{BlockCellId, BlockId, SheetId}; -use super::schema::{Field, Key, RenderId, Schema, SchemaTrait}; +use super::schema::{Field, RenderId, Schema, SchemaTrait}; #[derive(Debug, Clone, Default)] pub struct SchemaManager { @@ -17,42 +17,23 @@ impl SchemaManager { } } - #[inline] - pub fn resolve_by_ref_name( + // Make sure you know what you are doing. + // Given the key cell id, return the key-field cell id. + pub fn partially_resolve( &self, - name: &str, - key: &Key, - field: &Field, - ) -> Option<(SheetId, BlockCellId)> { - let (sheet_id, block_id) = self.refs.get(name)?; - let (row_id, col_id) = self.resolve_by_block_id(sheet_id, block_id, key, field)?; - Some(( - *sheet_id, - BlockCellId { - block_id: *block_id, - row: row_id, - col: col_id, - }, - )) - } - - #[inline] - pub fn resolve_by_block_id( - &self, - sheet_id: &SheetId, - block_id: &BlockId, - key: &Key, - field: &Field, - ) -> Option<(RowId, ColId)> { + ref_name: &str, + key: BlockCellId, + field: &String, + ) -> Option { + let (sheet_id, block_id) = self.refs.get(ref_name)?; let schema = self.schemas.get(&(*sheet_id, *block_id))?; - schema.resolve(key, field) + schema.partially_resolve(key, field) } - #[inline] - pub fn get_all_keys(&self, ref_name: &str) -> Option> { + pub fn get_all_key_cell_ids(&self, ref_name: &str) -> Option<(SheetId, Vec)> { let (sheet_id, block_id) = self.refs.get(ref_name)?; let schema = self.schemas.get(&(*sheet_id, *block_id))?; - Some(schema.get_all_keys()) + Some((*sheet_id, schema.get_all_key_cell_ids(*block_id))) } #[inline] diff --git a/crates/controller/src/block_manager/schema_manager/schema.rs b/crates/controller/src/block_manager/schema_manager/schema.rs index f00cf59b..b265b248 100644 --- a/crates/controller/src/block_manager/schema_manager/schema.rs +++ b/crates/controller/src/block_manager/schema_manager/schema.rs @@ -1,4 +1,4 @@ -use logisheets_base::{ColId, RowId}; +use logisheets_base::{BlockCellId, BlockId, ColId, RowId}; pub type RowSchema = FormSchema; pub type ColSchema = FormSchema; @@ -7,8 +7,8 @@ pub type RenderId = String; #[derive(Debug, Clone)] pub struct FormSchema { pub fields: Vec<(Field, (F, RenderId))>, - pub keys: Vec<(Key, K)>, pub name: String, + pub key: K, } pub type Field = String; @@ -16,7 +16,7 @@ pub type Key = String; #[derive(Debug, Clone)] pub struct RandomSchema { - pub key_field: Vec<(Key, Field, RowId, ColId, RenderId)>, + pub key_field: Vec<(Key, RowId, ColId, RenderId)>, pub name: String, } @@ -28,14 +28,6 @@ pub enum Schema { } impl SchemaTrait for Schema { - fn resolve(&self, key: &Key, field: &Field) -> Option<(RowId, ColId)> { - match self { - Schema::RowSchema(schema) => schema.resolve(key, field), - Schema::ColSchema(schema) => schema.resolve(key, field), - Schema::RandomSchema(schema) => schema.resolve(key, field), - } - } - fn get_render_id(&self, row: RowId, col: ColId) -> Option { match self { Schema::RowSchema(schema) => schema.get_render_id(row, col), @@ -52,14 +44,6 @@ impl SchemaTrait for Schema { } } - fn get_all_keys(&self) -> Vec { - match self { - Schema::RowSchema(schema) => schema.get_all_keys(), - Schema::ColSchema(schema) => schema.get_all_keys(), - Schema::RandomSchema(schema) => schema.get_all_keys(), - } - } - fn get_all_fields(&self) -> Vec { match self { Schema::RowSchema(schema) => schema.get_all_fields(), @@ -67,31 +51,33 @@ impl SchemaTrait for Schema { Schema::RandomSchema(schema) => schema.get_all_fields(), } } + + fn get_all_key_cell_ids(&self, block_id: BlockId) -> Vec { + match self { + Schema::RowSchema(form_schema) => form_schema.get_all_key_cell_ids(block_id), + Schema::ColSchema(form_schema) => form_schema.get_all_key_cell_ids(block_id), + Schema::RandomSchema(random_schema) => random_schema.get_all_key_cell_ids(block_id), + } + } + + fn partially_resolve(&self, key: BlockCellId, field: &String) -> Option { + match self { + Schema::RowSchema(form_schema) => form_schema.partially_resolve(key, field), + Schema::ColSchema(form_schema) => form_schema.partially_resolve(key, field), + Schema::RandomSchema(random_schema) => random_schema.partially_resolve(key, field), + } + } } pub trait SchemaTrait { - fn resolve(&self, key: &Key, field: &Field) -> Option<(RowId, ColId)>; fn get_render_id(&self, row: RowId, col: ColId) -> Option; fn get_ref_name(&self) -> String; - fn get_all_keys(&self) -> Vec; fn get_all_fields(&self) -> Vec; + fn get_all_key_cell_ids(&self, block_id: BlockId) -> Vec; + fn partially_resolve(&self, key: BlockCellId, field: &String) -> Option; } impl SchemaTrait for RowSchema { - fn resolve(&self, key: &Key, field: &Field) -> Option<(RowId, ColId)> { - let k = self - .keys - .iter() - .find(|(k, _)| k == key) - .map(|(_, id)| *id)?; - let f = self - .fields - .iter() - .find(|(f, _)| f == field) - .map(|(_, id)| id.0)?; - Some((k, f)) - } - fn get_render_id(&self, _row: RowId, col: ColId) -> Option { self.fields .iter() @@ -103,30 +89,38 @@ impl SchemaTrait for RowSchema { self.name.clone() } - fn get_all_keys(&self) -> Vec { - self.keys.iter().map(|(k, _)| k.clone()).collect() - } - fn get_all_fields(&self) -> Vec { self.fields.iter().map(|(f, _)| f.clone()).collect() } -} -impl SchemaTrait for ColSchema { - fn resolve(&self, key: &Key, field: &Field) -> Option<(RowId, ColId)> { - let k = self - .keys + fn get_all_key_cell_ids(&self, block_id: BlockId) -> Vec { + let key = self.key; + self.fields .iter() - .find(|(k, _)| k == key) - .map(|(_, id)| *id)?; - let f = self + .map(|(_, (f, _))| BlockCellId { + block_id, + row: key, + col: *f, + }) + .collect() + } + + fn partially_resolve(&self, key: BlockCellId, field: &String) -> Option { + let row = key.row; + let col = self .fields .iter() - .find(|(f, _)| f == field) - .map(|(_, id)| id.0)?; - Some((f, k)) + .find(|(f, (_, _))| f == field) + .map(|(_, (f, _))| *f); + col.map(|col| BlockCellId { + row, + col, + block_id: key.block_id, + }) } +} +impl SchemaTrait for ColSchema { fn get_render_id(&self, row: RowId, _col: ColId) -> Option { self.fields .iter() @@ -138,45 +132,65 @@ impl SchemaTrait for ColSchema { self.name.clone() } - fn get_all_keys(&self) -> Vec { - self.keys.iter().map(|(k, _)| k.clone()).collect() - } - fn get_all_fields(&self) -> Vec { self.fields.iter().map(|(f, _)| f.clone()).collect() } -} -impl SchemaTrait for RandomSchema { - fn resolve(&self, key: &Key, field: &Field) -> Option<(RowId, ColId)> { - self.key_field + fn get_all_key_cell_ids(&self, block_id: BlockId) -> Vec { + let key = self.key; + self.fields + .iter() + .map(|(_, (f, _))| BlockCellId { + block_id, + row: *f, + col: key, + }) + .collect() + } + + fn partially_resolve(&self, key: BlockCellId, field: &String) -> Option { + self.fields .iter() - .find(|(k, f, _, _, _)| k == key && f == field) - .map(|(_, _, r, c, _)| (*r, *c)) + .find(|(f, (_, _))| f == field) + .map(|(_, (f, _))| BlockCellId { + block_id: key.block_id, + row: *f, + col: key.col, + }) } +} +impl SchemaTrait for RandomSchema { fn get_render_id(&self, row: RowId, col: ColId) -> Option { self.key_field .iter() - .find(|(_, _, r, c, _)| r == &row && c == &col) - .map(|(_, _, _, _, id)| id.clone()) + .find(|(_, r, c, _)| r == &row && c == &col) + .map(|(_, _, _, id)| id.clone()) } fn get_ref_name(&self) -> String { self.name.clone() } - fn get_all_keys(&self) -> Vec { + fn get_all_fields(&self) -> Vec { self.key_field .iter() - .map(|(k, _, _, _, _)| k.clone()) + .map(|(f, _, _, _)| f.clone()) .collect() } - fn get_all_fields(&self) -> Vec { + fn get_all_key_cell_ids(&self, block_id: BlockId) -> Vec { self.key_field .iter() - .map(|(_, f, _, _, _)| f.clone()) + .map(|(_, r, c, _)| BlockCellId { + block_id, + row: *r, + col: *c, + }) .collect() } + + fn partially_resolve(&self, key: BlockCellId, _field: &String) -> Option { + Some(key) + } } diff --git a/crates/controller/src/calc_engine/calculator/funcs/blocks/blockrefs.rs b/crates/controller/src/calc_engine/calculator/funcs/blocks/blockrefs.rs index c249d629..e6b53a8b 100644 --- a/crates/controller/src/calc_engine/calculator/funcs/blocks/blockrefs.rs +++ b/crates/controller/src/calc_engine/calculator/funcs/blocks/blockrefs.rs @@ -29,7 +29,7 @@ where let keys = fetcher .get_all_keys(&ref_name) .into_iter() - .map(|t| Value::Text(t)); + .map(|(t, _, _)| Value::Text(t)); let key_values = keys .into_iter() .filter(|key| match_condition(&key_condigtion, key)) diff --git a/crates/controller/src/calc_engine/calculator/funcs/utils.rs b/crates/controller/src/calc_engine/calculator/funcs/utils.rs index 262c811b..421a3b74 100644 --- a/crates/controller/src/calc_engine/calculator/funcs/utils.rs +++ b/crates/controller/src/calc_engine/calculator/funcs/utils.rs @@ -152,7 +152,7 @@ pub mod tests_utils { use logisheets_base::block_ref::BlockRefTrait; use logisheets_base::get_curr_addr::GetCurrAddrTrait; use logisheets_base::set_curr_cell::SetCurrCellTrait; - use logisheets_base::SheetId; + use logisheets_base::{BlockCellId, SheetId}; use logisheets_parser::ast; use crate::calc_engine::calculator::calc_vertex::{CalcValue, CalcVertex}; @@ -189,7 +189,7 @@ pub mod tests_utils { } impl BlockRefTrait for TestFetcher { - fn get_all_keys(&self, _ref_name: &str) -> Vec { + fn get_all_keys(&self, _ref_name: &str) -> Vec<(String, SheetId, BlockCellId)> { unreachable!() } diff --git a/crates/controller/src/connectors/calc_connector.rs b/crates/controller/src/connectors/calc_connector.rs index 6f812653..5b48c0ff 100644 --- a/crates/controller/src/connectors/calc_connector.rs +++ b/crates/controller/src/connectors/calc_connector.rs @@ -548,10 +548,20 @@ where } impl<'a> BlockRefTrait for CalcConnector<'a> { - fn get_all_keys(&self, ref_name: &str) -> Vec { - self.block_schema_manager - .get_all_keys(ref_name) - .unwrap_or_default() + fn get_all_keys(&self, ref_name: &str) -> Vec<(String, SheetId, BlockCellId)> { + let (sheet_id, block_ids) = self + .block_schema_manager + .get_all_key_cell_ids(ref_name) + .unwrap_or_default(); + let text_fetcher = |id: TextId| self.text_id_manager.get_string(&id).unwrap().clone(); + block_ids + .iter() + .flat_map(|id| { + let cell = self.container.get_cell(sheet_id, &CellId::BlockCell(*id))?; + let v = cell.value.to_string(&text_fetcher); + Some((v, sheet_id, *id)) + }) + .collect() } fn get_all_fields(&self, ref_name: &str) -> Vec { @@ -566,7 +576,14 @@ impl<'a> BlockRefTrait for CalcConnector<'a> { key: &String, field: &String, ) -> Option<(SheetId, BlockCellId)> { - self.block_schema_manager - .resolve_by_ref_name(ref_name, key, field) + let keys = self.get_all_keys(ref_name); + keys.into_iter() + .find(|(k, _, _)| k == key) + .and_then(|(_, sheet_id, id)| { + let cell_id = self + .block_schema_manager + .partially_resolve(ref_name, id, field)?; + Some((sheet_id, cell_id)) + }) } } diff --git a/crates/controller/src/controller/display.rs b/crates/controller/src/controller/display.rs index c235918b..36972f9e 100644 --- a/crates/controller/src/controller/display.rs +++ b/crates/controller/src/controller/display.rs @@ -139,7 +139,6 @@ pub struct BlockSchemaFieldEntry { #[ts(file_name = "block_schema_random_entry.ts", rename_all = "camelCase")] pub struct BlockSchemaRandomEntry { pub key: String, - pub field: String, pub row: usize, pub col: usize, pub render_id: RenderId, diff --git a/crates/controller/src/edit_action/mod.rs b/crates/controller/src/edit_action/mod.rs index 9d2e22fe..97f1c907 100644 --- a/crates/controller/src/edit_action/mod.rs +++ b/crates/controller/src/edit_action/mod.rs @@ -449,7 +449,7 @@ pub struct BindFormSchema { // Form schema fields start from this index. pub field_from: usize, // Form schema keys start from this index. - pub key_from: usize, + pub key_idx: usize, pub fields: Vec, // Generated by frontend app. // It is used to customize the fields' render behaviors. @@ -472,7 +472,6 @@ pub struct BindRandomSchema { #[ts(file_name = "random_schema_unit.ts", builder, rename_all = "camelCase")] pub struct RandomSchemaUnit { pub key: String, - pub field: String, pub render_id: String, pub row: usize, pub col: usize, diff --git a/src/components/block-composer/config_panel.tsx b/src/components/block-composer/config_panel.tsx index c625eb12..a3fc9e22 100644 --- a/src/components/block-composer/config_panel.tsx +++ b/src/components/block-composer/config_panel.tsx @@ -483,6 +483,26 @@ export const FieldConfigPanel = ({ } /> + + onUpdate({ + ...field, + primary: + e.target.checked, + }) + } + /> + } + label={ + + Primary + + } + /> diff --git a/src/components/block-composer/field_list.tsx b/src/components/block-composer/field_list.tsx index 3e7b3712..4ff62b24 100644 --- a/src/components/block-composer/field_list.tsx +++ b/src/components/block-composer/field_list.tsx @@ -2,6 +2,7 @@ import {useState, useEffect} from 'react' import { Box, Button, + Chip, List, ListItem, ListItemButton, @@ -25,6 +26,7 @@ interface FieldListProps { onFieldSelect: (id: string) => void onFieldsReorder: (fields: FieldSetting[]) => void onAddField: () => void + embedded?: boolean } export const FieldList = ({ @@ -33,6 +35,7 @@ export const FieldList = ({ onFieldSelect, onFieldsReorder, onAddField, + embedded = false, }: FieldListProps) => { const [isDragEnabled, setIsDragEnabled] = useState(false) @@ -59,14 +62,23 @@ export const FieldList = ({ return ( {/* Header with Add Button */} + + {field.name} + + {field.primary && ( + + )} + + } secondary={ field.type .charAt(0) @@ -210,7 +265,46 @@ export const FieldList = ({ + + {field.name} + + {field.primary && ( + + )} + + } secondary={ field.type.charAt(0).toUpperCase() + field.type.slice(1) diff --git a/src/components/block-composer/index.tsx b/src/components/block-composer/index.tsx index 1f9af6cc..981db104 100644 --- a/src/components/block-composer/index.tsx +++ b/src/components/block-composer/index.tsx @@ -1,7 +1,12 @@ import {useState} from 'react' -import {Box, Typography, Dialog, DialogContent} from '@mui/material' +import {Box, Typography, Dialog, DialogContent, TextField} from '@mui/material' import {getSelectedCellRange} from '../canvas' -import {SelectedData, getFirstCell} from 'logisheets-web' +import { + BindFormSchemaBuilder, + SelectedData, + UpsertFieldRenderInfoBuilder, + getFirstCell, +} from 'logisheets-web' import {useToast} from '@/ui/notification/useToast' import {TYPES} from '@/core/ioc/types' import {useInjection} from '@/core/ioc/provider' @@ -52,6 +57,7 @@ export const BlockComposerComponent = (props: BlockComposerProps) => { if (!range) { return null } + const [refName, setRefName] = useState('') const selectedField = fields.find((f) => f.id === selectedFieldId) @@ -61,13 +67,24 @@ export const BlockComposerComponent = (props: BlockComposerProps) => { name: 'New Field', type: 'string', required: false, + primary: false, } setFields([...fields, newField]) setSelectedFieldId(newField.id) } const handleUpdateField = (field: FieldSetting) => { - setFields(fields.map((f) => (f.id === field.id ? field : f))) + setFields( + fields.map((f) => { + if (f.id === field.id) { + return field + } + if (field.primary) { + return {...f, primary: false} + } + return f + }) + ) } const handleDeleteField = (id: string) => { @@ -122,7 +139,7 @@ export const BlockComposerComponent = (props: BlockComposerProps) => { blockId, f ) - return [r.id, f] + return [r.id, r] }) const {y: row, x: col} = getFirstCell(selectedData) const len = fs.length @@ -142,77 +159,47 @@ export const BlockComposerComponent = (props: BlockComposerProps) => { } payloads.push(createBlockPayload) + const bindFormSchemaPayload: Payload = { + type: 'bindFormSchema', + value: new BindFormSchemaBuilder() + .refName(refName) + .sheetIdx(currentSheetIdx) + .blockId(blockId) + .fieldFrom(0) + .row(true) + .fields(fs.map((f) => f[1].name)) + .renderIds(fs.map((f) => f[0])) + .build(), + } + payloads.push(bindFormSchemaPayload) + fs.forEach(([fieldId, field], i) => { let diyRender = false + let formatter = '' switch (field.type.type) { case 'image': case 'enum': case 'multiSelect': - diyRender = true - break - case 'datetime': { - const formatter = field.type.formatter - if (formatter === '') { - break - } - const p = new SetBlockLineNumFmtBuilder() - .sheetIdx(currentSheetIdx) - .blockId(blockId) - .from(i) - .to(i) - .isRow(false) - .numFmt(formatter) - .build() - const payload: Payload = { - type: 'setBlockLineNumFmt', - value: p, - } - payloads.push(payload) - break - } case 'boolean': diyRender = true break case 'string': break - case 'number': { - const formatter = field.type.formatter - if (formatter === '') { - break - } - const p = new SetBlockLineNumFmtBuilder() - .sheetIdx(currentSheetIdx) - .blockId(blockId) - .from(i) - .to(i) - .isRow(false) - .numFmt(formatter) - .build() - const payload: Payload = { - type: 'setBlockLineNumFmt', - value: p, - } - payloads.push(payload) + case 'datetime': + case 'number': + formatter = field.type.formatter break - } default: break } - - const p = new SetBlockLineNameFieldBuilder() - .sheetIdx(currentSheetIdx) - .blockId(blockId) - .line(i) - .isRow(false) - .fieldId(fieldId) - .name(field.name) + const p = new UpsertFieldRenderInfoBuilder() + .renderId(fieldId) .diyRender(diyRender) + .styleUpdate({ + setNumFmt: formatter, + }) .build() - const payload: Payload = { - type: 'setBlockLineNameField', - value: p, - } - payloads.push(payload) + payloads.push({type: 'upsertFieldRenderInfo', value: p}) }) const result = await DATA_SERVICE.handleTransaction( @@ -236,14 +223,50 @@ export const BlockComposerComponent = (props: BlockComposerProps) => { PaperProps={{sx: {height: '80vh'}}} > - {/* Left Panel - Field List */} - + + {/* Left Panel - Block Ref Name */} + + + Block Ref Name + + setRefName(e.target.value)} + size="small" + fullWidth + placeholder="e.g. customers" + /> + + + {/* Left Panel - Field List */} + + {/* Right Panel - Field Editor */}