Skip to content

Commit 0acb3d4

Browse files
committed
[IMP] Allows sorting filter menu in readonly mode
Sorting a table should be possible even in readonly mode Task: 6047484
1 parent de5d244 commit 0acb3d4

15 files changed

Lines changed: 53 additions & 80 deletions

File tree

doc/extending/command.md

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,7 @@ coreTypes.add("MY_COMMAND_NAME");
4242

4343
### Read-Only Mode
4444

45-
In read-only mode, all core commands are cancelled with the `CommandResult` `Readonly` since the spreadsheet state cannot be modified.
46-
However, some locale commands still need to be executed, such as updating the active sheet.
47-
To allow a new local command in read-only mode, add its type to `readonlyAllowedCommands`:
48-
49-
```ts
50-
import { readonlyAllowedCommands } from "@odoo/o-spreadsheet";
51-
52-
readonlyAllowedCommands.add("MY_COMMAND_NAME");
53-
```
45+
All commands are allowed in readonly mode. Since the spreadsheet state cannot be modified , we use a specific transport service (ReadonlyTransportFilter) blocking revision to be send to the server.
5446

5547
## Reserved keywords in commands
5648

src/components/figures/figure_carousel/figure_carousel.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ export class CarouselFigure extends Component<Props, SpreadsheetChildEnv> {
8484
}
8585

8686
onCarouselDoubleClick() {
87+
if (this.env.model.getters.isReadonly()) {
88+
return;
89+
}
8790
this.env.model.dispatch("SELECT_FIGURE", { figureId: this.props.figureUI.id });
8891
this.env.openSidePanel("CarouselPanel", { figureId: this.props.figureUI.id });
8992
}

src/components/figures/figure_chart/figure_chart.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ export class ChartFigure extends Component<Props, SpreadsheetChildEnv> {
2424
static components = { ChartDashboardMenu };
2525

2626
onDoubleClick() {
27+
if (this.env.model.getters.isReadonly()) {
28+
return;
29+
}
2730
this.env.model.dispatch("SELECT_FIGURE", { figureId: this.props.figureUI.id });
2831
this.env.openSidePanel("ChartPanel");
2932
}

src/components/filters/filter_menu/filter_menu.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class FilterMenu extends Component<Props, SpreadsheetChildEnv> {
5353
this.table.range.sheetId,
5454
this.table.range.zone
5555
);
56-
return !this.env.model.getters.isReadonly() && coreTable?.type !== "dynamic";
56+
return coreTable?.type !== "dynamic";
5757
}
5858

