Datagrid: Refactor header column delete/clear (#67842)

* refactor header column delete/clear

* fix tests, add clear option on header dropdown

* fix e2e tests
This commit is contained in:
Victor Marin 2023-05-08 19:02:20 +03:00 committed by GitHub
parent a58de1f8d2
commit 5416ec4768
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 65 additions and 23 deletions

View File

@ -29,7 +29,7 @@ e2e.scenario({
cy.get('[data-testid="glide-cell-2-1"]').should('have.attr', 'aria-selected', 'true'); cy.get('[data-testid="glide-cell-2-1"]').should('have.attr', 'aria-selected', 'true');
cy.get('body').type('12{enter}', { delay: 500 }); cy.get('body').type('12{enter}', { delay: 500 });
cy.get('[aria-label="Confirm Modal Danger Button"]').click(); cy.get('[data-testid="data-testid Confirm Modal Danger Button"]').click();
cy.get('[data-testid="query-editor-row"]').contains('Snapshot'); cy.get('[data-testid="query-editor-row"]').contains('Snapshot');
}, },

View File

@ -17,7 +17,7 @@ e2e.scenario({
cy.get('[data-testid="glide-cell-2-1"]').should('have.attr', 'aria-selected', 'true'); cy.get('[data-testid="glide-cell-2-1"]').should('have.attr', 'aria-selected', 'true');
cy.get('body').type('123{enter}', { delay: 500 }); cy.get('body').type('123{enter}', { delay: 500 });
cy.get('[aria-label="Confirm Modal Danger Button"]').click(); cy.get('[data-testid="data-testid Confirm Modal Danger Button"]').click();
// Delete a cell // Delete a cell
cy.get('.dvn-scroller').click(200, 200); cy.get('.dvn-scroller').click(200, 200);
@ -57,7 +57,7 @@ e2e.scenario({
cy.get('.dvn-scroller').click(20, 190, { waitForAnimations: true }); cy.get('.dvn-scroller').click(20, 190, { waitForAnimations: true });
cy.get('.dvn-scroller').click(20, 90, { shiftKey: true, waitForAnimations: true }); // with shift to select all rows between clicks cy.get('.dvn-scroller').click(20, 90, { shiftKey: true, waitForAnimations: true }); // with shift to select all rows between clicks
cy.get('body').type('{del}'); cy.get('body').type('{del}');
cy.get('[aria-label="Confirm Modal Danger Button"]').click(); cy.get('[data-testid="data-testid Confirm Modal Danger Button"]').click();
cy.get('[data-testid="glide-cell-1-4"]').should('have.text', ''); cy.get('[data-testid="glide-cell-1-4"]').should('have.text', '');
cy.get('[data-testid="glide-cell-1-3"]').should('have.text', ''); cy.get('[data-testid="glide-cell-1-3"]').should('have.text', '');
cy.get('[data-testid="glide-cell-1-2"]').should('have.text', ''); cy.get('[data-testid="glide-cell-1-2"]').should('have.text', '');
@ -72,7 +72,7 @@ e2e.scenario({
cy.get('.dvn-scroller').click(20, 90, { commandKey: true, waitForAnimations: true }); // with cmd to select only clicked rows cy.get('.dvn-scroller').click(20, 90, { commandKey: true, waitForAnimations: true }); // with cmd to select only clicked rows
cy.get('body').type('{del}'); cy.get('body').type('{del}');
cy.get('[aria-label="Confirm Modal Danger Button"]').click(); cy.get('[data-testid="data-testid Confirm Modal Danger Button"]').click();
cy.get('[data-testid="glide-cell-1-1"]').should('have.text', ''); cy.get('[data-testid="glide-cell-1-1"]').should('have.text', '');
cy.get('[data-testid="glide-cell-2-1"]').should('have.text', 0); cy.get('[data-testid="glide-cell-2-1"]').should('have.text', 0);
@ -89,7 +89,7 @@ e2e.scenario({
// Delete column through header dropdown menu // Delete column through header dropdown menu
cy.get('.dvn-scroller').click(250, 15); // click header dropdown cy.get('.dvn-scroller').click(250, 15); // click header dropdown
cy.get('body').click(450, 420); // click delete column cy.get('body').click(450, 420); // click delete column
cy.get('[aria-label="Confirm Modal Danger Button"]').click(); cy.get('[data-testid="data-testid Confirm Modal Danger Button"]').click();
cy.get(`[data-testid="${DATAGRID_CANVAS}"] th`).should('have.length', 1); cy.get(`[data-testid="${DATAGRID_CANVAS}"] th`).should('have.length', 1);
// Delete row through context menu // Delete row through context menu
@ -108,7 +108,7 @@ e2e.scenario({
cy.get('.dvn-scroller').click(20, 90, { commandKey: true, waitForAnimations: true }); // with shift to select all rows between clicks cy.get('.dvn-scroller').click(20, 90, { commandKey: true, waitForAnimations: true }); // with shift to select all rows between clicks
cy.get('.dvn-scroller').rightclick(40, 90); cy.get('.dvn-scroller').rightclick(40, 90);
cy.get('[aria-label="Context menu"]').click(10, 10); cy.get('[aria-label="Context menu"]').click(10, 10);
cy.get('[aria-label="Confirm Modal Danger Button"]').click(); cy.get('[data-testid="data-testid Confirm Modal Danger Button"]').click();
cy.get(`[data-testid="${DATAGRID_CANVAS}"] tbody tr`).should('have.length', 5); // there are 5 data rows + 1 for the add new row btns cy.get(`[data-testid="${DATAGRID_CANVAS}"] tbody tr`).should('have.length', 5); // there are 5 data rows + 1 for the add new row btns
// Delete column through context menu // Delete column through context menu
@ -121,7 +121,7 @@ e2e.scenario({
// Add a new column // Add a new column
cy.get('body').click(350, 200).type('New Column{enter}'); cy.get('body').click(350, 200).type('New Column{enter}');
cy.get('[aria-label="Confirm Modal Danger Button"]').click(); cy.get('[data-testid="data-testid Confirm Modal Danger Button"]').click();
cy.get('body') cy.get('body')
.click(350, 230) .click(350, 230)
.type('Value 1{enter}') .type('Value 1{enter}')
@ -138,7 +138,7 @@ e2e.scenario({
cy.get(`[data-testid="${DATAGRID_CANVAS}"] th`).contains('Renamed column'); cy.get(`[data-testid="${DATAGRID_CANVAS}"] th`).contains('Renamed column');
// Change column field type // Change column field type
cy.get('.dvn-scroller').click(250, 15); cy.get('.dvn-scroller').click(310, 15);
cy.get('[aria-label="Context menu"]').click(50, 50); cy.get('[aria-label="Context menu"]').click(50, 50);
cy.get('.dvn-scroller').click(200, 100); cy.get('.dvn-scroller').click(200, 100);
cy.get('body').type('Str Value{enter}'); cy.get('body').type('Str Value{enter}');

View File

@ -111,14 +111,28 @@ describe('DataGrid', () => {
expect(screen.getByText('Remove all data')).toBeInTheDocument(); expect(screen.getByText('Remove all data')).toBeInTheDocument();
expect(screen.getByText('Search...')).toBeInTheDocument(); expect(screen.getByText('Search...')).toBeInTheDocument();
// click on header cell should show only column options // right clicking on header cell without clicking/selecting the cell should show only general options
fireEvent.contextMenu(scroller, {
clientX: 50,
clientY: 36,
});
expect(screen.getByText('Remove all data')).toBeInTheDocument();
expect(screen.getByText('Search...')).toBeInTheDocument();
// selecting the header first and then right click on header cell should show only column options
const canvas = screen.getByTestId('data-grid-canvas');
sendClick(canvas, {
clientX: 50,
clientY: 36,
});
fireEvent.contextMenu(scroller, { fireEvent.contextMenu(scroller, {
clientX: 50, clientX: 50,
clientY: 36, clientY: 36,
}); });
expect(screen.getByText('Delete column')).toBeInTheDocument(); expect(screen.getByText('Delete column')).toBeInTheDocument();
expect(screen.getByText('Clear column')).toBeInTheDocument();
expect(screen.getByText('Remove all data')).toBeInTheDocument(); expect(screen.getByText('Remove all data')).toBeInTheDocument();
expect(screen.getByText('Search...')).toBeInTheDocument(); expect(screen.getByText('Search...')).toBeInTheDocument();

View File

@ -154,8 +154,29 @@ export function DataGridPanel({ options, data, id, fieldConfig, width, height }:
return true; return true;
} }
if (selection.rows) { const rows = selection.rows.toArray();
updateSnapshot(deleteRows(frame, selection.rows.toArray()), onUpdateData); const cols = selection.columns.toArray();
if (rows.length) {
updateSnapshot(deleteRows(frame, rows), onUpdateData);
return true;
}
if (cols.length) {
const copiedFrame = {
...frame,
fields: frame.fields.map((field, index) => {
if (cols.includes(index)) {
return {
...field,
values: new Array(frame.length).fill(null),
};
}
return field;
}),
};
updateSnapshot(copiedFrame, onUpdateData);
return true; return true;
} }

View File

@ -53,10 +53,11 @@ export const DatagridContextMenu = ({
columnDeletionLabel = `Delete ${selectedColumns.length} columns`; columnDeletionLabel = `Delete ${selectedColumns.length} columns`;
} }
// Show delete/clear options on cell right click, but not on header right click, unless header column is specifically selected.
const showDeleteRow = (row !== undefined && row >= 0) || selectedRows.length; const showDeleteRow = (row !== undefined && row >= 0) || selectedRows.length;
const showDeleteColumn = (column !== undefined && column >= 0) || selectedColumns.length; const showDeleteColumn = (column !== undefined && column >= 0 && row !== undefined) || selectedColumns.length;
const showClearRow = row !== undefined && row >= 0 && !selectedRows.length; const showClearRow = row !== undefined && row >= 0 && !selectedRows.length;
const showClearColumn = column !== undefined && column >= 0 && !selectedColumns.length; const showClearColumn = column !== undefined && column >= 0 && row !== undefined && !selectedColumns.length;
const renderContextMenuItems = () => ( const renderContextMenuItems = () => (
<> <>
@ -85,6 +86,7 @@ export const DatagridContextMenu = ({
...data, ...data,
fields: data.fields.filter((_, index) => !selectedColumns.includes(index)), fields: data.fields.filter((_, index) => !selectedColumns.includes(index)),
}); });
dispatch({ type: DatagridActionType.gridSelectionCleared });
return; return;
} }
@ -215,20 +217,25 @@ export const DatagridContextMenu = ({
<MenuItem label="Rename column" onClick={renameColumnClicked} /> <MenuItem label="Rename column" onClick={renameColumnClicked} />
<MenuDivider /> <MenuDivider />
<MenuItem <MenuItem
label={columnDeletionLabel} label="Delete column"
onClick={() => { onClick={() => {
if (selectedColumns.length) {
saveData({
...data,
fields: data.fields.filter((_, index) => !selectedColumns.includes(index)),
});
return;
}
saveData({ saveData({
...data, ...data,
fields: data.fields.filter((_, index) => index !== column), fields: data.fields.filter((_, index) => index !== column),
}); });
// also clear selection since it will change it if the deleted column is selected or if indexes shift
dispatch({ type: DatagridActionType.gridSelectionCleared });
}}
/>
<MenuItem
label="Clear column"
onClick={() => {
const field = data.fields[column];
field.values = field.values.map(() => null);
saveData({
...data,
});
}} }}
/> />
</> </>