Skip to content

Commit 7a260a7

Browse files
author
Nate Rush
authored
Merge pull request #1289 from mito-ds/set-default-cell-editor
mitosheet: set default_apply_formula_to_column
2 parents f59dc37 + f0dda17 commit 7a260a7

15 files changed

+66
-16
lines changed

mitosheet/mitosheet/mito_backend.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from mitosheet.steps_manager import StepsManager
3030
from mitosheet.telemetry.telemetry_utils import (log, log_event_processed,
3131
telemetry_turned_on)
32-
from mitosheet.types import CodeOptions, ColumnDefinintion, ColumnDefinitions, ConditionalFormat, MitoTheme, ParamMetadata
32+
from mitosheet.types import CodeOptions, ColumnDefinintion, ColumnDefinitions, ConditionalFormat, DefaultEditingMode, MitoTheme, ParamMetadata
3333
from mitosheet.updates.replay_analysis import REPLAY_ANALYSIS_UPDATE
3434
from mitosheet.user.create import try_create_user_json_file
3535
from mitosheet.user.db import USER_JSON_PATH, get_user_field
@@ -58,6 +58,7 @@ def __init__(
5858
user_defined_editors: Optional[List[Callable]]=None,
5959
code_options: Optional[CodeOptions]=None,
6060
column_definitions: Optional[List[ColumnDefinitions]]=None,
61+
default_editing_mode: Optional[DefaultEditingMode]=None,
6162
theme: Optional[MitoTheme]=None,
6263
):
6364
"""
@@ -94,6 +95,8 @@ def __init__(
9495
if not os.path.exists(import_folder):
9596
raise ValueError(f"Import folder {import_folder} does not exist. Please change the file path or create the folder.")
9697

98+
default_apply_formula_to_column = False if default_editing_mode == 'cell' else True
99+
97100
# Set up the state container to hold private widget state
98101
self.steps_manager = StepsManager(
99102
args,
@@ -106,7 +109,8 @@ def __init__(
106109
user_defined_editors=user_defined_editors,
107110
code_options=code_options,
108111
column_definitions=column_definitions,
109-
theme=theme
112+
theme=theme,
113+
default_apply_formula_to_column=default_apply_formula_to_column
110114
)
111115

112116
# And the api

mitosheet/mitosheet/steps_manager.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ def __init__(
188188
user_defined_editors: Optional[List[Callable]]=None,
189189
code_options: Optional[CodeOptions]=None,
190190
column_definitions: Optional[List[ColumnDefinitions]]=None,
191+
default_apply_formula_to_column: Optional[bool]=None,
191192
theme: Optional[MitoTheme]=None,
192193
):
193194
"""
@@ -255,6 +256,9 @@ def __init__(
255256

256257
if not is_running_test() and not is_pro() and column_definitions is not None:
257258
raise ValueError("column definitions are only supported in the enterprise version of Mito. See Mito plans https://www.trymito.io/plans")
259+
260+
if not is_running_test() and not is_pro() and default_apply_formula_to_column is not None:
261+
raise ValueError(f'Setting default_editing_mode is only supported in the enterprise version of Mito. See Mito plans https://www.trymito.io/plans')
258262

259263
# The version of the public interface used by this analysis
260264
self.public_interface_version = 3
@@ -348,6 +352,7 @@ def __init__(
348352
self.code_options: CodeOptions = get_default_code_options(self.analysis_name) if code_options is None else code_options
349353

350354
self.theme = theme
355+
self.default_apply_formula_to_column = default_apply_formula_to_column if default_apply_formula_to_column is not None else True
351356

352357
@property
353358
def curr_step(self) -> Step:
@@ -421,7 +426,8 @@ def analysis_data_json(self):
421426
'path': self.import_folder,
422427
'pathParts': get_path_parts(self.import_folder)
423428
} if self.import_folder is not None else None,
424-
"theme": self.theme
429+
"theme": self.theme,
430+
"defaultApplyFormulaToColumn": self.default_apply_formula_to_column
425431
},
426432
cls=NpEncoder
427433
)

