├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── pull_request_template.md └── workflows │ └── release.yml ├── .gitignore ├── .husky ├── .gitignore ├── post-checkout └── pre-commit ├── .prettierignore ├── COPYRIGHT ├── LICENSE ├── demo ├── currencies.js ├── data.js ├── favicon.png ├── file_store.js ├── index.html ├── main.css ├── main.js ├── pivot.js ├── readme.md └── transport.js ├── doc ├── add_function.md ├── add_right_click_item.md ├── extending │ ├── architecture.md │ ├── business_feature.md │ ├── command.md │ ├── plugin.md │ ├── translations.md │ ├── ui_extension.md │ └── xlsx │ │ └── xlsx_import.md ├── integrating │ ├── collaborative │ │ ├── collaborative.md │ │ └── collaborative_choices.md │ └── integration.md ├── o-spreadsheet.png └── o-spreadsheet_terminology.png ├── global.d.ts ├── package-lock.json ├── package.json ├── readme.md ├── rollup.config.js ├── src ├── actions │ ├── action.ts │ ├── data_actions.ts │ ├── edit_actions.ts │ ├── format_actions.ts │ ├── insert_actions.ts │ ├── menu_items_actions.ts │ ├── sheet_actions.ts │ └── view_actions.ts ├── clipboard_handlers │ ├── abstract_cell_clipboard_handler.ts │ ├── abstract_clipboard_handler.ts │ ├── abstract_figure_clipboard_handler.ts │ ├── borders_clipboard.ts │ ├── cell_clipboard.ts │ ├── chart_clipboard.ts │ ├── conditional_format_clipboard.ts │ ├── data_validation_clipboard.ts │ ├── image_clipboard.ts │ ├── index.ts │ ├── merge_clipboard.ts │ ├── references_clipboard.ts │ ├── sheet_clipboard.ts │ └── tables_clipboard.ts ├── collaborative │ ├── local_transport_service.ts │ ├── ot │ │ ├── ot.ts │ │ ├── ot_helpers.ts │ │ └── ot_specific.ts │ ├── revisions.ts │ └── session.ts ├── components │ ├── action_button │ │ ├── action_button.ts │ │ └── action_button.xml │ ├── animation │ │ ├── ripple.ts │ │ └── ripple.xml │ ├── autofill │ │ ├── autofill.ts │ │ └── autofill.xml │ ├── border_editor │ │ ├── border_editor.ts │ │ ├── border_editor.xml │ │ ├── border_editor_widget.ts │ │ └── border_editor_widget.xml │ ├── bottom_bar │ │ ├── bottom_bar.ts │ │ ├── bottom_bar.xml │ │ ├── bottom_bar_sheet │ │ │ ├── bottom_bar_sheet.ts │ │ │ └── bottom_bar_sheet.xml │ │ └── bottom_bar_statistic │ │ │ ├── aggregate_statistics_store.ts │ │ │ ├── bottom_bar_statistic.ts │ │ │ └── bottom_bar_statistic.xml │ ├── collaborative_client_tag │ │ ├── collaborative_client_tag.ts │ │ └── collaborative_client_tag.xml │ ├── color_picker │ │ ├── color_picker.ts │ │ ├── color_picker.xml │ │ ├── color_picker_widget.ts │ │ └── color_picker_widget.xml │ ├── composer │ │ ├── autocomplete_dropdown │ │ │ ├── autocomplete_dropdown.ts │ │ │ ├── autocomplete_dropdown.xml │ │ │ └── autocomplete_dropdown_store.ts │ │ ├── composer │ │ │ ├── abstract_composer_store.ts │ │ │ ├── cell_composer_store.ts │ │ │ ├── composer.ts │ │ │ └── composer.xml │ │ ├── composer_focus_store.ts │ │ ├── content_editable_helper.ts │ │ ├── formula_assistant │ │ │ ├── formula_assistant.ts │ │ │ └── formula_assistant.xml │ │ ├── grid_composer │ │ │ ├── grid_composer.ts │ │ │ └── grid_composer.xml │ │ ├── standalone_composer │ │ │ ├── standalone_composer.ts │ │ │ ├── standalone_composer.xml │ │ │ └── standalone_composer_store.ts │ │ └── top_bar_composer │ │ │ ├── top_bar_composer.ts │ │ │ └── top_bar_composer.xml │ ├── dashboard │ │ ├── clickable_cell_store.ts │ │ ├── dashboard.ts │ │ └── dashboard.xml │ ├── data_validation_overlay │ │ ├── data_validation_overlay.ts │ │ ├── data_validation_overlay.xml │ │ ├── dv_checkbox │ │ │ ├── dv_checkbox.ts │ │ │ └── dv_checkbox.xml │ │ └── dv_list_icon │ │ │ ├── dv_list_icon.ts │ │ │ └── dv_list_icon.xml │ ├── error_tooltip │ │ ├── error_tooltip.ts │ │ └── error_tooltip.xml │ ├── figures │ │ ├── chart │ │ │ ├── chartJs │ │ │ │ ├── chartjs.ts │ │ │ │ ├── chartjs.xml │ │ │ │ ├── chartjs_show_values_plugin.ts │ │ │ │ └── chartjs_waterfall_plugin.ts │ │ │ ├── gauge │ │ │ │ ├── gauge_chart_component.ts │ │ │ │ └── gauge_chart_component.xml │ │ │ └── scorecard │ │ │ │ ├── chart_scorecard.ts │ │ │ │ └── chart_scorecard.xml │ │ ├── figure │ │ │ ├── figure.ts │ │ │ └── figure.xml │ │ ├── figure_chart │ │ │ ├── figure_chart.ts │ │ │ └── figure_chart.xml │ │ ├── figure_container │ │ │ ├── figure_container.ts │ │ │ └── figure_container.xml │ │ └── figure_image │ │ │ ├── figure_image.ts │ │ │ └── figure_image.xml │ ├── filters │ │ ├── filter_icon │ │ │ ├── filter_icon.ts │ │ │ └── filter_icon.xml │ │ ├── filter_icons_overlay │ │ │ ├── filter_icons_overlay.ts │ │ │ └── filter_icons_overlay.xml │ │ ├── filter_menu │ │ │ ├── filter_menu.ts │ │ │ └── filter_menu.xml │ │ └── filter_menu_item │ │ │ ├── filter_menu_value_item.ts │ │ │ └── filter_menu_value_item.xml │ ├── focus_store.ts │ ├── font_size_editor │ │ ├── font_size_editor.ts │ │ └── font_size_editor.xml │ ├── grid │ │ ├── grid.ts │ │ ├── grid.xml │ │ └── hovered_cell_store.ts │ ├── grid_add_rows_footer │ │ ├── grid_add_rows_footer.ts │ │ └── grid_add_rows_footer.xml │ ├── grid_cell_icon │ │ ├── grid_cell_icon.ts │ │ └── grid_cell_icon.xml │ ├── grid_overlay │ │ ├── grid_overlay.ts │ │ └── grid_overlay.xml │ ├── grid_popover │ │ ├── grid_popover.ts │ │ └── grid_popover.xml │ ├── header_group │ │ ├── header_group.ts │ │ ├── header_group.xml │ │ ├── header_group_container.ts │ │ └── header_group_container.xml │ ├── headers_overlay │ │ ├── headers_overlay.ts │ │ └── headers_overlay.xml │ ├── helpers │ │ ├── autofocus_hook.ts │ │ ├── css.ts │ │ ├── dom_helpers.ts │ │ ├── drag_and_drop.ts │ │ ├── drag_and_drop_hook.ts │ │ ├── draw_grid_hook.ts │ │ ├── figure_container_helper.ts │ │ ├── figure_drag_helper.ts │ │ ├── figure_snap_helper.ts │ │ ├── highlight_hook.ts │ │ ├── html_content_helpers.ts │ │ ├── index.ts │ │ ├── listener_hook.ts │ │ ├── position_hook.ts │ │ ├── selection_helpers.ts │ │ ├── time_hooks.ts │ │ ├── touch_scroll_hook.ts │ │ └── wheel_hook.ts │ ├── highlight │ │ ├── border │ │ │ ├── border.ts │ │ │ └── border.xml │ │ ├── corner │ │ │ ├── corner.ts │ │ │ └── corner.xml │ │ └── highlight │ │ │ ├── highlight.ts │ │ │ └── highlight.xml │ ├── icon_picker │ │ ├── icon_picker.ts │ │ └── icon_picker.xml │ ├── icons │ │ ├── icons.ts │ │ └── icons.xml │ ├── index.ts │ ├── link │ │ ├── index.ts │ │ ├── link_display │ │ │ ├── link_display.ts │ │ │ └── link_display.xml │ │ └── link_editor │ │ │ ├── link_editor.ts │ │ │ └── link_editor.xml │ ├── menu │ │ ├── menu.ts │ │ └── menu.xml │ ├── paint_format_button │ │ ├── paint_format_button.ts │ │ ├── paint_format_button.xml │ │ └── paint_format_store.ts │ ├── pivot_html_renderer │ │ ├── pivot_html_renderer.ts │ │ └── pivot_html_renderer.xml │ ├── popover │ │ ├── cell_popover_store.ts │ │ ├── index.ts │ │ ├── popover.ts │ │ ├── popover.xml │ │ └── popover_builders.ts │ ├── scrollbar.ts │ ├── scrollbar │ │ ├── index.ts │ │ ├── scrollbar.ts │ │ ├── scrollbar.xml │ │ ├── scrollbar_horizontal.ts │ │ └── scrollbar_vertical.ts │ ├── selection_input │ │ ├── selection_input.ts │ │ ├── selection_input.xml │ │ └── selection_input_store.ts │ ├── side_panel │ │ ├── chart │ │ │ ├── bar_chart │ │ │ │ ├── bar_chart_config_panel.ts │ │ │ │ └── bar_chart_config_panel.xml │ │ │ ├── building_blocks │ │ │ │ ├── axis_design │ │ │ │ │ ├── axis_design_editor.ts │ │ │ │ │ └── axis_design_editor.xml │ │ │ │ ├── data_series │ │ │ │ │ ├── data_series.ts │ │ │ │ │ └── data_series.xml │ │ │ │ ├── error_section │ │ │ │ │ ├── error_section.ts │ │ │ │ │ └── error_section.xml │ │ │ │ ├── general_design │ │ │ │ │ ├── general_design_editor.ts │ │ │ │ │ └── general_design_editor.xml │ │ │ │ ├── generic_side_panel │ │ │ │ │ ├── config_panel.ts │ │ │ │ │ └── config_panel.xml │ │ │ │ ├── label_range │ │ │ │ │ ├── label_range.ts │ │ │ │ │ └── label_range.xml │ │ │ │ └── title │ │ │ │ │ ├── title.ts │ │ │ │ │ └── title.xml │ │ │ ├── chart_type_picker │ │ │ │ ├── chart_previews.xml │ │ │ │ ├── chart_type_picker.ts │ │ │ │ └── chart_type_picker.xml │ │ │ ├── chart_with_axis │ │ │ │ ├── design_panel.ts │ │ │ │ └── design_panel.xml │ │ │ ├── combo_chart │ │ │ │ ├── combo_chart_config_panel.ts │ │ │ │ ├── combo_chart_config_panel.xml │ │ │ │ ├── combo_chart_design_panel.ts │ │ │ │ └── combo_chart_design_panel.xml │ │ │ ├── gauge_chart_panel │ │ │ │ ├── gauge_chart_config_panel.ts │ │ │ │ ├── gauge_chart_config_panel.xml │ │ │ │ ├── gauge_chart_design_panel.ts │ │ │ │ └── gauge_chart_design_panel.xml │ │ │ ├── index.ts │ │ │ ├── line_chart │ │ │ │ ├── line_chart_config_panel.ts │ │ │ │ └── line_chart_config_panel.xml │ │ │ ├── main_chart_panel │ │ │ │ ├── main_chart_panel.ts │ │ │ │ ├── main_chart_panel.xml │ │ │ │ └── main_chart_panel_store.ts │ │ │ ├── pie_chart │ │ │ │ ├── pie_chart_design_panel.ts │ │ │ │ └── pie_chart_design_panel.xml │ │ │ ├── scatter_chart │ │ │ │ ├── scatter_chart_config_panel.ts │ │ │ │ └── scatter_chart_config_panel.xml │ │ │ ├── scorecard_chart_panel │ │ │ │ ├── scorecard_chart_config_panel.ts │ │ │ │ ├── scorecard_chart_config_panel.xml │ │ │ │ ├── scorecard_chart_design_panel.ts │ │ │ │ └── scorecard_chart_design_panel.xml │ │ │ └── waterfall_chart │ │ │ │ ├── waterfall_chart_design_panel.ts │ │ │ │ └── waterfall_chart_design_panel.xml │ │ ├── components │ │ │ ├── badge_selection │ │ │ │ ├── badge_selection.ts │ │ │ │ └── badge_selection.xml │ │ │ ├── checkbox │ │ │ │ ├── checkbox.ts │ │ │ │ └── checkbox.xml │ │ │ ├── cog_wheel_menu │ │ │ │ ├── cog_wheel_menu.ts │ │ │ │ └── cog_wheel_menu.xml │ │ │ ├── collapsible │ │ │ │ ├── side_panel_collapsible.ts │ │ │ │ └── side_panel_collapsible.xml │ │ │ ├── radio_selection │ │ │ │ ├── radio_selection.ts │ │ │ │ └── radio_selection.xml │ │ │ ├── round_color_picker │ │ │ │ ├── round_color_picker.ts │ │ │ │ └── round_color_picker.xml │ │ │ └── section │ │ │ │ ├── section.ts │ │ │ │ └── section.xml │ │ ├── conditional_formatting │ │ │ ├── cf_editor │ │ │ │ ├── cell_is_rule_editor.xml │ │ │ │ ├── cf_editor.ts │ │ │ │ ├── cf_editor.xml │ │ │ │ ├── color_scale_rule_editor.xml │ │ │ │ ├── data_bar_rule_editor.xml │ │ │ │ └── icon_set_rule_editor.xml │ │ │ ├── cf_preview │ │ │ │ ├── cf_preview.ts │ │ │ │ └── cf_preview.xml │ │ │ ├── cf_preview_list │ │ │ │ ├── cf_preview_list.ts │ │ │ │ └── cf_preview_list.xml │ │ │ ├── conditional_formatting.ts │ │ │ └── conditional_formatting.xml │ │ ├── custom_currency │ │ │ ├── custom_currency.ts │ │ │ └── custom_currency.xml │ │ ├── data_validation │ │ │ ├── data_validation_panel.ts │ │ │ ├── data_validation_panel.xml │ │ │ ├── data_validation_panel_helper.ts │ │ │ ├── dv_criterion_form │ │ │ │ ├── dv_criterion_form.ts │ │ │ │ ├── dv_date_criterion │ │ │ │ │ ├── dv_date_criterion.ts │ │ │ │ │ └── dv_date_criterion.xml │ │ │ │ ├── dv_double_input_criterion │ │ │ │ │ ├── dv_double_input_criterion.ts │ │ │ │ │ └── dv_double_input_criterion.xml │ │ │ │ ├── dv_input │ │ │ │ │ ├── dv_input.ts │ │ │ │ │ └── dv_input.xml │ │ │ │ ├── dv_single_input_criterion │ │ │ │ │ ├── dv_single_input_criterion.ts │ │ │ │ │ └── dv_single_input_criterion.xml │ │ │ │ ├── dv_value_in_list_criterion │ │ │ │ │ ├── dv_value_in_list_criterion.ts │ │ │ │ │ └── dv_value_in_list_criterion.xml │ │ │ │ └── dv_value_in_range_criterion │ │ │ │ │ ├── dv_value_in_range_criterion.ts │ │ │ │ │ └── dv_value_in_range_criterion.xml │ │ │ ├── dv_editor │ │ │ │ ├── dv_editor.ts │ │ │ │ └── dv_editor.xml │ │ │ └── dv_preview │ │ │ │ ├── dv_preview.ts │ │ │ │ └── dv_preview.xml │ │ ├── find_and_replace │ │ │ ├── find_and_replace.ts │ │ │ ├── find_and_replace.xml │ │ │ └── find_and_replace_store.ts │ │ ├── more_formats │ │ │ ├── more_formats.ts │ │ │ └── more_formats.xml │ │ ├── pivot │ │ │ ├── editable_name │ │ │ │ ├── editable_name.ts │ │ │ │ └── editable_name.xml │ │ │ ├── pivot_defer_update │ │ │ │ ├── pivot_defer_update.ts │ │ │ │ └── pivot_defer_update.xml │ │ │ ├── pivot_layout_configurator │ │ │ │ ├── add_dimension_button │ │ │ │ │ ├── add_dimension_button.ts │ │ │ │ │ └── add_dimension_button.xml │ │ │ │ ├── pivot_dimension │ │ │ │ │ ├── pivot_dimension.ts │ │ │ │ │ └── pivot_dimension.xml │ │ │ │ ├── pivot_dimension_granularity │ │ │ │ │ ├── pivot_dimension_granularity.ts │ │ │ │ │ └── pivot_dimension_granularity.xml │ │ │ │ ├── pivot_dimension_order │ │ │ │ │ ├── pivot_dimension_order.ts │ │ │ │ │ └── pivot_dimension_order.xml │ │ │ │ ├── pivot_layout_configurator.ts │ │ │ │ ├── pivot_layout_configurator.xml │ │ │ │ └── pivot_measure │ │ │ │ │ ├── pivot_measure.ts │ │ │ │ │ └── pivot_measure.xml │ │ │ ├── pivot_measure_display_panel │ │ │ │ ├── pivot_measure_display_panel.ts │ │ │ │ ├── pivot_measure_display_panel.xml │ │ │ │ └── pivot_measure_display_panel_store.ts │ │ │ ├── pivot_side_panel │ │ │ │ ├── pivot_side_panel.ts │ │ │ │ ├── pivot_side_panel.xml │ │ │ │ ├── pivot_side_panel_store.ts │ │ │ │ └── pivot_spreadsheet_side_panel │ │ │ │ │ ├── pivot_spreadsheet_side_panel.ts │ │ │ │ │ └── pivot_spreadsheet_side_panel.xml │ │ │ └── pivot_title_section │ │ │ │ ├── pivot_title_section.ts │ │ │ │ └── pivot_title_section.xml │ │ ├── remove_duplicates │ │ │ ├── remove_duplicates.ts │ │ │ └── remove_duplicates.xml │ │ ├── select_menu │ │ │ ├── select_menu.ts │ │ │ └── select_menu.xml │ │ ├── settings │ │ │ ├── settings_panel.ts │ │ │ └── settings_panel.xml │ │ ├── side_panel │ │ │ ├── side_panel.ts │ │ │ ├── side_panel.xml │ │ │ └── side_panel_store.ts │ │ ├── split_to_columns_panel │ │ │ ├── split_to_columns_panel.ts │ │ │ └── split_to_columns_panel.xml │ │ ├── table_panel │ │ │ ├── table_panel.ts │ │ │ └── table_panel.xml │ │ └── table_style_editor_panel │ │ │ ├── table_style_editor_panel.ts │ │ │ └── table_style_editor_panel.xml │ ├── spreadsheet │ │ ├── spreadsheet.ts │ │ └── spreadsheet.xml │ ├── tables │ │ ├── table_dropdown_button │ │ │ ├── table_dropdown_button.ts │ │ │ └── table_dropdown_button.xml │ │ ├── table_resizer │ │ │ ├── table_resizer.ts │ │ │ └── table_resizer.xml │ │ ├── table_style_picker │ │ │ ├── table_style_picker.ts │ │ │ └── table_style_picker.xml │ │ ├── table_style_preview │ │ │ ├── table_canvas_helpers.ts │ │ │ ├── table_style_preview.ts │ │ │ └── table_style_preview.xml │ │ └── table_styles_popover │ │ │ ├── table_styles_popover.ts │ │ │ └── table_styles_popover.xml │ ├── text_input │ │ ├── text_input.ts │ │ └── text_input.xml │ ├── top_bar │ │ ├── top_bar.ts │ │ └── top_bar.xml │ ├── translations_terms.ts │ └── validation_messages │ │ ├── validation_messages.ts │ │ └── validation_messages.xml ├── constants.ts ├── formulas │ ├── code_builder.ts │ ├── compiler.ts │ ├── composer_tokenizer.ts │ ├── helpers.ts │ ├── index.ts │ ├── parser.ts │ ├── range_tokenizer.ts │ └── tokenizer.ts ├── functions │ ├── arguments.ts │ ├── helper_assert.ts │ ├── helper_financial.ts │ ├── helper_logical.ts │ ├── helper_lookup.ts │ ├── helper_math.ts │ ├── helper_matrices.ts │ ├── helper_parser.ts │ ├── helper_statistical.ts │ ├── helpers.ts │ ├── index.ts │ ├── module_array.ts │ ├── module_custom.ts │ ├── module_database.ts │ ├── module_date.ts │ ├── module_engineering.ts │ ├── module_filter.ts │ ├── module_financial.ts │ ├── module_info.ts │ ├── module_logical.ts │ ├── module_lookup.ts │ ├── module_math.ts │ ├── module_operators.ts │ ├── module_parser.ts │ ├── module_statistical.ts │ ├── module_text.ts │ └── module_web.ts ├── helpers │ ├── cells │ │ ├── cell_evaluation.ts │ │ └── index.ts │ ├── chart_date.ts │ ├── clipboard │ │ ├── clipboard_helpers.ts │ │ └── navigator_clipboard_wrapper.ts │ ├── color.ts │ ├── coordinates.ts │ ├── data_normalization.ts │ ├── data_validation_helpers.ts │ ├── dates.ts │ ├── edge_scrolling.ts │ ├── event_bus.ts │ ├── figures │ │ ├── charts │ │ │ ├── abstract_chart.ts │ │ │ ├── bar_chart.ts │ │ │ ├── chart_common.ts │ │ │ ├── chart_common_line_scatter.ts │ │ │ ├── chart_factory.ts │ │ │ ├── chart_ui_common.ts │ │ │ ├── combo_chart.ts │ │ │ ├── gauge_chart.ts │ │ │ ├── gauge_chart_rendering.ts │ │ │ ├── index.ts │ │ │ ├── line_chart.ts │ │ │ ├── pie_chart.ts │ │ │ ├── pyramid_chart.ts │ │ │ ├── scatter_chart.ts │ │ │ ├── scorecard_chart.ts │ │ │ ├── scorecard_chart_config_builder.ts │ │ │ └── waterfall_chart.ts │ │ ├── figure │ │ │ └── figure.ts │ │ └── images │ │ │ └── image_provider.ts │ ├── format │ │ ├── format.ts │ │ ├── format_parser.ts │ │ └── format_tokenizer.ts │ ├── index.ts │ ├── internal_viewport.ts │ ├── inverse_commands.ts │ ├── links.ts │ ├── locale.ts │ ├── misc.ts │ ├── numbers.ts │ ├── pivot │ │ ├── pivot_composer_helpers.ts │ │ ├── pivot_domain_helpers.ts │ │ ├── pivot_helpers.ts │ │ ├── pivot_highlight.ts │ │ ├── pivot_menu_items.ts │ │ ├── pivot_positional_formula_registry.ts │ │ ├── pivot_presence_tracker.ts │ │ ├── pivot_presentation.ts │ │ ├── pivot_registry.ts │ │ ├── pivot_runtime_definition.ts │ │ ├── pivot_side_panel_registry.ts │ │ ├── pivot_time_adapter.ts │ │ ├── spreadsheet_pivot │ │ │ ├── data_entry_spreadsheet_pivot.ts │ │ │ ├── date_spreadsheet_pivot.ts │ │ │ ├── runtime_definition_spreadsheet_pivot.ts │ │ │ └── spreadsheet_pivot.ts │ │ └── table_spreadsheet_pivot.ts │ ├── range.ts │ ├── recompute_zones.ts │ ├── rectangle.ts │ ├── reference_type.ts │ ├── references.ts │ ├── rendering.ts │ ├── search.ts │ ├── sheet.ts │ ├── sort.ts │ ├── state_manager_helpers.ts │ ├── table_helpers.ts │ ├── table_presets.ts │ ├── text_helper.ts │ ├── ui │ │ ├── cut_interactive.ts │ │ ├── freeze_interactive.ts │ │ ├── merge_interactive.ts │ │ ├── paste_interactive.ts │ │ ├── sheet_interactive.ts │ │ ├── split_to_columns_interactive.ts │ │ ├── table_interactive.ts │ │ └── toggle_group_interactive.ts │ ├── uuid.ts │ └── zones.ts ├── history │ ├── branch.ts │ ├── factory.ts │ ├── operation.ts │ ├── operation_sequence.ts │ ├── repeat_commands │ │ ├── repeat_commands_generic.ts │ │ ├── repeat_commands_specific.ts │ │ └── repeat_revision.ts │ ├── selective_history.ts │ └── tree.ts ├── index.ts ├── migrations │ ├── data.ts │ ├── legacy_tools.ts │ ├── locale.ts │ └── migration_steps.ts ├── model.ts ├── plugins │ ├── base_plugin.ts │ ├── core │ │ ├── borders.ts │ │ ├── cell.ts │ │ ├── chart.ts │ │ ├── conditional_format.ts │ │ ├── data_validation.ts │ │ ├── figures.ts │ │ ├── header_grouping.ts │ │ ├── header_size.ts │ │ ├── header_visibility.ts │ │ ├── image.ts │ │ ├── index.ts │ │ ├── merge.ts │ │ ├── pivot.ts │ │ ├── range.ts │ │ ├── settings.ts │ │ ├── sheet.ts │ │ ├── spreadsheet_pivot.ts │ │ ├── table_style.ts │ │ └── tables.ts │ ├── core_plugin.ts │ ├── index.ts │ ├── ui_core_views │ │ ├── cell_evaluation │ │ │ ├── binary_grid.ts │ │ │ ├── compilation_parameters.ts │ │ │ ├── evaluation_plugin.ts │ │ │ ├── evaluator.ts │ │ │ ├── formula_dependency_graph.ts │ │ │ ├── index.ts │ │ │ ├── position_map.ts │ │ │ ├── position_set.ts │ │ │ ├── r_tree.ts │ │ │ └── spreading_relation.ts │ │ ├── custom_colors.ts │ │ ├── dynamic_tables.ts │ │ ├── evaluation_chart.ts │ │ ├── evaluation_conditional_format.ts │ │ ├── evaluation_data_validation.ts │ │ ├── header_sizes_ui.ts │ │ ├── index.ts │ │ └── pivot_ui.ts │ ├── ui_feature │ │ ├── autofill.ts │ │ ├── automatic_sum.ts │ │ ├── cell_computed_style.ts │ │ ├── collaborative.ts │ │ ├── data_cleanup.ts │ │ ├── datavalidation_insertion.ts │ │ ├── format.ts │ │ ├── header_visibility_ui.ts │ │ ├── index.ts │ │ ├── insert_pivot.ts │ │ ├── local_history.ts │ │ ├── pivot_presence_plugin.ts │ │ ├── sort.ts │ │ ├── split_to_columns.ts │ │ ├── table_autofill.ts │ │ ├── table_computed_style.ts │ │ ├── table_resize_ui.ts │ │ ├── ui_options.ts │ │ └── ui_sheet.ts │ ├── ui_plugin.ts │ └── ui_stateful │ │ ├── clipboard.ts │ │ ├── filter_evaluation.ts │ │ ├── header_positions.ts │ │ ├── index.ts │ │ ├── selection.ts │ │ └── sheetview.ts ├── registries │ ├── auto_completes │ │ ├── auto_complete_registry.ts │ │ ├── data_validation_auto_complete.ts │ │ ├── function_auto_complete.ts │ │ ├── index.ts │ │ ├── pivot_auto_complete.ts │ │ ├── pivot_dimension_auto_complete.ts │ │ └── sheet_name_auto_complete.ts │ ├── autofill_modifiers.ts │ ├── autofill_rules.ts │ ├── cell_clickable_registry.ts │ ├── cell_popovers_registry.ts │ ├── chart_types.ts │ ├── currencies_registry.ts │ ├── data_validation_registry.ts │ ├── evaluation_registry.ts │ ├── figure_registry.ts │ ├── icons_on_cell_registry.ts │ ├── index.ts │ ├── inverse_command_registry.ts │ ├── menu_items_registry.ts │ ├── menus │ │ ├── cell_menu_registry.ts │ │ ├── col_menu_registry.ts │ │ ├── header_group_registry.ts │ │ ├── index.ts │ │ ├── link_menu_registry.ts │ │ ├── number_format_menu_registry.ts │ │ ├── row_menu_registry.ts │ │ ├── sheet_menu_registry.ts │ │ ├── table_style_menu_registry.ts │ │ └── topbar_menu_registry.ts │ ├── ot_registry.ts │ ├── registry.ts │ ├── repeat_commands_registry.ts │ ├── side_panel_registry.ts │ ├── side_panel_registry_entries.ts │ └── topbar_component_registry.ts ├── selection_stream │ ├── event_stream.ts │ └── selection_stream_processor.ts ├── state_observer.ts ├── store_engine │ ├── README.md │ ├── dependency_container.ts │ ├── index.ts │ ├── store.ts │ └── store_hooks.ts ├── stores │ ├── DOM_focus_store.ts │ ├── array_formula_highlight.ts │ ├── grid_renderer_store.ts │ ├── highlight_store.ts │ ├── index.ts │ ├── model_store.ts │ ├── notification_store.ts │ ├── renderer_store.ts │ └── spreadsheet_store.ts ├── translation.ts ├── types │ ├── autofill.ts │ ├── cell_popovers.ts │ ├── cells.ts │ ├── chart │ │ ├── bar_chart.ts │ │ ├── chart.ts │ │ ├── combo_chart.ts │ │ ├── common_bar_combo.ts │ │ ├── common_chart.ts │ │ ├── gauge_chart.ts │ │ ├── index.ts │ │ ├── line_chart.ts │ │ ├── pie_chart.ts │ │ ├── pyramid_chart.ts │ │ ├── scatter_chart.ts │ │ ├── scorecard_chart.ts │ │ └── waterfall_chart.ts │ ├── clipboard.ts │ ├── collaborative │ │ ├── revisions.ts │ │ ├── session.ts │ │ └── transport_service.ts │ ├── commands.ts │ ├── conditional_formatting.ts │ ├── currency.ts │ ├── data_validation.ts │ ├── env.ts │ ├── errors.ts │ ├── event_stream │ │ ├── index.ts │ │ └── selection_events.ts │ ├── figure.ts │ ├── files.ts │ ├── find_and_replace.ts │ ├── format.ts │ ├── functions.ts │ ├── getters.ts │ ├── history.ts │ ├── image.ts │ ├── index.ts │ ├── locale.ts │ ├── misc.ts │ ├── pivot.ts │ ├── pivot_runtime.ts │ ├── range.ts │ ├── rendering.ts │ ├── table.ts │ ├── validator.ts │ ├── workbook_data.ts │ └── xlsx.ts └── xlsx │ ├── constants.ts │ ├── conversion │ ├── cf_conversion.ts │ ├── color_conversion.ts │ ├── conversion_maps.ts │ ├── data_validation_conversion.ts │ ├── figure_conversion.ts │ ├── format_conversion.ts │ ├── formula_conversion.ts │ ├── index.ts │ ├── sheet_conversion.ts │ ├── style_conversion.ts │ └── table_conversion.ts │ ├── extraction │ ├── base_extractor.ts │ ├── cf_extractor.ts │ ├── chart_extractor.ts │ ├── data_validation_extractor.ts │ ├── external_book_extractor.ts │ ├── figure_extractor.ts │ ├── index.ts │ ├── misc_extractor.ts │ ├── pivot_extractor.ts │ ├── sheet_extractor.ts │ ├── style_extractor.ts │ └── table_extractor.ts │ ├── functions │ ├── cells.ts │ ├── charts.ts │ ├── conditional_formatting.ts │ ├── data_validation.ts │ ├── drawings.ts │ ├── styles.ts │ ├── table.ts │ └── worksheet.ts │ ├── helpers │ ├── colors.ts │ ├── content_helpers.ts │ ├── misc.ts │ ├── xlsx_helper.ts │ ├── xlsx_parser_error_manager.ts │ └── xml_helpers.ts │ ├── xlsx_reader.ts │ └── xlsx_writer.ts ├── tests ├── __mocks__ │ ├── content_editable_helper.ts │ ├── dom_helpers.ts │ ├── mock_file_store.ts │ ├── mock_image_provider.ts │ ├── mock_misc_helpers.ts │ └── transport_service.ts ├── __snapshots__ │ ├── cog_wheel_menu.test.ts.snap │ ├── renderer_store.test.ts.snap │ └── top_bar_component.test.ts.snap ├── __xlsx__ │ ├── read_demo_xlsx.ts │ └── xlsx_demo_data.xlsx ├── action_button.test.ts ├── autofill │ ├── autofill_component.test.ts │ └── autofill_plugin.test.ts ├── borders │ ├── border_editor_component.test.ts │ └── border_plugin.test.ts ├── bottom_bar │ ├── __snapshots__ │ │ └── bottom_bar_component.test.ts.snap │ ├── aggregate_statistics_store.test.ts │ ├── automatic_sum_model.test.ts │ └── bottom_bar_component.test.ts ├── cells │ ├── cell_plugin.test.ts │ ├── cell_popovers_store.test.ts │ ├── merges_plugin.test.ts │ └── style_plugin.test.ts ├── clipboard │ ├── clipboard_figure_plugin.test.ts │ └── clipboard_plugin.test.ts ├── cog_wheel_menu.test.ts ├── collaborative │ ├── collaborative.test.ts │ ├── collaborative_clipboard.test.ts │ ├── collaborative_helpers.ts │ ├── collaborative_history.test.ts │ ├── collaborative_monkey_party.test.ts │ ├── collaborative_selection.test.ts │ ├── collaborative_session.test.ts │ ├── collaborative_sheet_manipulations.test.ts │ ├── inverses.test.ts │ └── ot │ │ ├── ot.test.ts │ │ ├── ot_columns_added.test.ts │ │ ├── ot_columns_removed.test.ts │ │ ├── ot_merged.test.ts │ │ ├── ot_rows_added.test.ts │ │ ├── ot_rows_removed.test.ts │ │ └── ot_sheet_deleted.test.ts ├── colors │ ├── __snapshots__ │ │ └── color_picker_component.test.ts.snap │ ├── color_helpers.test.ts │ ├── color_picker_component.test.ts │ └── custom_colors_plugin.test.ts ├── components │ ├── __snapshots__ │ │ ├── pivot_html_renderer.test.ts.snap │ │ └── text_input.test.ts.snap │ ├── pivot_html_renderer.test.ts │ └── text_input.test.ts ├── composer │ ├── __snapshots__ │ │ ├── autocomplete_dropdown_component.test.ts.snap │ │ ├── composer_integration_component.test.ts.snap │ │ ├── content_editable_helpers.test.ts.snap │ │ └── formula_assistant_component.test.ts.snap │ ├── auto_complete │ │ ├── data_validation_auto_complete_store.test.ts │ │ ├── function_auto_complete_store.test.ts │ │ ├── pivot_auto_complete_store.test.ts │ │ └── sheet_name_auto_complete_store.test.ts │ ├── autocomplete_dropdown_component.test.ts │ ├── composer_component.test.ts │ ├── composer_integration_component.test.ts │ ├── composer_sheet_transform_plugin.test.ts │ ├── composer_store.test.ts │ ├── content_editable_helpers.test.ts │ ├── formula_assistant_component.test.ts │ └── standalone_composer_component.test.ts ├── conditional_formatting │ ├── __snapshots__ │ │ └── conditional_formatting_panel_component.test.ts.snap │ ├── conditional_formatting_panel_component.test.ts │ └── conditional_formatting_plugin.test.ts ├── data_validation │ ├── data_validation_blocking_component.test.ts │ ├── data_validation_checkbox_component.test.ts │ ├── data_validation_checkbox_plugin.test.ts │ ├── data_validation_clipboard_plugin.test.ts │ ├── data_validation_core_plugin.test.ts │ ├── data_validation_generics_side_panel_component.test.ts │ ├── data_validation_list_component.test.ts │ ├── data_validation_preview_component.test.ts │ ├── data_validation_registry.test.ts │ └── evaluation_data_validation_plugin.test.ts ├── evaluation │ ├── __snapshots__ │ │ ├── compiler.test.ts.snap │ │ └── composer_tokenizer.test.ts.snap │ ├── compiler.test.ts │ ├── composer_tokenizer.test.ts │ ├── evaluation.test.ts │ ├── evaluation_formula_array.test.ts │ ├── expressions.test.ts │ ├── formulas.test.ts │ ├── parser.test.ts │ ├── range_tokenizer.test.ts │ └── tokenizer.test.ts ├── figures │ ├── __snapshots__ │ │ └── figure_component.test.ts.snap │ ├── chart │ │ ├── __snapshots__ │ │ │ └── chart_plugin.test.ts.snap │ │ ├── bar_chart_plugin.test.ts │ │ ├── chart_plugin.test.ts │ │ ├── chart_type_picker.test.ts │ │ ├── charts_component.test.ts │ │ ├── combo_chart_component.test.ts │ │ ├── combo_chart_plugin.test.ts │ │ ├── common_chart_plugin.test.ts │ │ ├── gauge │ │ │ ├── __snapshots__ │ │ │ │ └── gauge_chart_plugin.test.ts.snap │ │ │ ├── gauge_chart_plugin.test.ts │ │ │ └── gauge_rendering.test.ts │ │ ├── line_chart_plugin.test.ts │ │ ├── menu_item_insert_chart.test.ts │ │ ├── pie_chart_plugin.test.ts │ │ ├── pyramid_chart │ │ │ ├── pyramid_chart_component.test.ts │ │ │ └── pyramid_chart_plugin.test.ts │ │ ├── scorecard │ │ │ ├── scorecard_chart_component.test.ts │ │ │ └── scorecard_chart_plugin.test.ts │ │ └── waterfall │ │ │ ├── waterfall_chart_plugin.test.ts │ │ │ └── waterfall_panel_component.test.ts │ ├── figure_component.test.ts │ ├── figures_plugin.test.ts │ └── image │ │ ├── image_file_store.test.ts │ │ └── image_plugin.test.ts ├── find_and_replace │ ├── find_and_replace_store.test.ts │ └── find_replace_side_panel_component.test.ts ├── formats │ ├── __snapshots__ │ │ └── custom_currency_side_panel_component.test.ts.snap │ ├── custom_currency_side_panel_component.test.ts │ ├── format_helpers.test.ts │ ├── formatting_plugin.test.ts │ ├── more_formats_side_panel.test.ts │ └── plain_text_format.test.ts ├── functions │ ├── arguments.test.ts │ ├── dates.test.ts │ ├── functions.test.ts │ ├── helper.test.ts │ ├── module_array.test.ts │ ├── module_custom.test.ts │ ├── module_database.test.ts │ ├── module_date.test.ts │ ├── module_engineering.test.ts │ ├── module_filter.test.ts │ ├── module_financial.test.ts │ ├── module_info.test.ts │ ├── module_logical.test.ts │ ├── module_lookup.test.ts │ ├── module_math.test.ts │ ├── module_operators.test.ts │ ├── module_parser.test.ts │ ├── module_statistical.test.ts │ ├── module_text.test.ts │ ├── module_web.test.ts │ └── vectorization.test.ts ├── grid │ ├── __snapshots__ │ │ ├── dashboard_grid_component.test.ts.snap │ │ └── grid_component.test.ts.snap │ ├── array_formula_highlights_store.test.ts │ ├── dashboard_grid_component.test.ts │ ├── grid_cell_icon_component.test.ts │ ├── grid_component.test.ts │ ├── grid_drag_and_drop_component.test.ts │ ├── grid_overlay_component.test.ts │ ├── highlight_component.test.ts │ └── highlight_store.test.ts ├── header_group │ ├── __snapshots__ │ │ └── header_group_component.test.ts.snap │ ├── header_group_component.test.ts │ └── header_group_plugin.test.ts ├── headers │ ├── header_visibility_plugin.test.ts │ └── resizing_plugin.test.ts ├── helpers │ ├── coordinates_helpers.test.ts │ ├── css_helpers.test.ts │ ├── locale_helpers.test.ts │ ├── misc_helpers.test.ts │ ├── numbers_helpers.test.ts │ ├── positions_map.test.ts │ ├── positions_set.test.ts │ ├── recompute_zones_helpers.test.ts │ ├── reference_types_helpers.test.ts │ ├── search_helpers.test.ts │ ├── sheet.test.ts │ ├── translation_helpers.test.ts │ ├── ui_helpers.test.ts │ └── zones_helpers.test.ts ├── history │ ├── history_plugin.test.ts │ └── selective_history_plugin.test.ts ├── link │ ├── __snapshots__ │ │ └── link_display_component.test.ts.snap │ ├── link_display_component.test.ts │ └── link_editor_component.test.ts ├── menus │ ├── __snapshots__ │ │ └── context_menu_component.test.ts.snap │ ├── context_menu_component.test.ts │ ├── menu_items_registry.test.ts │ └── menu_items_registry_cross_spreadsheet.test.ts ├── model │ ├── core.test.ts │ ├── data.test.ts │ ├── model.test.ts │ └── model_import_export.test.ts ├── pivots │ ├── add_dimension_button.test.ts │ ├── pivot_calculated_measure.test.ts │ ├── pivot_data.ts │ ├── pivot_helpers.test.ts │ ├── pivot_insert.test.ts │ ├── pivot_measure │ │ ├── pivot_measure_display_model.test.ts │ │ └── pivot_measure_display_panel.test.ts │ ├── pivot_menu_items.test.ts │ ├── pivot_plugin.test.ts │ ├── pivot_side_panel.test.ts │ └── spreadsheet_pivot │ │ ├── __snapshots__ │ │ └── spreadsheet_pivot_side_panel.test.ts.snap │ │ ├── date_spreadsheet_pivot.test.ts │ │ ├── spreadsheet_pivot.test.ts │ │ └── spreadsheet_pivot_side_panel.test.ts ├── popover │ ├── __snapshots__ │ │ └── error_tooltip_component.test.ts.snap │ ├── error_tooltip_component.test.ts │ └── popover_component.test.ts ├── range_plugin.test.ts ├── readme.md ├── remove_duplicates │ ├── remove_duplicates_plugin.test.ts │ └── remove_duplicates_side_panel_component.test.ts ├── renderer_store.test.ts ├── repeat_commands_plugin.test.ts ├── select_menu_component.test.ts ├── selection_input │ ├── selection_input_component.test.ts │ └── selection_input_store.test.ts ├── settings │ ├── settings_plugin.test.ts │ └── settings_side_panel.test.ts ├── setup │ ├── canvas.mock.ts │ ├── jest.setup.ts │ ├── jest_extend.ts │ ├── jest_global_setup.ts │ ├── jest_global_teardown.ts │ ├── polyfill.ts │ └── resize_observer.mock.ts ├── sheet │ ├── __snapshots__ │ │ └── sheet_manipulation_plugin.test.ts.snap │ ├── navigation_plugin.test.ts │ ├── selection_plugin.test.ts │ ├── sheet_manipulation_component.test.ts │ ├── sheet_manipulation_plugin.test.ts │ ├── sheets_plugin.test.ts │ └── sheetview_plugin.test.ts ├── side_panels │ ├── building_blocks │ │ ├── __snapshots__ │ │ │ ├── data_series.test.ts.snap │ │ │ ├── error_section.test.ts.snap │ │ │ ├── label_range.test.ts.snap │ │ │ ├── round_color_picker.test.ts.snap │ │ │ └── title.test.ts.snap │ │ ├── data_series.test.ts │ │ ├── error_section.test.ts │ │ ├── label_range.test.ts │ │ ├── round_color_picker.test.ts │ │ └── title.test.ts │ └── components │ │ ├── __snapshots__ │ │ ├── checkbox.test.ts.snap │ │ └── section.test.ts.snap │ │ ├── checkbox.test.ts │ │ └── section.test.ts ├── sort_plugin.test.ts ├── split_to_column │ ├── split_to_column_plugin.test.ts │ └── split_to_columns_panel.test.ts ├── spreadsheet │ ├── __snapshots__ │ │ └── spreadsheet_component.test.ts.snap │ ├── side_panel_component.test.ts │ └── spreadsheet_component.test.ts ├── table │ ├── __snapshots__ │ │ └── filter_menu_component.test.ts.snap │ ├── dynamic_table_plugin.test.ts │ ├── filter_evaluation_plugin.test.ts │ ├── filter_icon_overlay.test.ts │ ├── filter_menu_component.test.ts │ ├── table_autofill_plugin.test.ts │ ├── table_computed_style_plugin.test.ts │ ├── table_core_style_plugin.test.ts │ ├── table_dropdown_button_component.test.ts │ ├── table_helpers.test.ts │ ├── table_panel_component.test.ts │ ├── table_resize_ui_plugin.test.ts │ ├── table_resizer_component.test.ts │ ├── table_style_editor_panel_component.test.ts │ ├── table_styles_popover_component.test.ts │ └── tables_plugin.test.ts ├── test_helpers │ ├── chart_helpers.ts │ ├── clipboard.ts │ ├── commands_helpers.ts │ ├── constants.ts │ ├── debug_helpers.ts │ ├── dom_helper.ts │ ├── getters_helpers.ts │ ├── helpers.ts │ ├── index.ts │ ├── mock_helpers.ts │ ├── pivot_helpers.ts │ ├── renderer_helpers.ts │ ├── stores.ts │ └── xlsx.ts ├── top_bar_component.test.ts ├── trim_whitespace_plugin.test.ts └── xlsx │ ├── __snapshots__ │ └── xlsx_export.test.ts.snap │ ├── xlsx_export.test.ts │ ├── xlsx_import.test.ts │ └── xlsx_import_export.test.ts ├── tools ├── bundle.cjs ├── bundle_xlsx │ ├── unzip_xlsx_demo.cjs │ ├── unzip_xlsx_demo.sh │ ├── zip_xlsx_demo.cjs │ └── zip_xlsx_demo.sh ├── bundle_xml │ ├── bundle_xml_templates.cjs │ ├── main.cjs │ └── watch_xml_templates.cjs ├── owl_templates │ └── compile_templates.cjs ├── parse_message.cjs └── server │ └── main.cjs ├── tsconfig.base.json ├── tsconfig.jest.json └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "jest": true 6 | }, 7 | "extends": "eslint:recommended", 8 | "globals": { 9 | "owl": "readonly", 10 | "o_spreadsheet": "readonly" 11 | }, 12 | "parser": "babel-eslint", 13 | "parserOptions": { 14 | "ecmaVersion": 2018, 15 | "sourceType": "module" 16 | }, 17 | "rules": { 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | **Version (please indicate which version you are using):** 10 | - [ ] 16.0 11 | - [ ] 17.0 12 | - [ ] other: specify 13 | 14 | **Platform (OS and Browser + version):** 15 | example: Windows 10, Chrome 80.0.3987.149 16 | 17 | 18 | **Describe the bug** 19 | A clear and concise description of what the bug is. 20 | 21 | **To Reproduce** 22 | Steps to reproduce the behavior: 23 | 1. Go to '...' 24 | 2. Click on '....' 25 | 3. Scroll down to '....' 26 | 4. See error 27 | 28 | **Expected behavior** 29 | A clear and concise description of what you expected to happen. 30 | 31 | **Screenshots** 32 | If applicable, add screenshots to help explain your problem. 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description: 2 | 3 | description of this task, what is implemented and why it is implemented that way. 4 | 5 | Task: [TASK_ID](https://www.odoo.com/odoo/2328/tasks/TASK_ID) 6 | 7 | ## review checklist 8 | 9 | - [ ] feature is organized in plugin, or UI components 10 | - [ ] support of duplicate sheet (deep copy) 11 | - [ ] in model/core: ranges are Range object, and can be adapted (adaptRanges) 12 | - [ ] in model/UI: ranges are strings (to show the user) 13 | - [ ] undo-able commands (uses this.history.update) 14 | - [ ] multiuser-able commands (has inverse commands and transformations where needed) 15 | - [ ] new/updated/removed commands are documented 16 | - [ ] exportable in excel 17 | - [ ] translations (\_t("qmsdf %s", abc)) 18 | - [ ] unit tested 19 | - [ ] clean commented code 20 | - [ ] track breaking changes 21 | - [ ] doc is rebuild (npm run doc) 22 | - [ ] status is correct in Odoo -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .idea/ 3 | .vscode/ 4 | dist/ 5 | build/ 6 | .npmrc 7 | /coverage/ 8 | logs/ 9 | 10 | debug.log 11 | .git.cache 12 | tests/__xlsx__/xlsx_demo_data/* 13 | # Excel temp file 14 | tests/__xlsx__/~$xlsx_demo_data.xlsx 15 | 16 | tools/owl_templates/_compiled/* 17 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/post-checkout: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | if [ "$HUSKY_POST_CHECKOUT" != 0 ]; then 5 | if [ "$1" != "$2" ]; then 6 | npm install >/dev/null 2>&1 7 | fi 8 | fi 9 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .eslintrc.json 2 | .prettierignore 3 | COPYRIGHT 4 | LICENSE 5 | 6 | .husky/ 7 | .github/ 8 | .idea/ 9 | .vscode/ 10 | dist/ 11 | build/ 12 | .gitignore 13 | .npmrc 14 | coverage/ 15 | logs/ 16 | tests/**/__snapshots__ 17 | tests/**/xlsx_demo_data 18 | # Ignore all PNG files: 19 | **/*.png 20 | **/*.xlsx 21 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | 2 | Most of the files are 3 | 4 | Copyright (c) 2004-2015 Odoo S.A. 5 | 6 | Many files also contain contributions from third 7 | parties. In this case the original copyright of 8 | the contributions can be traced through the 9 | history of the source version control system. 10 | 11 | When that is not the case, the files contain a prominent 12 | notice stating the original copyright and applicable 13 | license, or come with their own dedicated COPYRIGHT 14 | and/or LICENSE file. 15 | 16 | -------------------------------------------------------------------------------- /demo/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/odoo/o-spreadsheet/bef1e2bd5da8a72feada65405a2fb2cf782d4ab3/demo/favicon.png -------------------------------------------------------------------------------- /demo/file_store.js: -------------------------------------------------------------------------------- 1 | export class FileStore { 2 | serverUrl = "http://localhost:9090/upload-image"; 3 | 4 | /** 5 | * Upload a file to the server to be saved. Returns the path of the file 6 | */ 7 | async upload(file) { 8 | const fd = new FormData(); 9 | fd.append("image", file /*, optional filename */); 10 | const res = await fetch(this.serverUrl, { 11 | method: "POST", 12 | body: fd, 13 | }); 14 | if (res.ok) { 15 | return await res.text(); 16 | } else { 17 | throw new Error(res.statusText); 18 | } 19 | } 20 | 21 | async delete(path) { 22 | console.warn("cannot delete file. Not implemented"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |6 | 7 | hello 8 | 9 |
10 |16 | 17 | hello 18 | 19 | 20 | test 21 | 22 |
23 |29 | 30 | hello 31 | 32 | 33 | test 34 | 35 |
36 |42 | 43 | hello 44 | 45 |
46 |