5959
get table() {

src/components/grid/grid.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,28 @@ export class Grid extends Component<Props, SpreadsheetChildEnv> {
446446
"Alt+Shift+ArrowDown": () => this.processHeaderGroupingKey("down"),
447447
};
448448

449+
private readonlyAllowedShortcuts = new Set([
450+
"Tab",
451+
"Shift+Tab",
452+
"Escape",
453+
"Ctrl+A",
454+
"Ctrl+Z",
455+
"Ctrl+Y",
456+
"F4",
457+
"Alt+Enter",
458+
"Ctrl+Home",
459+
"Ctrl+End",
460+
"Shift+ ",
461+
"Ctrl+ ",
462+
"Ctrl+H",
463+
"Ctrl+F",
464+
"Ctrl+Shift+ ",
465+
"Alt+Shift+ArrowRight",
466+
"Alt+Shift+ArrowLeft",
467+
"Alt+Shift+ArrowUp",
468+
"Alt+Shift+ArrowDown",
469+
]);
470+
449471
private focusComposerFromActiveCell() {
450472
const cell = this.env.model.getters.getActiveCell();
451473
cell.type === CellValueType.empty
@@ -647,6 +669,9 @@ export class Grid extends Component<Props, SpreadsheetChildEnv> {
647669

648670
onKeydown(ev: KeyboardEvent) {
649671
const keyDownString = keyboardEventToShortcutString(ev);
672+
if (this.env.model.getters.isReadonly() && !this.readonlyAllowedShortcuts.has(keyDownString)) {
673+
return;
674+
}
650675
const handler = this.keyDownMapping[keyDownString];
651676
if (handler) {
652677
ev.preventDefault();

src/helpers/ui/sheet_interactive.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ export function interactiveRenameSheet(
99
name: string,
1010
errorCallback: () => void
1111
) {
12+
if (env.model.getters.isReadonly()) {
13+
return;
14+
}
1215
const result = env.model.dispatch("RENAME_SHEET", {
1316
sheetId,
1417
newName: name,

src/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,6 @@ export type {
260260
TransportService,
261261
} from "./types/collaborative/transport_service";
262262
export {
263-
canExecuteInReadonly,
264263
coreTypes,
265264
invalidateCFEvaluationCommands,
266265
invalidateChartEvaluationCommands,
@@ -269,7 +268,6 @@ export {
269268
isCoreCommand,
270269
isSheetDependent,
271270
lockedSheetAllowedCommands,
272-
readonlyAllowedCommands,
273271
} from "./types/commands";
274272
export { CellErrorType, EvaluationError } from "./types/errors";
275273

src/model.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import { StateObserver } from "./state_observer";
2929
import { _t, setDefaultTranslationMethod } from "./translation";
3030
import { StateUpdateMessage } from "./types/collaborative/transport_service";
3131
import {
32-
canExecuteInReadonly,
3332
Command,
3433
CommandDispatcher,
3534
CommandHandler,
@@ -516,9 +515,6 @@ export class Model extends EventBus<any> implements CommandDispatcher {
516515
dispatch: CommandDispatcher["dispatch"] = (type: CommandTypes, payload?: any) => {
517516
const command: Command = createCommand(type, payload);
518517
const status: Status = this.status;
519-
if (this.getters.isReadonly() && !canExecuteInReadonly(command)) {
520-
return new DispatchResult(CommandResult.Readonly);
521-
}
522518
if (!this.session.canApplyOptimisticUpdate()) {
523519
return new DispatchResult(CommandResult.WaitingSessionConfirmation);
524520
}

src/types/commands.ts

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -197,29 +197,6 @@ export const invalidSubtotalFormulasCommands = new Set<CommandTypes>([
197197
"UPDATE_FILTER",
198198
]);
199199

200-
export const readonlyAllowedCommands = new Set<CommandTypes>([
201-
"START",
202-
"ACTIVATE_SHEET",
203-
204-
"COPY",
205-
206-
"RESIZE_SHEETVIEW",
207-
"SET_VIEWPORT_OFFSET",
208-
"SET_ZOOM",
209-
210-
"EVALUATE_CELLS",
211-
"EVALUATE_CHARTS",
212-
213-
"SET_FORMULA_VISIBILITY",
214-
215-
"UPDATE_FILTER",
216-
"UPDATE_CHART",
217-
"UPDATE_CHART_REGION",
218-
"UPDATE_CAROUSEL_ACTIVE_ITEM",
219-
220-
"UPDATE_PIVOT",
221-
]);
222-
223200
export const lockedSheetAllowedCommands = new Set<Command["type"]>([
224201
// core commands
225202
"LOCK_SHEET",
@@ -357,10 +334,6 @@ export function isCoreCommand(cmd: Command): cmd is CoreCommand {
357334
return coreTypes.has(cmd.type as any);
358335
}
359336

360-
export function canExecuteInReadonly(cmd: Command): boolean {
361-
return readonlyAllowedCommands.has(cmd.type);
362-
}
363-
364337
//#region Core Commands
365338
// ------------------------------------------------
366339

tests/collaborative/collaborative.test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -600,11 +600,6 @@ describe("Multi users synchronisation", () => {
600600
(user) => getCellContent(user, "A1"),
601601
"hello"
602602
);
603-
setCellContent(david, "A1", "I'm David and I want access !");
604-
expect([alice, bob, charlie, david]).toHaveSynchronizedValue(
605-
(user) => getCellContent(user, "A1"),
606-
"hello"
607-
);
608603
});
609604

610605
test("autofill overwrite style and format", () => {

0 commit comments

Comments
 (0)