mitosheet/mitosheet/streamlit/v1/apps/column_definitions_app.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
df = pd.DataFrame({
99
'A': [1, 2, 3, 4, 5, 6, 7, 8, 9],
1010
'B': [1, 2, 3, 4, 5, 6, 7, 8, 9]
11-
})
11+
}, index=['a', 'b', 'c', 'd', 'e', 'b', 'g', 'h', 'i'])
1212
new_dfs, code = spreadsheet(
1313
df,
14+
height='1200px',
15+
default_editing_mode='cell',
1416
column_definitions=[
1517
[
1618
{

mitosheet/mitosheet/streamlit/v1/spreadsheet.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
from mitosheet.mito_backend import MitoBackend
1515
from mitosheet.selection_utils import get_selected_element
16-
from mitosheet.types import CodeOptions, ColumnDefinitions, ConditionalFormat, ParamMetadata, ParamType
16+
from mitosheet.types import CodeOptions, ColumnDefinitions, ConditionalFormat, DefaultEditingMode, ParamMetadata, ParamType
17+
from mitosheet.user.utils import is_pro
1718
from mitosheet.utils import get_new_id
1819

1920
CURRENT_MITO_ANALYSIS_VERSION = 1
@@ -270,6 +271,7 @@ def _get_mito_backend(
270271
_sheet_functions: Optional[List[Callable]]=None,
271272
_code_options: Optional[CodeOptions]=None,
272273
_column_definitions: Optional[List[ColumnDefinitions]]=None,
274+
_default_editing_mode: Optional[DefaultEditingMode]=None,
273275
import_folder: Optional[str]=None,
274276
df_names: Optional[List[str]]=None,
275277
session_id: Optional[str]=None,
@@ -282,6 +284,7 @@ def _get_mito_backend(
282284
user_defined_importers=_importers, user_defined_functions=_sheet_functions, user_defined_editors=_editors,
283285
code_options=_code_options,
284286
column_definitions = _column_definitions,
287+
default_editing_mode=_default_editing_mode,
285288
)
286289

287290
# Make a send function that stores the responses in a list
@@ -323,6 +326,7 @@ def spreadsheet( # type: ignore
323326
import_folder: Optional[str]=None,
324327
code_options: Optional[CodeOptions]=None,
325328
column_definitions: Optional[List[ColumnDefinitions]]=None,
329+
default_editing_mode: Optional[DefaultEditingMode]=None,
326330
return_type: str='default',
327331
height: Optional[str]=None,
328332
key=None
@@ -370,6 +374,7 @@ def spreadsheet( # type: ignore
370374
_editors=editors,
371375
_code_options=code_options,
372376
_column_definitions=column_definitions,
377+
_default_editing_mode=default_editing_mode,
373378
import_folder=import_folder,
374379
session_id=session_id,
375380
df_names=df_names,

mitosheet/mitosheet/tests/step_performers/test_export_to_file.py

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import glob
1111
import os
12+
import openpyxl
1213
import pandas as pd
1314
import pytest
1415
from mitosheet.tests.test_utils import check_dataframes_equal, create_mito_wrapper, get_dataframe_generation_code

mitosheet/mitosheet/tests/streamlit/test_streamlit.py

+10
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,14 @@ def test_spreadsheet_with_column_definitions_only_one_color():
164164
code_options={'as_function': True, 'call_function': False, 'function_name': 'test', 'function_params': {}},
165165
return_type='function'
166166
)
167+
assert callable(f)
168+
169+
@requires_streamlit
170+
def test_spreadsheet_with_default_apply_formula_to_column():
171+
f = spreadsheet(
172+
df1,
173+
default_editing_mode='cell',
174+
code_options={'as_function': True, 'call_function': False, 'function_name': 'test', 'function_params': {}},
175+
return_type='function'
176+
)
167177
assert callable(f)

mitosheet/mitosheet/tests/test_mito_backend.py

+10
Original file line numberDiff line numberDiff line change
@@ -191,4 +191,14 @@ def test_create_backend_with_code_options_works():
191191
mito_backend = MitoBackend(code_options=code_options)
192192
assert mito_backend.steps_manager.code_options == code_options
193193

194+
def test_create_backend_default_apply_formula_to_column():
195+
mito_backend = MitoBackend(default_editing_mode='cell')
196+
assert mito_backend.steps_manager.default_apply_formula_to_column == False
197+
198+
mito_backend = MitoBackend(default_editing_mode='column')
199+
assert mito_backend.steps_manager.default_apply_formula_to_column == True
200+
201+
mito_backend = MitoBackend()
202+
assert mito_backend.steps_manager.default_apply_formula_to_column == True
203+
194204

mitosheet/mitosheet/types.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,10 @@ class ColumnDefinintion(TypedDict):
383383
columns: List[ColumnHeader]
384384
conditional_formats: List[ColumnDefinitionConditionalFormats]
385385

386-
# TODO: This is a confusing name. Think of a better one.
387386
ColumnDefinitions = List[ColumnDefinintion]
388387

388+
DefaultEditingMode = Literal['cell', 'column']
389+
389390
UserDefinedFunctionParamType = Literal['any', 'str', 'int', 'float', 'bool', 'DataFrame', 'ColumnHeader']
390391

391392
class MitoTheme(TypedDict):
@@ -455,6 +456,7 @@ class ExecuteThroughTranspileNewDataframeParams(TypedDict):
455456
ColumnDefinitionConditionalFormats = Any # type: ignore
456457
ColumnDefinintion = Any # type: ignore
457458
ColumnDefinitions = Any # type: ignore
459+
DefaultEditingMode = Any # type: ignore
458460

459461
ParamName = str # type: ignore
460462
ParamType = str # type: ignore

mitosheet/src/mito/components/endo/EndoGrid.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ function EndoGrid(props: {
553553
return;
554554
}
555555

556-
const {startingColumnFormula, arrowKeysScrollInFormula, editingMode} = getStartingFormula(sheetData, props.editorState, rowIndex, columnIndex);
556+
const {startingColumnFormula, arrowKeysScrollInFormula, editingMode} = getStartingFormula(sheetData, props.editorState, rowIndex, columnIndex, props.analysisData.defaultApplyFormulaToColumn);
557557

558558
setEditorState({
559559
rowIndex: rowIndex,
@@ -621,7 +621,7 @@ function EndoGrid(props: {
621621
setGridState((gridState) => {
622622
const lastSelection = gridState.selections[gridState.selections.length - 1]
623623

624-
const {startingColumnFormula, arrowKeysScrollInFormula, editingMode} = getStartingFormula(sheetData, undefined, lastSelection.startingRowIndex, lastSelection.startingColumnIndex, e);
624+
const {startingColumnFormula, arrowKeysScrollInFormula, editingMode} = getStartingFormula(sheetData, undefined, lastSelection.startingRowIndex, lastSelection.startingColumnIndex, props.analysisData.defaultApplyFormulaToColumn, e);
625625

626626
setEditorState({
627627
rowIndex: lastSelection.startingRowIndex,

mitosheet/src/mito/components/endo/FormulaBar.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Col from '../layout/Col';
1212
import Row from '../layout/Row';
1313
import { TaskpaneType } from '../taskpanes/taskpanes';
1414
import CellEditor from './celleditor/CellEditor';
15-
import { getFullFormula } from './celleditor/cellEditorUtils';
15+
import { getDefaultEditingMode, getFullFormula } from './celleditor/cellEditorUtils';
1616
import { calculateCurrentSheetView } from './sheetViewUtils';
1717
import { getCellDataFromCellIndexes } from './utils';
1818

@@ -100,7 +100,7 @@ const FormulaBar = (props: {
100100
formula: formulaBarValue,
101101
arrowKeysScrollInFormula: true,
102102
editorLocation: 'formula bar',
103-
editingMode: columnFormulaLocation || 'entire_column',
103+
editingMode: columnFormulaLocation || getDefaultEditingMode(props.analysisData.defaultApplyFormulaToColumn),
104104
sheetIndex: props.sheetIndex,
105105
})
106106
// If we're opening the formula cell editor while the cell editor is currently open,

mitosheet/src/mito/components/endo/celleditor/CellEditor.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ const CellEditor = (props: {
130130
return prevEditingState;
131131
}
132132

133-
const startingColumnFormula = getStartingFormula(sheetData, prevEditingState, props.editorState.rowIndex, props.editorState.columnIndex).startingColumnFormula
133+
const startingColumnFormula = getStartingFormula(sheetData, prevEditingState, props.editorState.rowIndex, props.editorState.columnIndex, props.analysisData.defaultApplyFormulaToColumn).startingColumnFormula
134134
return {
135135
...prevEditingState,
136136
formula: startingColumnFormula

mitosheet/src/mito/components/endo/celleditor/cellEditorUtils.tsx

+12-3
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ export const getCellEditorInputCurrentSelection = (containerDiv: HTMLDivElement
8686
}
8787
}
8888

89+
/**
90+
* Gets the editing mode that the cell editor should start in, based on the default.
91+
*/
92+
export const getDefaultEditingMode = (defaultApplyFormulaToColumn: boolean): 'entire_column' | 'specific_index_labels' => {
93+
return defaultApplyFormulaToColumn ? 'entire_column' : 'specific_index_labels';
94+
}
95+
8996

9097
/**
9198
* Keys that don't get appended to the cell editing mode when you
@@ -114,8 +121,10 @@ export const getStartingFormula = (
114121
editorState: EditorState | undefined,
115122
rowIndex: number,
116123
columnIndex: number,
124+
defaultApplyFormulaToColumn: boolean,
117125
e?: KeyboardEvent
118126
): {startingColumnFormula: string, arrowKeysScrollInFormula: boolean, editingMode: 'entire_column' | 'specific_index_labels'} => {
127+
119128
// Preserve the formula if setting the same column's formula and you're just switching cell editors.
120129
// ie: from the floating cell editor to the formula bar.
121130
if (editorState !== undefined && editorState.columnIndex === columnIndex) {
@@ -132,7 +141,7 @@ export const getStartingFormula = (
132141
return {
133142
startingColumnFormula: '',
134143
arrowKeysScrollInFormula: false,
135-
editingMode: 'entire_column'
144+
editingMode: getDefaultEditingMode(defaultApplyFormulaToColumn)
136145
};
137146
}
138147

@@ -174,14 +183,14 @@ export const getStartingFormula = (
174183
return {
175184
startingColumnFormula: '',
176185
arrowKeysScrollInFormula: false,
177-
editingMode: 'entire_column'
186+
editingMode: getDefaultEditingMode(defaultApplyFormulaToColumn)
178187
}
179188
}
180189

181190
return {
182191
startingColumnFormula: originalValue,
183192
arrowKeysScrollInFormula: true,
184-
editingMode: columnFormulaLocation || 'entire_column'
193+
editingMode: columnFormulaLocation || getDefaultEditingMode(defaultApplyFormulaToColumn)
185194
};
186195
}
187196

mitosheet/src/mito/components/toolbar/FormulaTabContents.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export const FormulaTabContents = (
6565
} else {
6666
const rowIndex = props.gridState.selections[0].startingRowIndex;
6767
const columnIndex = props.gridState.selections[0].startingColumnIndex;
68-
const {startingColumnFormula, arrowKeysScrollInFormula, editingMode} = getStartingFormula(props.sheetData, props.editorState, rowIndex, columnIndex);
68+
const {startingColumnFormula, arrowKeysScrollInFormula, editingMode} = getStartingFormula(props.sheetData, props.editorState, rowIndex, columnIndex, false);
6969
const newFormula = `=${functionObject.function}(${startingColumnFormula.startsWith('=') ? startingColumnFormula.substring(1) : startingColumnFormula}`;
7070

7171
props.setEditorState({

mitosheet/src/mito/types.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ export interface AnalysisData {
802802
pathParts: string[],
803803
} | null;
804804
theme: MitoTheme | null;
805+
defaultApplyFormulaToColumn: boolean;
805806
}
806807

807808
export interface MitoConfig {

mitosheet/src/mito/utils/actions.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ export const getActions = (
156156
const startingRowIndex = gridState.selections[gridState.selections.length - 1].startingRowIndex;
157157
const startingColumnIndex = gridState.selections[gridState.selections.length - 1].startingColumnIndex;
158158
const {columnID, cellValue, columnDtype } = getCellDataFromCellIndexes(sheetData, startingRowIndex, startingColumnIndex);
159-
const {startingColumnFormula, arrowKeysScrollInFormula} = getStartingFormula(sheetData, undefined, startingRowIndex, startingColumnIndex);
159+
const {startingColumnFormula, arrowKeysScrollInFormula} = getStartingFormula(sheetData, undefined, startingRowIndex, startingColumnIndex, analysisData.defaultApplyFormulaToColumn);
160160
const startingColumnID = columnID;
161161
const lastStepSummary = analysisData.stepSummaryList[analysisData.stepSummaryList.length - 1];
162162

0 commit comments

Comments
 (0)