Skip to content

Commit

Permalink
feat: add final rowspan implementation (#1101)
Browse files Browse the repository at this point in the history
* feat: add final rowspan implementation
  • Loading branch information
ghiscoding authored Jan 18, 2025
1 parent 7ff7170 commit 2e65fa8
Show file tree
Hide file tree
Showing 54 changed files with 3,016 additions and 817 deletions.
446 changes: 446 additions & 0 deletions cypress/e2e/example-0031-row-span.cy.ts

Large diffs are not rendered by default.

442 changes: 442 additions & 0 deletions cypress/e2e/example-0032-row-span-many-columns.cy.ts

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions cypress/e2e/example-auto-scroll-when-dragging.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,15 @@ describe('Example - Auto scroll when dragging', { retries: 1 }, () => {
});

it('should have a frozen grid with 4 containers with 2 columns on the left and 3 rows on the top after click Set/Clear Frozen button', () => {
cy.get('#myGrid [style="top: 0px;"]').should('have.length', 1);
cy.get('#myGrid2 [style="top: 0px;"]').should('have.length', 1);
cy.get('#myGrid div.slick-row[style*="top: 0px"]').should('have.length', 1);
cy.get('#myGrid2 div.slick-row[style*="top: 0px"]').should('have.length', 1);

cy.get('#toggleFrozen').click();

cy.get('#myGrid [style="top: 0px;"]').should('have.length', 2 * 2);
cy.get('#myGrid2 [style="top: 0px;"]').should('have.length', 2 * 2);
cy.get('#myGrid .grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 2 * 2);
cy.get('#myGrid2 .grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 2 * 2);
cy.get('#myGrid div.slick-row[style*="top: 0px"]').should('have.length', 2 * 2);
cy.get('#myGrid2 div.slick-row[style*="top: 0px"]').should('have.length', 2 * 2);
cy.get('#myGrid .grid-canvas-left > [style*="top: 0px"]').children().should('have.length', 2 * 2);
cy.get('#myGrid2 .grid-canvas-left > [style*="top: 0px"]').children().should('have.length', 2 * 2);
cy.get('#myGrid .grid-canvas-top').children().should('have.length', 3 * 2);
cy.get('#myGrid2 .grid-canvas-top').children().should('have.length', 3 * 2);
});
Expand Down Expand Up @@ -268,8 +268,8 @@ describe('Example - Auto scroll when dragging', { retries: 1 }, () => {

it('should have a frozen & grouping by Duration grid after click Set/Clear grouping by Duration button', { scrollBehavior: false }, () => {
cy.get('#toggleGroup').trigger('click');
cy.get('#myGrid [style="top: 0px;"]').should('have.length', 2 * 2);
cy.get('#myGrid2 [style="top: 0px;"]').should('have.length', 2 * 2);
cy.get('#myGrid div.slick-row[style*="top: 0px;"]').should('have.length', 2 * 2);
cy.get('#myGrid2 div.slick-row[style*="top: 0px;"]').should('have.length', 2 * 2);
cy.get('#myGrid .grid-canvas-top.grid-canvas-left').contains('Duration');
cy.get('#myGrid2 .grid-canvas-top.grid-canvas-left').contains('Duration');
});
Expand All @@ -282,7 +282,7 @@ describe('Example - Auto scroll when dragging', { retries: 1 }, () => {
cy.get('@viewport').invoke('scrollTop').then(scrollAfter => {
expect(scrollBefore).to.be.lessThan(scrollAfter);
cy.dragEnd(selector);
cy.get(selector + ' [style="top: 350px;"].slick-group').should('not.be.hidden');;
cy.get(selector + ' [style*="top: 350px;"].slick-group').should('not.be.hidden');;
});
});
}
Expand All @@ -295,8 +295,8 @@ describe('Example - Auto scroll when dragging', { retries: 1 }, () => {
it('should reset to default grid when click Set/Clear Frozen button and Set/Clear grouping button', () => {
cy.get('#toggleFrozen').trigger('click');
cy.get('#toggleGroup').trigger('click');
cy.get('#myGrid [style="top: 0px;"]').should('have.length', 1);
cy.get('#myGrid2 [style="top: 0px;"]').should('have.length', 1);
cy.get('#myGrid div.slick-row[style*="top: 0px;"]').should('have.length', 1);
cy.get('#myGrid2 div.slick-row[style*="top: 0px;"]').should('have.length', 1);
});

});
24 changes: 12 additions & 12 deletions cypress/e2e/example-autotooltips.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,22 @@ describe('Example AutoTooltips Plugin', () => {
.trigger('mousemove', 'bottomRight')
.trigger('mouseup', 'bottomRight', { which: 1, force: true });

cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l3.r3`).should('contain', '01/01/2009');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l3.r3`).trigger('mouseover');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l3.r3`).should('have.attr', 'title', '01/01/2009');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l3.r3`).should('contain', '01/01/2009');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l3.r3`).trigger('mouseover');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l3.r3`).should('have.attr', 'title', '01/01/2009');

cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell.l3.r3`).should('contain', '01/01/2009');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell.l3.r3`).trigger('mouseover');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell.l3.r3`).should('have.attr', 'title', '01/01/2009');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell.l3.r3`).should('contain', '01/01/2009');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell.l3.r3`).trigger('mouseover');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell.l3.r3`).should('have.attr', 'title', '01/01/2009');
});

