diff --git a/src/collaborative/ot/ot_specific.ts b/src/collaborative/ot/ot_specific.ts index 78de393c38..502db59aa5 100644 --- a/src/collaborative/ot/ot_specific.ts +++ b/src/collaborative/ot/ot_specific.ts @@ -7,7 +7,7 @@ import { } from "../../helpers"; import { transformDefinition } from "../../helpers/figures/charts"; import { DEFAULT_TABLE_CONFIG } from "../../helpers/table_presets"; -import { otRegistry } from "../../registries"; +import { otRegistry } from "../../registries/ot_registry"; import { AddColumnsRowsCommand, AddMergeCommand, diff --git a/src/collaborative/session.ts b/src/collaborative/session.ts index f63f5616cd..3820a5400f 100644 --- a/src/collaborative/session.ts +++ b/src/collaborative/session.ts @@ -1,7 +1,7 @@ import { DEBOUNCE_TIME, DEFAULT_REVISION_ID, MESSAGE_VERSION } from "../constants"; -import { UuidGenerator } from "../helpers"; import { EventBus } from "../helpers/event_bus"; import { debounce, isDefined } from "../helpers/misc"; +import { UuidGenerator } from "../helpers/uuid"; import { SelectiveHistory as RevisionLog } from "../history/selective_history"; import { CoreCommand, HistoryChange, Lazy, UID, WorkbookData } from "../types"; import { @@ -41,6 +41,12 @@ export class Session extends EventBus { private debouncedMove: Session["move"]; private pendingMessages: StateUpdateMessage[] = []; + /** + * Stored position of the client, if session.move is called while the client is not in a session. + * Will be used to send the position to the server when the client joins. + */ + private awaitingClientPosition: ClientPosition | undefined; + private waitingAck: boolean = false; /** * Flag used to block all commands when an undo or redo is triggered, until @@ -155,6 +161,10 @@ export class Session extends EventBus { this.clientId = "local"; } this.transportService.onNewMessage(this.clientId, this.onMessageReceived.bind(this)); + if (this.awaitingClientPosition) { + this._move(this.awaitingClientPosition); + this.awaitingClientPosition = undefined; + } } loadInitialMessages(messages: StateUpdateMessage[]) { @@ -237,9 +247,11 @@ export class Session extends EventBus { } private _move(position: ClientPosition) { - // this method is debounced and might be called after the client - // left the session. - if (!this.clients[this.clientId]) return; + // this method could be called before the client joins the session, or after he left (because of the debounce) + if (!this.clients[this.clientId]) { + this.awaitingClientPosition = position; + return; + } const currentPosition = this.clients[this.clientId]?.position; if ( currentPosition?.col === position.col && diff --git a/src/components/bottom_bar/bottom_bar_sheet/bottom_bar_sheet.ts b/src/components/bottom_bar/bottom_bar_sheet/bottom_bar_sheet.ts index d313dcc00c..feb396e091 100644 --- a/src/components/bottom_bar/bottom_bar_sheet/bottom_bar_sheet.ts +++ b/src/components/bottom_bar/bottom_bar_sheet/bottom_bar_sheet.ts @@ -1,8 +1,8 @@ import { Component, onPatched, useEffect, useExternalListener, useRef, useState } from "@odoo/owl"; import { ACTION_COLOR, BOTTOMBAR_HEIGHT } from "../../../constants"; import { interactiveRenameSheet } from "../../../helpers/ui/sheet_interactive"; -import { getSheetMenuRegistry } from "../../../registries"; import { MenuItemRegistry } from "../../../registries/menu_items_registry"; +import { getSheetMenuRegistry } from "../../../registries/menus"; import { Store, useStore } from "../../../store_engine"; import { DOMFocusableElementStore } from "../../../stores/DOM_focus_store"; import { Rect, SpreadsheetChildEnv } from "../../../types"; diff --git a/src/components/composer/autocomplete_dropdown/autocomplete_dropdown.ts b/src/components/composer/autocomplete_dropdown/autocomplete_dropdown.ts index 8e3d589eea..6e1c6403ca 100644 --- a/src/components/composer/autocomplete_dropdown/autocomplete_dropdown.ts +++ b/src/components/composer/autocomplete_dropdown/autocomplete_dropdown.ts @@ -1,5 +1,5 @@ import { Component, useEffect, useRef } from "@odoo/owl"; -import { AutoCompleteProposal } from "../../../registries"; +import { AutoCompleteProposal } from "../../../registries/auto_completes"; import { css } from "../../helpers/css"; css/* scss */ ` diff --git a/src/components/composer/autocomplete_dropdown/autocomplete_dropdown_store.ts b/src/components/composer/autocomplete_dropdown/autocomplete_dropdown_store.ts index 41cd6c68f9..15abc2a3fd 100644 --- a/src/components/composer/autocomplete_dropdown/autocomplete_dropdown_store.ts +++ b/src/components/composer/autocomplete_dropdown/autocomplete_dropdown_store.ts @@ -1,4 +1,4 @@ -import { AutoCompleteProposal, AutoCompleteProvider } from "../../../registries"; +import { AutoCompleteProposal, AutoCompleteProvider } from "../../../registries/auto_completes"; import { SpreadsheetStore } from "../../../stores"; export class AutoCompleteStore extends SpreadsheetStore { diff --git a/src/components/composer/standalone_composer/standalone_composer.ts b/src/components/composer/standalone_composer/standalone_composer.ts index 31fed08eea..a0f76c2c7a 100644 --- a/src/components/composer/standalone_composer/standalone_composer.ts +++ b/src/components/composer/standalone_composer/standalone_composer.ts @@ -1,7 +1,7 @@ import { Component } from "@odoo/owl"; import { ACTION_COLOR, GRAY_300 } from "../../../constants"; import { Token } from "../../../formulas"; -import { AutoCompleteProviderDefinition } from "../../../registries"; +import { AutoCompleteProviderDefinition } from "../../../registries/auto_completes"; import { Store, useLocalStore, useStore } from "../../../store_engine"; import { Color, ComposerFocusType, SpreadsheetChildEnv, UID } from "../../../types/index"; import { css, cssPropertiesToCss } from "../../helpers/css"; diff --git a/src/components/composer/standalone_composer/standalone_composer_store.ts b/src/components/composer/standalone_composer/standalone_composer_store.ts index 5ce548a301..2e9c7db7d6 100644 --- a/src/components/composer/standalone_composer/standalone_composer_store.ts +++ b/src/components/composer/standalone_composer/standalone_composer_store.ts @@ -1,7 +1,7 @@ import { Token, rangeTokenize } from "../../../formulas"; import { EnrichedToken } from "../../../formulas/composer_tokenizer"; import { setXcToFixedReferenceType } from "../../../helpers/reference_type"; -import { AutoCompleteProviderDefinition } from "../../../registries"; +import { AutoCompleteProviderDefinition } from "../../../registries/auto_completes"; import { Get } from "../../../store_engine"; import { Color, UID, UnboundedZone, Zone } from "../../../types"; import { AbstractComposerStore } from "../composer/abstract_composer_store"; diff --git a/src/components/figures/figure/figure.ts b/src/components/figures/figure/figure.ts index ebe1366c83..da6a91edbe 100644 --- a/src/components/figures/figure/figure.ts +++ b/src/components/figures/figure/figure.ts @@ -4,7 +4,7 @@ import { FIGURE_BORDER_COLOR, SELECTION_BORDER_COLOR, } from "../../../constants"; -import { figureRegistry } from "../../../registries/index"; +import { figureRegistry } from "../../../registries/figure_registry"; import { AnchorOffset, CSSProperties, diff --git a/src/components/figures/figure_container/figure_container.ts b/src/components/figures/figure_container/figure_container.ts index 65cc1f2008..6a23f50065 100644 --- a/src/components/figures/figure_container/figure_container.ts +++ b/src/components/figures/figure_container/figure_container.ts @@ -2,7 +2,7 @@ import { Component, onMounted, onWillUpdateProps, useState } from "@odoo/owl"; import { ComponentsImportance, MIN_FIG_SIZE } from "../../../constants"; import { isDefined } from "../../../helpers"; import { rectUnion } from "../../../helpers/rectangle"; -import { figureRegistry } from "../../../registries"; +import { figureRegistry } from "../../../registries/figure_registry"; import { AnchorOffset, Figure, diff --git a/src/components/side_panel/pivot/pivot_layout_configurator/add_dimension_button/add_dimension_button.ts b/src/components/side_panel/pivot/pivot_layout_configurator/add_dimension_button/add_dimension_button.ts index a365fa14df..a1a1f4a9dc 100644 --- a/src/components/side_panel/pivot/pivot_layout_configurator/add_dimension_button/add_dimension_button.ts +++ b/src/components/side_panel/pivot/pivot_layout_configurator/add_dimension_button/add_dimension_button.ts @@ -1,7 +1,10 @@ import { Component, useExternalListener, useRef, useState } from "@odoo/owl"; import { COMPOSER_ASSISTANT_COLOR } from "../../../../../constants"; import { fuzzyLookup } from "../../../../../helpers"; -import { AutoCompleteProposal, AutoCompleteProvider } from "../../../../../registries"; +import { + AutoCompleteProposal, + AutoCompleteProvider, +} from "../../../../../registries/auto_completes"; import { Store, useLocalStore } from "../../../../../store_engine"; import { SpreadsheetChildEnv } from "../../../../../types"; import { PivotField } from "../../../../../types/pivot"; diff --git a/src/components/top_bar/number_formats_tool/number_formats_tool.ts b/src/components/top_bar/number_formats_tool/number_formats_tool.ts index b5d7b379b2..c114587452 100644 --- a/src/components/top_bar/number_formats_tool/number_formats_tool.ts +++ b/src/components/top_bar/number_formats_tool/number_formats_tool.ts @@ -1,6 +1,6 @@ import { Component, useRef, useState } from "@odoo/owl"; import { Action, createAction } from "../../../actions/action"; -import { formatNumberMenuItemSpec } from "../../../registries"; +import { formatNumberMenuItemSpec } from "../../../registries/menus"; import { Rect, SpreadsheetChildEnv } from "../../../types"; import { ActionButton } from "../../action_button/action_button"; import { getBoundingRectAsPOJO } from "../../helpers/dom_helpers"; diff --git a/src/components/top_bar/top_bar.ts b/src/components/top_bar/top_bar.ts index 6d7451f87a..5c867ac0bc 100644 --- a/src/components/top_bar/top_bar.ts +++ b/src/components/top_bar/top_bar.ts @@ -18,8 +18,9 @@ import { SEPARATOR_COLOR, TOPBAR_TOOLBAR_HEIGHT, } from "../../constants"; -import { formatNumberMenuItemSpec, topbarComponentRegistry } from "../../registries/index"; +import { formatNumberMenuItemSpec } from "../../registries/menus"; import { topbarMenuRegistry } from "../../registries/menus/topbar_menu_registry"; +import { topbarComponentRegistry } from "../../registries/topbar_component_registry"; import { Store, useStore } from "../../store_engine"; import { FormulaFingerprintStore } from "../../stores/formula_fingerprints_store"; import { Color, Pixel, SpreadsheetChildEnv } from "../../types/index"; diff --git a/src/index.ts b/src/index.ts index 06d0bbf989..2ee2832aaa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -153,33 +153,35 @@ import { statefulUIPluginRegistry, } from "./plugins/index"; import { UNDO_REDO_PIVOT_COMMANDS } from "./plugins/ui_core_views/pivot_ui"; +import { autoCompleteProviders } from "./registries/auto_completes"; +import { autofillModifiersRegistry } from "./registries/autofill_modifiers"; +import { autofillRulesRegistry } from "./registries/autofill_rules"; import { clickableCellRegistry } from "./registries/cell_clickable_registry"; -import { iconsOnCellRegistry } from "./registries/icons_on_cell_registry"; +import { cellPopoverRegistry } from "./registries/cell_popovers_registry"; import { - autoCompleteProviders, - autofillModifiersRegistry, - autofillRulesRegistry, - cellMenuRegistry, - cellPopoverRegistry, chartComponentRegistry, chartRegistry, chartSubtypeRegistry, +} from "./registries/chart_types"; +import { figureRegistry } from "./registries/figure_registry"; +import { iconsOnCellRegistry } from "./registries/icons_on_cell_registry"; +import { inverseCommandRegistry } from "./registries/inverse_command_registry"; +import { + cellMenuRegistry, colMenuRegistry, - figureRegistry, - inverseCommandRegistry, linkMenuRegistry, numberFormatMenuRegistry, - otRegistry, rowMenuRegistry, - topbarComponentRegistry, topbarMenuRegistry, -} from "./registries/index"; +} from "./registries/menus"; +import { otRegistry } from "./registries/ot_registry"; import { genericRepeat, repeatCommandTransformRegistry, repeatLocalCommandTransformRegistry, } from "./registries/repeat_commands_registry"; import { sidePanelRegistry } from "./registries/side_panel_registry"; +import { topbarComponentRegistry } from "./registries/topbar_component_registry"; import { useLocalStore, useStore, useStoreProvider } from "./store_engine"; import { DependencyContainer } from "./store_engine/dependency_container"; import { SpreadsheetStore } from "./stores"; diff --git a/src/plugins/ui_feature/autofill.ts b/src/plugins/ui_feature/autofill.ts index cfa41970aa..8bebfbcd0d 100644 --- a/src/plugins/ui_feature/autofill.ts +++ b/src/plugins/ui_feature/autofill.ts @@ -7,7 +7,8 @@ import { toXC, toZone, } from "../../helpers/index"; -import { autofillModifiersRegistry, autofillRulesRegistry } from "../../registries/index"; +import { autofillModifiersRegistry } from "../../registries/autofill_modifiers"; +import { autofillRulesRegistry } from "../../registries/autofill_rules"; import { AutoFillCellCommand, AutofillData, diff --git a/src/registries/index.ts b/src/registries/index.ts deleted file mode 100644 index d60d385e4d..0000000000 --- a/src/registries/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -export * from "./auto_completes/index"; -export * from "./autofill_modifiers"; -export * from "./autofill_rules"; -export * from "./cell_popovers_registry"; -export * from "./chart_types"; -export * from "./currencies_registry"; -export * from "./figure_registry"; -export * from "./inverse_command_registry"; -export * from "./menus/index"; -export * from "./ot_registry"; -export * from "./side_panel_registry_entries"; -export * from "./topbar_component_registry"; diff --git a/src/registries/side_panel_registry.ts b/src/registries/side_panel_registry.ts index 193c444e6a..5bc06a225d 100644 --- a/src/registries/side_panel_registry.ts +++ b/src/registries/side_panel_registry.ts @@ -1,5 +1,24 @@ +import { ChartPanel } from "../components/side_panel/chart/main_chart_panel/main_chart_panel"; +import { ConditionalFormattingPanel } from "../components/side_panel/conditional_formatting/conditional_formatting"; +import { CustomCurrencyPanel } from "../components/side_panel/custom_currency/custom_currency"; +import { DataValidationPanel } from "../components/side_panel/data_validation/data_validation_panel"; +import { DataValidationEditor } from "../components/side_panel/data_validation/dv_editor/dv_editor"; +import { FindAndReplacePanel } from "../components/side_panel/find_and_replace/find_and_replace"; +import { MoreFormatsPanel } from "../components/side_panel/more_formats/more_formats"; +import { PivotMeasureDisplayPanel } from "../components/side_panel/pivot/pivot_measure_display_panel/pivot_measure_display_panel"; +import { PivotSidePanel } from "../components/side_panel/pivot/pivot_side_panel/pivot_side_panel"; +import { RemoveDuplicatesPanel } from "../components/side_panel/remove_duplicates/remove_duplicates"; +import { SettingsPanel } from "../components/side_panel/settings/settings_panel"; import { SidePanelState } from "../components/side_panel/side_panel/side_panel_store"; -import { Getters, SpreadsheetChildEnv } from "../types"; +import { SplitIntoColumnsPanel } from "../components/side_panel/split_to_columns_panel/split_to_columns_panel"; +import { TablePanel } from "../components/side_panel/table_panel/table_panel"; +import { + TableStyleEditorPanel, + TableStyleEditorPanelProps, +} from "../components/side_panel/table_style_editor_panel/table_style_editor_panel"; +import { getTableTopLeft } from "../helpers/table_helpers"; +import { _t } from "../translation"; +import { Getters, SpreadsheetChildEnv, UID } from "../types"; import { Registry } from "./registry"; //------------------------------------------------------------------------------ @@ -18,3 +37,117 @@ export interface SidePanelContent { } export const sidePanelRegistry = new Registry(); + +sidePanelRegistry.add("ConditionalFormatting", { + title: _t("Conditional formatting"), + Body: ConditionalFormattingPanel, +}); + +sidePanelRegistry.add("ChartPanel", { + title: _t("Chart"), + Body: ChartPanel, + computeState: (getters: Getters, initialProps: { figureId: UID }) => { + const figureId = getters.getSelectedFigureId() ?? initialProps.figureId; + if (!getters.isChartDefined(figureId)) { + return { isOpen: false }; + } + return { isOpen: true, props: { figureId } }; + }, +}); + +sidePanelRegistry.add("FindAndReplace", { + title: _t("Find and Replace"), + Body: FindAndReplacePanel, +}); + +sidePanelRegistry.add("CustomCurrency", { + title: _t("Custom currency format"), + Body: CustomCurrencyPanel, +}); + +sidePanelRegistry.add("SplitToColumns", { + title: _t("Split text into columns"), + Body: SplitIntoColumnsPanel, +}); + +sidePanelRegistry.add("Settings", { + title: _t("Spreadsheet settings"), + Body: SettingsPanel, +}); + +sidePanelRegistry.add("RemoveDuplicates", { + title: _t("Remove duplicates"), + Body: RemoveDuplicatesPanel, +}); + +sidePanelRegistry.add("DataValidation", { + title: _t("Data validation"), + Body: DataValidationPanel, +}); + +sidePanelRegistry.add("DataValidationEditor", { + title: _t("Data validation"), + Body: DataValidationEditor, +}); + +sidePanelRegistry.add("MoreFormats", { + title: _t("More date formats"), + Body: MoreFormatsPanel, +}); + +sidePanelRegistry.add("TableSidePanel", { + title: _t("Edit table"), + Body: TablePanel, + computeState: (getters: Getters) => { + const table = getters.getFirstTableInSelection(); + if (!table) { + return { isOpen: false }; + } + + const coreTable = getters.getCoreTable(getTableTopLeft(table)); + return { isOpen: true, props: { table: coreTable }, key: table.id }; + }, +}); + +sidePanelRegistry.add("TableStyleEditorPanel", { + title: _t("Create custom table style"), + Body: TableStyleEditorPanel, + computeState: (getters: Getters, initialProps: TableStyleEditorPanelProps) => { + return { + isOpen: true, + props: { ...initialProps }, + key: initialProps.styleId ?? "new", + }; + }, +}); + +sidePanelRegistry.add("PivotSidePanel", { + title: (env: SpreadsheetChildEnv, props: { pivotId: UID }) => { + return _t("Pivot #%s", env.model.getters.getPivotFormulaId(props.pivotId)); + }, + Body: PivotSidePanel, + computeState: (getters: Getters, props: { pivotId: UID }) => { + return { + isOpen: getters.isExistingPivot(props.pivotId), + props, + key: `pivot_key_${props.pivotId}`, + }; + }, +}); + +sidePanelRegistry.add("PivotMeasureDisplayPanel", { + title: (env: SpreadsheetChildEnv, props: PivotMeasureDisplayPanel["props"]) => { + const measure = env.model.getters.getPivot(props.pivotId).getMeasure(props.measure.id); + return _t('Measure "%s" options', measure.displayName); + }, + Body: PivotMeasureDisplayPanel, + computeState: (getters: Getters, props: PivotMeasureDisplayPanel["props"]) => { + try { + // This will throw if the pivot or measure does not exist + getters.getPivot(props.pivotId).getMeasure(props.measure.id); + return { isOpen: true, props, key: "pivot_measure_display" }; + } catch (e) { + return { isOpen: false }; + } + }, +}); diff --git a/src/registries/side_panel_registry_entries.ts b/src/registries/side_panel_registry_entries.ts deleted file mode 100644 index 0610435ae7..0000000000 --- a/src/registries/side_panel_registry_entries.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { ChartPanel } from "../components/side_panel/chart/main_chart_panel/main_chart_panel"; -import { ConditionalFormattingPanel } from "../components/side_panel/conditional_formatting/conditional_formatting"; -import { CustomCurrencyPanel } from "../components/side_panel/custom_currency/custom_currency"; -import { DataValidationPanel } from "../components/side_panel/data_validation/data_validation_panel"; -import { DataValidationEditor } from "../components/side_panel/data_validation/dv_editor/dv_editor"; -import { FindAndReplacePanel } from "../components/side_panel/find_and_replace/find_and_replace"; -import { MoreFormatsPanel } from "../components/side_panel/more_formats/more_formats"; -import { PivotMeasureDisplayPanel } from "../components/side_panel/pivot/pivot_measure_display_panel/pivot_measure_display_panel"; -import { PivotSidePanel } from "../components/side_panel/pivot/pivot_side_panel/pivot_side_panel"; -import { RemoveDuplicatesPanel } from "../components/side_panel/remove_duplicates/remove_duplicates"; -import { SettingsPanel } from "../components/side_panel/settings/settings_panel"; -import { SplitIntoColumnsPanel } from "../components/side_panel/split_to_columns_panel/split_to_columns_panel"; -import { TablePanel } from "../components/side_panel/table_panel/table_panel"; -import { - TableStyleEditorPanel, - TableStyleEditorPanelProps, -} from "../components/side_panel/table_style_editor_panel/table_style_editor_panel"; -import { getTableTopLeft } from "../helpers/table_helpers"; -import { _t } from "../translation"; -import { Getters, SpreadsheetChildEnv, UID } from "../types"; -import { sidePanelRegistry } from "./side_panel_registry"; - -//------------------------------------------------------------------------------ -// Side Panel Registry -//------------------------------------------------------------------------------ - -sidePanelRegistry.add("ConditionalFormatting", { - title: _t("Conditional formatting"), - Body: ConditionalFormattingPanel, -}); - -sidePanelRegistry.add("ChartPanel", { - title: _t("Chart"), - Body: ChartPanel, - computeState: (getters: Getters, initialProps: { figureId: UID }) => { - const figureId = getters.getSelectedFigureId() ?? initialProps.figureId; - if (!getters.isChartDefined(figureId)) { - return { isOpen: false }; - } - return { isOpen: true, props: { figureId } }; - }, -}); - -sidePanelRegistry.add("FindAndReplace", { - title: _t("Find and Replace"), - Body: FindAndReplacePanel, -}); - -sidePanelRegistry.add("CustomCurrency", { - title: _t("Custom currency format"), - Body: CustomCurrencyPanel, -}); - -sidePanelRegistry.add("SplitToColumns", { - title: _t("Split text into columns"), - Body: SplitIntoColumnsPanel, -}); - -sidePanelRegistry.add("Settings", { - title: _t("Spreadsheet settings"), - Body: SettingsPanel, -}); - -sidePanelRegistry.add("RemoveDuplicates", { - title: _t("Remove duplicates"), - Body: RemoveDuplicatesPanel, -}); - -sidePanelRegistry.add("DataValidation", { - title: _t("Data validation"), - Body: DataValidationPanel, -}); - -sidePanelRegistry.add("DataValidationEditor", { - title: _t("Data validation"), - Body: DataValidationEditor, -}); - -sidePanelRegistry.add("MoreFormats", { - title: _t("More date formats"), - Body: MoreFormatsPanel, -}); - -sidePanelRegistry.add("TableSidePanel", { - title: _t("Edit table"), - Body: TablePanel, - computeState: (getters: Getters) => { - const table = getters.getFirstTableInSelection(); - if (!table) { - return { isOpen: false }; - } - - const coreTable = getters.getCoreTable(getTableTopLeft(table)); - return { isOpen: true, props: { table: coreTable }, key: table.id }; - }, -}); - -sidePanelRegistry.add("TableStyleEditorPanel", { - title: _t("Create custom table style"), - Body: TableStyleEditorPanel, - computeState: (getters: Getters, initialProps: TableStyleEditorPanelProps) => { - return { - isOpen: true, - props: { ...initialProps }, - key: initialProps.styleId ?? "new", - }; - }, -}); - -sidePanelRegistry.add("PivotSidePanel", { - title: (env: SpreadsheetChildEnv, props: { pivotId: UID }) => { - return _t("Pivot #%s", env.model.getters.getPivotFormulaId(props.pivotId)); - }, - Body: PivotSidePanel, - computeState: (getters: Getters, props: { pivotId: UID }) => { - return { - isOpen: getters.isExistingPivot(props.pivotId), - props, - key: `pivot_key_${props.pivotId}`, - }; - }, -}); - -sidePanelRegistry.add("PivotMeasureDisplayPanel", { - title: (env: SpreadsheetChildEnv, props: PivotMeasureDisplayPanel["props"]) => { - const measure = env.model.getters.getPivot(props.pivotId).getMeasure(props.measure.id); - return _t('Measure "%s" options', measure.displayName); - }, - Body: PivotMeasureDisplayPanel, - computeState: (getters: Getters, props: PivotMeasureDisplayPanel["props"]) => { - try { - // This will throw if the pivot or measure does not exist - getters.getPivot(props.pivotId).getMeasure(props.measure.id); - return { isOpen: true, props, key: "pivot_measure_display" }; - } catch (e) { - return { isOpen: false }; - } - }, -}); diff --git a/tests/collaborative/collaborative_session.test.ts b/tests/collaborative/collaborative_session.test.ts index a6678a0b27..6acb25715c 100644 --- a/tests/collaborative/collaborative_session.test.ts +++ b/tests/collaborative/collaborative_session.test.ts @@ -5,6 +5,7 @@ import { lazy } from "../../src/helpers"; import { buildRevisionLog } from "../../src/history/factory"; import { Client, CommandResult, WorkbookData } from "../../src/types"; import { MockTransportService } from "../__mocks__/transport_service"; +import { unPatchSessionMove } from "../setup/session_debounce_mock"; import { selectCell, setCellContent } from "../test_helpers/commands_helpers"; import { nextTick } from "../test_helpers/helpers"; @@ -31,6 +32,7 @@ describe("Collaborative session", () => { }); test("local client move", () => { + unPatchSessionMove(); session.move({ sheetId: "sheetId", col: 0, row: 0 }); jest.advanceTimersByTime(DEBOUNCE_TIME + 100); const spy = jest.spyOn(transport, "sendMessage"); diff --git a/tests/composer/autocomplete_dropdown_component.test.ts b/tests/composer/autocomplete_dropdown_component.test.ts index 37c8c0cdd3..05270623ad 100644 --- a/tests/composer/autocomplete_dropdown_component.test.ts +++ b/tests/composer/autocomplete_dropdown_component.test.ts @@ -3,7 +3,7 @@ import { CellComposerStore } from "../../src/components/composer/composer/cell_c import { DEFAULT_CELL_HEIGHT, DEFAULT_CELL_WIDTH } from "../../src/constants"; import { functionRegistry } from "../../src/functions/index"; import { Model } from "../../src/model"; -import { autoCompleteProviders } from "../../src/registries"; +import { autoCompleteProviders } from "../../src/registries/auto_completes"; import { Store } from "../../src/store_engine"; import { selectCell } from "../test_helpers/commands_helpers"; import { diff --git a/tests/figures/figure_component.test.ts b/tests/figures/figure_component.test.ts index f86da81fbf..d4b45d9d0c 100644 --- a/tests/figures/figure_component.test.ts +++ b/tests/figures/figure_component.test.ts @@ -8,11 +8,11 @@ import { MENU_WIDTH, SELECTION_BORDER_COLOR, } from "../../src/constants"; -import { figureRegistry } from "../../src/registries"; import { Figure, Pixel, Position, SpreadsheetChildEnv, UID } from "../../src/types"; import { FigureComponent } from "../../src/components/figures/figure/figure"; import { downloadFile } from "../../src/components/helpers/dom_helpers"; +import { figureRegistry } from "../../src/registries/figure_registry"; import { ClipboardMIMEType } from "../../src/types/clipboard"; import { activateSheet, diff --git a/tests/menus/menu_items_registry.test.ts b/tests/menus/menu_items_registry.test.ts index 2e431e4e50..9ff63fa4c0 100644 --- a/tests/menus/menu_items_registry.test.ts +++ b/tests/menus/menu_items_registry.test.ts @@ -1,10 +1,4 @@ import { toUnboundedZone, toZone, zoneToXc } from "../../src/helpers"; -import { - cellMenuRegistry, - colMenuRegistry, - rowMenuRegistry, - topbarMenuRegistry, -} from "../../src/registries/index"; import { SpreadsheetChildEnv, UID } from "../../src/types"; import { copy, @@ -56,6 +50,12 @@ import { FONT_SIZES } from "../../src/constants"; import { functionRegistry } from "../../src/functions"; import { interactivePaste } from "../../src/helpers/ui/paste_interactive"; import { MenuItemRegistry } from "../../src/registries/menu_items_registry"; +import { + cellMenuRegistry, + colMenuRegistry, + rowMenuRegistry, + topbarMenuRegistry, +} from "../../src/registries/menus"; import { DEFAULT_LOCALES } from "../../src/types/locale"; import { FR_LOCALE } from "../test_helpers/constants"; diff --git a/tests/model/model.test.ts b/tests/model/model.test.ts index ad1a6a2dbe..308cb101c8 100644 --- a/tests/model/model.test.ts +++ b/tests/model/model.test.ts @@ -1,4 +1,4 @@ -import { CommandResult, CorePlugin } from "../../src"; +import { CollaborationMessage, CommandResult, CorePlugin } from "../../src"; import { MESSAGE_VERSION } from "../../src/constants"; import { toZone } from "../../src/helpers"; import { Model, ModelConfig } from "../../src/model"; @@ -388,14 +388,15 @@ describe("Model", () => { }); test("it should not snapshot when importing xlsx file in readonly mode", async () => { + const messages: CollaborationMessage[] = []; const transport = new MockTransportService(); - const spy = jest.spyOn(transport, "sendMessage"); + transport.onNewMessage("listener", (message) => messages.push(message)); const xlsxData = await getTextXlsxFiles(); new Model(xlsxData, { transportService: transport, client: { id: "test", name: "Test" }, mode: "readonly", }); - expect(spy).not.toHaveBeenCalled(); + expect(messages.map((m) => m.type)).not.toContain("SNAPSHOT_CREATED"); }); }); diff --git a/tests/pivots/pivot_menu_items.test.ts b/tests/pivots/pivot_menu_items.test.ts index aad4bf84fb..b3fd58ecb7 100644 --- a/tests/pivots/pivot_menu_items.test.ts +++ b/tests/pivots/pivot_menu_items.test.ts @@ -2,7 +2,7 @@ import { Model, SortDirection, SpreadsheetChildEnv } from "../../src"; import { Action } from "../../src/actions/action"; import { PIVOT_TABLE_CONFIG } from "../../src/constants"; import { toCartesian, toZone } from "../../src/helpers"; -import { cellMenuRegistry, topbarMenuRegistry } from "../../src/registries"; +import { cellMenuRegistry, topbarMenuRegistry } from "../../src/registries/menus"; import { createSheet, createTable, diff --git a/tests/pivots/spreadsheet_pivot/spreadsheet_pivot_side_panel.test.ts b/tests/pivots/spreadsheet_pivot/spreadsheet_pivot_side_panel.test.ts index 231a9306cc..b9c47aa888 100644 --- a/tests/pivots/spreadsheet_pivot/spreadsheet_pivot_side_panel.test.ts +++ b/tests/pivots/spreadsheet_pivot/spreadsheet_pivot_side_panel.test.ts @@ -2,7 +2,7 @@ import { Model, PivotSortedColumn, SpreadsheetChildEnv } from "../../../src"; import { PIVOT_TABLE_CONFIG, PIVOT_TOKEN_COLOR } from "../../../src/constants"; import { toXC, toZone } from "../../../src/helpers"; import { SpreadsheetPivot } from "../../../src/helpers/pivot/spreadsheet_pivot/spreadsheet_pivot"; -import { topbarMenuRegistry } from "../../../src/registries"; +import { topbarMenuRegistry } from "../../../src/registries/menus"; import { NotificationStore } from "../../../src/stores/notification_store"; import { activateSheet, diff --git a/tests/setup/jest.setup.ts b/tests/setup/jest.setup.ts index c9a5c79ff3..96888a522d 100644 --- a/tests/setup/jest.setup.ts +++ b/tests/setup/jest.setup.ts @@ -10,6 +10,7 @@ import "./jest_extend"; import "./polyfill"; import "./resize_observer.mock"; import { Resizers } from "./resize_observer.mock"; +import { patchSessionMove } from "./session_debounce_mock"; window.Chart = Object.assign(Chart.Chart, Chart); @@ -67,6 +68,7 @@ beforeEach(() => { const blob = new window.Blob([data], { type }); setTimeout(() => callback(blob), 0); }); + patchSessionMove(); }); afterEach(() => { diff --git a/tests/setup/session_debounce_mock.ts b/tests/setup/session_debounce_mock.ts new file mode 100644 index 0000000000..59c6fbdf72 --- /dev/null +++ b/tests/setup/session_debounce_mock.ts @@ -0,0 +1,22 @@ +import { ClientPosition } from "../../src"; +import { Session } from "../../src/collaborative/session"; + +const originalSessionMove = Session.prototype.move; + +/** + * Patch the `session.move` method to remove debounce. + * This is useful for testing purposes, to ensure that there aren't indeterministic test because a render + * happens in the middle of the test when the debounce is executed. + */ +export function patchSessionMove() { + Session.prototype.move = function (this: Session, position: ClientPosition) { + this["_move"](position); + }; +} + +/** + * Remove the patch on `session.move` method that remove debounce. + */ +export function unPatchSessionMove() { + Session.prototype.move = originalSessionMove; +} diff --git a/tests/spreadsheet/spreadsheet_component.test.ts b/tests/spreadsheet/spreadsheet_component.test.ts index 761fbbbca3..aefd57ae38 100644 --- a/tests/spreadsheet/spreadsheet_component.test.ts +++ b/tests/spreadsheet/spreadsheet_component.test.ts @@ -8,6 +8,7 @@ import { functionRegistry } from "../../src/functions"; import { toZone } from "../../src/helpers"; import { HighlightStore } from "../../src/stores/highlight_store"; import { SpreadsheetChildEnv } from "../../src/types"; +import { unPatchSessionMove } from "../setup/session_debounce_mock"; import { addRows, createChart, @@ -247,6 +248,7 @@ describe("Simple Spreadsheet Component", () => { }); test("Can instantiate a spreadsheet with a given client id-name", async () => { + unPatchSessionMove(); const client = { id: "alice", name: "Alice" }; ({ model } = await mountSpreadsheet({ model: new Model({}, { client }) })); expect(model.getters.getClient()).toEqual(client); diff --git a/tests/test_helpers/helpers.ts b/tests/test_helpers/helpers.ts index 013256aa01..d8f5cf48c4 100644 --- a/tests/test_helpers/helpers.ts +++ b/tests/test_helpers/helpers.ts @@ -29,8 +29,8 @@ import { MergePlugin } from "../../src/plugins/core/merge"; import { CorePluginConstructor } from "../../src/plugins/core_plugin"; import { SheetUIPlugin } from "../../src/plugins/ui_feature"; import { UIPluginConstructor } from "../../src/plugins/ui_plugin"; -import { topbarMenuRegistry } from "../../src/registries"; import { MenuItemRegistry } from "../../src/registries/menu_items_registry"; +import { topbarMenuRegistry } from "../../src/registries/menus"; import { Registry } from "../../src/registries/registry"; import { DependencyContainer, diff --git a/tests/top_bar_component.test.ts b/tests/top_bar_component.test.ts index 78fa87d7cc..f347281def 100644 --- a/tests/top_bar_component.test.ts +++ b/tests/top_bar_component.test.ts @@ -6,7 +6,8 @@ import { TopBar } from "../src/components/top_bar/top_bar"; import { topBarToolBarRegistry } from "../src/components/top_bar/top_bar_tools_registry"; import { DEBOUNCE_TIME, DEFAULT_FONT_SIZE } from "../src/constants"; import { toZone, zoneToXc } from "../src/helpers"; -import { topbarComponentRegistry, topbarMenuRegistry } from "../src/registries"; +import { topbarMenuRegistry } from "../src/registries/menus"; +import { topbarComponentRegistry } from "../src/registries/topbar_component_registry"; import { ConditionalFormat, Currency, Pixel, SpreadsheetChildEnv, Style } from "../src/types"; import { FileStore } from "./__mocks__/mock_file_store"; import { MockTransportService } from "./__mocks__/transport_service";