(core) Adding new command Duplicate rows

Summary:
New command "Duplicate rows" is available in the Row/Card Context Menu and as a keyboard shortcut Ctrl+Alt+C.
- All selected rows are duplicated (even if only a single column is selected)
- Rows are inserted immediately after the last selected row (using manualSort value).
- Formulas and CENSORED fields are not copied.
Implemented on the UI level (no new action).

Test Plan: new test

Reviewers: cyprien

Reviewed By: cyprien

Differential Revision: https://phab.getgrist.com/D3371
This commit is contained in:
Jarosław Sadziński
2022-04-19 15:01:08 +02:00
parent d7514e9cfc
commit 77ef9df27d
7 changed files with 158 additions and 34 deletions

View File

@@ -1,14 +1,8 @@
import { allCommands } from 'app/client/components/commands';
import { menuDivider, menuItemCmd } from 'app/client/ui2018/menus';
import { dom } from 'grainjs';
import { IMultiColumnContextMenu } from 'app/client/ui/GridViewMenus';
interface IRowContextMenu {
disableInsert: boolean;
disableDelete: boolean;
isViewSorted: boolean;
numRows: number;
}
import { IRowContextMenu } from 'app/client/ui/RowContextMenu';
import { dom } from 'grainjs';
export function CellContextMenu(rowOptions: IRowContextMenu, colOptions: IMultiColumnContextMenu) {
@@ -65,7 +59,8 @@ export function CellContextMenu(rowOptions: IRowContextMenu, colOptions: IMultiC
menuItemCmd(allCommands.insertRecordAfter, 'Insert row below',
dom.cls('disabled', disableInsert))]
),
menuItemCmd(allCommands.duplicateRows, `Duplicate ${numRows === 1 ? 'row' : 'rows'}`,
dom.cls('disabled', disableInsert || numRows === 0)),
menuItemCmd(allCommands.insertFieldBefore, 'Insert column to the left',
disableForReadonlyView),
menuItemCmd(allCommands.insertFieldAfter, 'Insert column to the right',

View File

@@ -2,13 +2,14 @@ import { allCommands } from 'app/client/components/commands';
import { menuDivider, menuItemCmd } from 'app/client/ui2018/menus';
import { dom } from 'grainjs';
interface IRowContextMenu {
export interface IRowContextMenu {
disableInsert: boolean;
disableDelete: boolean;
isViewSorted: boolean;
numRows: number;
}
export function RowContextMenu({ disableInsert, disableDelete, isViewSorted }: IRowContextMenu) {
export function RowContextMenu({ disableInsert, disableDelete, isViewSorted, numRows }: IRowContextMenu) {
const result: Element[] = [];
if (isViewSorted) {
// When the view is sorted, any newly added records get shifts instantly at the top or
@@ -26,6 +27,10 @@ export function RowContextMenu({ disableInsert, disableDelete, isViewSorted }: I
dom.cls('disabled', disableInsert)),
);
}
result.push(
menuItemCmd(allCommands.duplicateRows, `Duplicate ${numRows === 1 ? 'row' : 'rows'}`,
dom.cls('disabled', disableInsert || numRows === 0)),
);
result.push(
menuDivider(),
// TODO: should show `Delete ${num} rows` when multiple are selected