it('should hover over "Finish" cell to see tooltip', () => {
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('contain', '01/05/2009');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).trigger('mouseover');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('not.have.attr', 'title', '01/05/2009');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('contain', '01/05/2009');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).trigger('mouseover');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('not.have.attr', 'title', '01/05/2009');

cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('contain', '01/05/2009');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).trigger('mouseover');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('not.have.attr', 'title', '01/05/2009');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('contain', '01/05/2009');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).trigger('mouseover');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l4.r4`).should('not.have.attr', 'title', '01/05/2009');
});
});
6 changes: 3 additions & 3 deletions cypress/e2e/example-checkbox-header-row.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,16 @@ describe('Example - Checkbox Header Row', () => {

// Row index 3, 5 and 21 (last one will be on 2nd page)
cy.get('input[type="checkbox"]:checked').should('have.length', 2); // 2x in current page and 1x in next page
cy.get('[style="top: 75px;"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked');
cy.get('[style="top: 125px;"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked');
cy.get('[style*="top: 75px;"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked');
cy.get('[style*="top: 125px;"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked');
});

it('should go to next page and expect 1 row selected in that second page', () => {
cy.get('.sgi-chevron-right')
.click();

cy.get('input[type="checkbox"]:checked').should('have.length', 1); // only 1x row in page 2
cy.get('[style="top: 100px;"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked');
cy.get('[style*="top: 100px;"] > .slick-cell:nth(0) input[type="checkbox"]').should('be.checked');
});

it('should click on "Select All" checkbox and expect all rows selected in current page', () => {
Expand Down
6 changes: 3 additions & 3 deletions cypress/e2e/example-checkbox-row-select.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ describe('Example - Checkbox Row Select', () => {
});

it('should be able to select first 2 rows and now expect 3 rows selected', () => {
cy.get(`.slick-row[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) input[type=checkbox]`).click();
cy.get(`.slick-row[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0) input[type=checkbox]`).click();
cy.get(`.slick-row[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) input[type=checkbox]`).click();
cy.get(`.slick-row[style*="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0) input[type=checkbox]`).click();

cy.get('#myGrid')
.find('.slick-cell-checkboxsel input:checked')
Expand All @@ -43,7 +43,7 @@ describe('Example - Checkbox Row Select', () => {
cy.get('#unselectRow5')
.click();

cy.get(`.slick-row[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(0) input[type=checkbox]`)
cy.get(`.slick-row[style*="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(0) input[type=checkbox]`)
.should('not.be.checked');

cy.get('#myGrid')
Expand Down
115 changes: 84 additions & 31 deletions cypress/e2e/example-colspan.cy.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,98 @@
describe('Example - Column Span & Header Grouping', { retries: 1 }, () => {
// NOTE: everywhere there's a * 2 is because we have a top+bottom (frozen rows) containers even after Unfreeze Columns/Rows
const GRID_ROW_HEIGHT = 25;
const fullTitles = ['Title', 'Duration', '% Complete', 'Start', 'Finish', 'Effort Driven'];
for (let i = 0; i < 30; i++) {
fullTitles.push(`Mock${i}`);
}
const GRID_ROW_HEIGHT = 25;
const fullTitles = ['Title', 'Duration', '% Complete', 'Start', 'Finish', 'Effort Driven'];
for (let i = 0; i < 30; i++) {
fullTitles.push(`Mock${i}`);
}

it('should display Example title', () => {
cy.visit(`${Cypress.config('baseUrl')}/examples/example-colspan.html`);
cy.get('h2').contains('Demonstrates');
cy.get('h2 + ul > li').first().contains('column span');
it('should display Example title', () => {
cy.visit(`${Cypress.config('baseUrl')}/examples/example-colspan.html`);
cy.get('h2').contains('Demonstrates');
cy.get('h2 + ul > li').first().contains('column span');
});

it('should have exact column titles', () => {
cy.get('#myGrid')
.find('.slick-header-columns')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullTitles[index]));
});

it('should expect 1st row to be 1 column spanned to the entire width', () => {
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 0');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell.l0.r5`).should('exist');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('not.exist');
});

it('should expect 2nd row to be 4 columns and not be spanned', () => {
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 1');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell.l0.r0`).should('exist');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', '5 days');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1).l1.r3`).should('exist');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(2)`).should('contain', '01/05/2009');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(3)`).contains(/(true|false)/);
});

it('should expect 3rd row to be 1 column spanned to the entire width', () => {
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 2');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell.l0.r5`).should('exist');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('not.exist');
});

it('should expect 4th row to be 4 columns and not be spanned', () => {
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 3');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', '5 days');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(2)`).should('contain', '01/05/2009');
cy.get(`[style*="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(3)`).contains(/(true|false)/);
});

describe('Basic Key Navigations', () => {
it('should start at Task 1 on Duration colspan 5 days and type "PageDown" key once and be on Task 20 with full colspan', () => {
cy.get('[data-row=1] > .slick-cell.l1.r3').as('active_cell').click();
cy.get('@active_cell').type('{pagedown}');
cy.get('[data-row=20] > .slick-cell.l0.r5.active').should('have.length', 1);
});

it('should start at Task 1 on Duration colspan 5 days and type "PageDown" key 2x times and be on Task 39 with colspan of 3', () => {
cy.get('[data-row=1] > .slick-cell.l1.r3').as('active_cell').click();
cy.get('@active_cell').type('{pagedown}{pagedown}');
cy.get('[data-row=39] > .slick-cell.l1.r3.active').should('have.length', 1);
});

it('should start at Task 39 on Duration colspan 5 days and type "PageUp" key 2x times and be on Task 1 with full colspan', () => {
cy.get('[data-row=39] > .slick-cell.l1.r3').as('active_cell').click();
cy.get('@active_cell').type('{pageup}{pageup}');
cy.get('[data-row=1] > .slick-cell.l1.r3.active').should('have.length', 1);
});

it('should have exact column titles', () => {
cy.get('#myGrid')
.find('.slick-header-columns')
.children()
.each(($child, index) => expect($child.text()).to.eq(fullTitles[index]));
it('should start at Task 2 on Duration colspan 5 days and type "PageDown" key 2x times and "PageUp" twice and be back to Task 1 with colspan of 3', () => {
cy.get('[data-row=1] > .slick-cell.l1.r3').as('active_cell').click();
cy.get('@active_cell').type('{pagedown}{pagedown}{pageup}{pageup}');
cy.get('[data-row=1] > .slick-cell.l1.r3.active').should('have.length', 1);
});

it('should expect 1st row to be 1 column spanned to the entire width', () => {
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 0');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(1)`).should('not.exist');
it('should start at Task 2 on Duration colspan 5 days and type "PageDown" key 2x times and "PageUp" 3x times and be on Task 0 with full colspan', () => {
cy.get('[data-row=1] > .slick-cell.l1.r3').as('active_cell').click();
cy.get('@active_cell').type('{pagedown}{pagedown}{pageup}{pageup}{pageup}');
cy.get('[data-row=0] > .slick-cell.l0.r5.active').should('have.length', 1);
});

it('should expect 2nd row to be 4 columns and not be spanned', () => {
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 1');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', '5 days');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(2)`).should('contain', '01/05/2009');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(3)`).contains(/(true|false)/);
it('should start at Task 1 on Duration colspan 5 days and type "ArrowDown" key once and be on Task 2 with full colspan', () => {
cy.get('[data-row=1] > .slick-cell.l1.r3').as('active_cell').click();
cy.get('@active_cell').type('{downarrow}');
cy.get('[data-row=2] > .slick-cell.l0.r5.active').should('have.length', 1);
});

it('should expect 3rd row to be 1 column spanned to the entire width', () => {
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 2');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(1)`).should('not.exist');
it('should start at Task 1 on Duration colspan 5 days and type "ArrowDown" key 2x times and be on Task 1 with colspan of 3', () => {
cy.get('[data-row=1] > .slick-cell.l1.r3').as('active_cell').click();
cy.get('@active_cell').type('{downarrow}{downarrow}');
cy.get('[data-row=3] > .slick-cell.l1.r3.active').should('have.length', 1);
});

it('should expect 4th row to be 4 columns and not be spanned', () => {
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(0)`).should('contain', 'Task 3');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(1)`).should('contain', '5 days');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(2)`).should('contain', '01/05/2009');
cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(3)`).contains(/(true|false)/);
it('should start at Task 1 on Duration colspan 5 days and type "ArrowDown" key 2x times, then "ArrowUp" key 2x times and be back on Task 1 with colspan of 3', () => {
cy.get('[data-row=1] > .slick-cell.l1.r3').as('active_cell').click();
cy.get('@active_cell').type('{downarrow}{downarrow}{uparrow}{uparrow}');
cy.get('[data-row=1] > .slick-cell.l1.r3.active').should('have.length', 1);
});
});
});
Loading

0 comments on commit 2e65fa8

Please sign in to comment.