Skip to content

Commit

Permalink
Merge pull request #87 from Watts-Lab/dan/drag-and-drop
Browse files Browse the repository at this point in the history
Drag and Drop to Reorder Stages and Elements within Timeline
  • Loading branch information
dankim444 authored Oct 10, 2024
2 parents 570c6e8 + ab29d9d commit 95de794
Show file tree
Hide file tree
Showing 6 changed files with 319 additions and 125 deletions.
142 changes: 142 additions & 0 deletions cypress/e2e/reorder.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// npm run cypress:open

describe('timeline drag and drop', () => {
beforeEach(() => {
// initial yaml treatment file
let yamltreatment = "name: drag_and_drop_test\nplayerCount: 1\ngameStages: []";

cy.viewport(2000, 1000, { log: false });
cy.visit('http://localhost:3000/editor');
cy.get('[data-cy="code-editor"]').clear().type(yamltreatment);
cy.get('[data-cy="yaml-save"]').click();

// add first stage
cy.get('[data-cy="add-stage-button"]').click();
cy.get('[data-cy="edit-stage-name-new"]').type("Stage 1");
cy.get('[data-cy="edit-stage-duration-new"]').type("{backspace}300");
cy.get('[data-cy="edit-stage-save-new"]').click();

// add element 1 in stage 1
cy.get('[data-cy="add-element-button-0"]').click();
cy.get('[data-cy="edit-element-name-0-new"]').type("Element 1");
cy.get('[data-cy="edit-element-type-0-new"]').select("Prompt");
cy.get('[data-cy="edit-element-file-0-new"]').type("projects/example/preDiscussionInstructions.md");
cy.get('[data-cy="edit-element-save-0-new"]').click();

// add element 2 in stage 1
cy.get('[data-cy="add-element-button-0"]').click();
cy.get('[data-cy="edit-element-name-0-new"]').type("Element 2");
cy.get('[data-cy="edit-element-type-0-new"]').select("Survey");
cy.get('[data-cy="edit-element-surveyName-0-new"]').select("TIPI");
cy.get('[data-cy="edit-element-save-0-new"]').click();

// add second stage
cy.get('[data-cy="add-stage-button"]').click();
cy.get('[data-cy="edit-stage-name-new"]').type("Stage 2");
cy.get('[data-cy="edit-stage-duration-new"]').type("{backspace}200");
cy.get('[data-cy="edit-stage-save-new"]').click();

cy.get('[data-cy="stage-0"]').contains("Stage 1").should("be.visible");
cy.get('[data-cy="stage-1"]').contains("Stage 2").should("be.visible");
cy.get('[data-cy="element-0-0"]').contains("Element 1").should("be.visible");
cy.get('[data-cy="element-0-1"]').contains("Element 2").should("be.visible");
});

it('allows reordering of elements within stage', () => {
// verify initial order
cy.get('[data-cy="element-0-0"]').contains("Element 1").should("be.visible");
cy.get('[data-cy="element-0-1"]').contains("Element 2").should("be.visible");
cy.get('[data-cy^="element-0-"]').should('have.length', 2);

// swap first element with second element
cy.get('[data-cy="element-0-0"]')
.focus()
.type(" ") // space bar selects item to move
.type("{downArrow}") // move element down one
.type(" "); // stop moving item

cy.wait(1000);

// verify new order
cy.get('[data-cy="element-0-0"]').contains("Element 2").should("be.visible");
cy.get('[data-cy="element-0-1"]').contains("Element 1").should("be.visible");
cy.get('[data-cy^="element-0-"]').should('have.length', 2);
})

it('allows reodering of stages', () => {
// verify initial order
cy.get('[data-cy="stage-0"]').contains("Stage 1").should("be.visible");
cy.get('[data-cy="stage-1"]').contains("Stage 2").should("be.visible");
cy.get('[data-cy^="stage-"]').should('have.length', 2);

// swap first stage with second stage
cy.get('[data-cy="stage-0"]')
.focus()
.type(" ")
.type("{rightArrow}") // move stage 1 to the right
.type(" ");

cy.wait(1000);

// verify new order
cy.get('[data-cy="stage-0"]').contains("Stage 2").should("be.visible");
cy.get('[data-cy="stage-1"]').contains("Stage 1").should("be.visible");
cy.get('[data-cy^="stage-"]').should('have.length', 2);
})

it('rejects dragging elements to invalid spots', () => {
// verify initial order
cy.get('[data-cy="element-0-0"]').contains("Element 1").should("be.visible");
cy.get('[data-cy="element-0-1"]').contains("Element 2").should("be.visible");
cy.get('[data-cy^="element-0-"]').should('have.length', 2);

// try moving first element from stage 1 to stage 2
cy.get('[data-cy="element-0-0"]')
.focus()
.type(" ")
.type("{rightArrow}")
.type(" ");

cy.wait(1000);

// verify that order remains the same
cy.get('[data-cy="element-0-0"]').contains("Element 1").should("be.visible");
cy.get('[data-cy="element-0-1"]').contains("Element 2").should("be.visible");
cy.get('[data-cy^="element-0-"]').should('have.length', 2);

// try moving second element outside of stage 1
cy.get('[data-cy="element-0-1"]')
.focus()
.type(" ")
.type("{rightArrow}")
.type(" ");

cy.wait(1000);

// verify that order remains the same
cy.get('[data-cy="element-0-0"]').contains("Element 1").should("be.visible");
cy.get('[data-cy="element-0-1"]').contains("Element 2").should("be.visible");
cy.get('[data-cy^="element-0-"]').should('have.length', 2);
})

it('rejects dragging stages outside of timeline', () => {
// verify initial order
cy.get('[data-cy="stage-0"]').contains("Stage 1").should("be.visible");
cy.get('[data-cy="stage-1"]').contains("Stage 2").should("be.visible");
cy.get('[data-cy^="stage-"]').should('have.length', 2);

// try dragging stage outside of timeline
cy.get('[data-cy="stage-0"]')
.focus()
.type(" ")
.type("{upArrow}")
.type(" ");

cy.wait(1000);

// verify that order remains the same
cy.get('[data-cy="stage-0"]').contains("Stage 1").should("be.visible");
cy.get('[data-cy="stage-1"]').contains("Stage 2").should("be.visible");
cy.get('[data-cy^="stage-"]').should('have.length', 2);
})
})
93 changes: 26 additions & 67 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"patch": "cp patchedPlayer.d.ts ./node_modules/@empirica/core/dist/player-classic-react.d.ts"
},
"dependencies": {
"@empirica/core": "^1.11.0",
"@hello-pangea/dnd": "^16.6.0",
"@empirica/core": "^1.11.6",
"@hello-pangea/dnd": "^17.0.0",
"@hookform/resolvers": "^3.6.0",
"@uiw/react-textarea-code-editor": "^2.1.9",
"@watts-lab/surveys": "^1.13.4",
Expand Down
1 change: 1 addition & 0 deletions src/app/editor/components/ElementCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export function ElementCard({
className="card bg-base-200 shadow-md min-h-12 min-w-[10px] justify-center px-5"
style={{ left: startTime * scale, width: scale * (endTime - startTime) }}
data-cy={'element-' + stageIndex + '-' + elementIndex}
tabIndex={0}
>
<div>
{Object.keys(element).map((key) => (
Expand Down
Loading

0 comments on commit 95de794

Please sign in to comment.