Skip to content

Commit

Permalink
Merge pull request #2331 from concord-consortium/187848992-fix-issue-…
Browse files Browse the repository at this point in the history
…with-combining-data-card-stacks-via-drag-and-drop

fix: Issue with combining  data card stacks via drag and drop (PT-187848992)
  • Loading branch information
emcelroy authored Jul 2, 2024
2 parents 2484f7f + 7139f7a commit 75b87a9
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 179 deletions.
114 changes: 18 additions & 96 deletions cypress/e2e/functional/tile_tests/datacard_merge_spec.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import ClueCanvas from '../../../support/elements/common/cCanvas';
import Canvas from '../../../support/elements/common/Canvas';
import DataCardToolTile from '../../../support/elements/tile/DataCardToolTile';

let clueCanvas = new ClueCanvas;
let dc = new DataCardToolTile;
let canvas = new Canvas;
let studentWorkspace = 'SAS 1.1 Solving a Mystery with Proportional Reasoning';
const dataTransfer = new DataTransfer;

function beforeTest() {
const queryParams = `${Cypress.config("qaUnitStudent5")}`;
Expand All @@ -15,14 +11,6 @@ function beforeTest() {
cy.waitForLoad();
}

function openMyWork() {
cy.wait(2000);
clueCanvas.getInvestigationCanvasTitle().text().then((investigationTitle) => {
cy.openTopTab('my-work');
cy.openDocumentThumbnail('my-work', 'workspaces', investigationTitle);
});
}

context('Merge Data Card Tool Tile', function () {
it("Merge Data Card Tool Tile", () => {
beforeTest();
Expand Down Expand Up @@ -64,12 +52,9 @@ context('Merge Data Card Tool Tile', function () {
dc.getTile(1).should("exist");
dc.getTileTitle(1).should("have.text", "Card Deck Data 2");

dc.getTile(0).find(".data-card-tool")
.trigger('dragstart', { dataTransfer }).then(() => {
dc.getTile(1).find(".data-card-tool .data-card-header-row")
.trigger('drop', { dataTransfer, force: true })
.trigger('dragend', { dataTransfer, force: true });
});
dc.getMergeDataButton(1).click();
dc.getMergeDataModalSelect().select("Card Deck Data 1");
dc.getMergeDataModalAddDataButton().click();

dc.getAttrs(0).should("have.length", 1);
dc.getCardNofTotalListing(0).should("have.text", "Card 1 of 1");
Expand Down Expand Up @@ -98,12 +83,9 @@ context('Merge Data Card Tool Tile', function () {
dc.getTile(1).should("exist");
dc.getTileTitle(1).should("have.text", "Card Deck Data 2");

dc.getTile(0).find(".data-card-tool")
.trigger('dragstart', { dataTransfer }).then(() => {
dc.getTile(1).find(".data-card-tool .data-card-header-row")
.trigger('drop', { dataTransfer, force: true })
.trigger('dragend', { dataTransfer, force: true });
});
dc.getMergeDataButton(1).click();
dc.getMergeDataModalSelect().select("Card Deck Data 1");
dc.getMergeDataModalAddDataButton().click();

dc.getAttrs(0).should("have.length", 1);
dc.getCardNofTotalListing(0).should("have.text", "Card 1 of 1");
Expand Down Expand Up @@ -140,12 +122,9 @@ context('Merge Data Card Tool Tile', function () {
dc.getAttrName(1).contains("Attr1 Name");
dc.getAttrValue(1).click().type("Attr1 Value{enter}");

dc.getTile(0).find(".data-card-tool")
.trigger('dragstart', { dataTransfer }).then(() => {
dc.getTile(1).find(".data-card-tool .data-card-header-row")
.trigger('drop', { dataTransfer, force: true })
.trigger('dragend', { dataTransfer, force: true });
});
dc.getMergeDataButton(1).click();
dc.getMergeDataModalSelect().select("Card Deck Data 1");
dc.getMergeDataModalAddDataButton().click();

dc.getAttrs(0).should("have.length", 1);
dc.getCardNofTotalListing(0).should("have.text", "Card 1 of 1");
Expand Down Expand Up @@ -186,12 +165,9 @@ context('Merge Data Card Tool Tile', function () {
dc.getAttrName(1).contains("Attr2 Name");
dc.getAttrValue(1).click().type("Attr2 Value{enter}");

dc.getTile(0).find(".data-card-tool")
.trigger('dragstart', { dataTransfer }).then(() => {
dc.getTile(1).find(".data-card-tool .data-card-header-row")
.trigger('drop', { dataTransfer, force: true })
.trigger('dragend', { dataTransfer, force: true });
});
dc.getMergeDataButton(1).click();
dc.getMergeDataModalSelect().select("Card Deck Data 1");
dc.getMergeDataModalAddDataButton().click();

dc.getAttrs(0).should("have.length", 1);
dc.getCardNofTotalListing(0).should("have.text", "Card 1 of 1");
Expand Down Expand Up @@ -232,12 +208,9 @@ context('Merge Data Card Tool Tile', function () {
dc.getAttrName(1).contains("Attr1 Name");
dc.getAttrValue(1).click().type("Attr2 Value{enter}");

dc.getTile(0).find(".data-card-tool")
.trigger('dragstart', { dataTransfer }).then(() => {
dc.getTile(1).find(".data-card-tool .data-card-header-row")
.trigger('drop', { dataTransfer, force: true })
.trigger('dragend', { dataTransfer, force: true });
});
dc.getMergeDataButton(1).click();
dc.getMergeDataModalSelect().select("Card Deck Data 1");
dc.getMergeDataModalAddDataButton().click();

dc.getAttrs(1).should("have.length", 1);
dc.getCardNofTotalListing(1).should("have.text", "Card 1 of 2");
Expand Down Expand Up @@ -275,12 +248,9 @@ context('Merge Data Card Tool Tile', function () {
dc.getSortSelect(1).select("Attr2 Name");
dc.getSortView(1).should('exist');

dc.getTile(0).find(".data-card-tool")
.trigger('dragstart', { dataTransfer }).then(() => {
dc.getTile(1).find(".data-card-tool .data-card-header-row")
.trigger('drop', { dataTransfer, force: true })
.trigger('dragend', { dataTransfer, force: true });
});
dc.getMergeDataButton(1).click();
dc.getMergeDataModalSelect().select("Card Deck Data 1");
dc.getMergeDataModalAddDataButton().click();

dc.getSortSelect(1).select("None");
dc.getSingleCardView(1).should('exist');
Expand All @@ -301,52 +271,4 @@ context('Merge Data Card Tool Tile', function () {
dc.getPreviousCardButton(1).click();
dc.getCardNofTotalListing(1).should("have.text", "Card 1 of 2");
});

it("merge Data card tool tile across documents", () => {
beforeTest();
openMyWork();
clueCanvas.addTile("datacard");
dc.getTile(0).should("exist");
dc.getTileTitle(0).should("have.text", "Card Deck Data 1");

dc.getAttrName(0).dblclick().type("Attr1 Name{enter}");
dc.getAttrName(0).contains("Attr1 Name");
dc.getAttrValue(0).click().type("Attr1 Value{enter}");

cy.log("opens document in main doc on the left");
canvas.createNewExtraDocumentFromFileMenu(studentWorkspace, "my-work");

cy.log("creates a Data Card tool tile in new personal workspace");
clueCanvas.addTile("datacard");
dc.getTile(0).should("exist");
dc.getTileTitle(0).should("have.text", "Card Deck Data 1");

dc.getAttrName(0).dblclick().type("Attr2 Name{enter}");
dc.getAttrName(0).contains("Attr2 Name");
dc.getAttrValue(0).click().type("Attr2 Value{enter}");

cy.log("merge Data card tool tile from left to right");
dc.getTile(0, "[data-test=\"subtab-workspaces\"] .editable-document-content").find(".data-card-tool")
.trigger('dragstart', { dataTransfer }).then(() => {
dc.getTile(0).find(".data-card-tool .data-card-header-row")
.trigger('drop', { dataTransfer, force: true })
.trigger('dragend', { dataTransfer, force: true });
});

dc.getAttrs(0).should("have.length", 2);
dc.getCardNofTotalListing(0).should("have.text", "Card 1 of 2");
dc.getAttrName(0).eq(0).should("have.text", "Attr2 Name");
dc.getAttrValue(0).eq(0).invoke("val").should("contain", "Attr2 Value");
dc.getAttrName(0).eq(1).should("have.text", "Attr1 Name");
dc.getAttrValue(0).eq(1).invoke("val").should("be.empty");
dc.getNextCardButton(0).click();
dc.getCardNofTotalListing(0).should("have.text", "Card 2 of 2");
dc.getAttrs(0).should("have.length", 2);
dc.getAttrName(0).eq(0).should("have.text", "Attr2 Name");
dc.getAttrValue(0).eq(0).invoke("val").should("be.empty");
dc.getAttrName(0).eq(1).should("have.text", "Attr1 Name");
dc.getAttrValue(0).eq(1).invoke("val").should("contain", "Attr1 Value");
dc.getPreviousCardButton(0).click();
dc.getCardNofTotalListing(0).should("have.text", "Card 1 of 2");
});
});
87 changes: 4 additions & 83 deletions src/plugins/data-card/data-card-tile.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import classNames from "classnames";
import { observer } from "mobx-react";
import React, { useEffect, useRef, useState } from "react";
import { ITileProps, extractDragTileType, kDragTiles } from "../../components/tiles/tile-component";
import { ITileProps } from "../../components/tiles/tile-component";
import { useUIStore } from "../../hooks/use-stores";
import { DataCardContentModelType } from "./data-card-content";
import { DataCardRows } from "./components/data-card-rows";
Expand All @@ -13,8 +13,6 @@ import { AddIconButton, RemoveIconButton } from "./components/add-remove-icons";
import { useCautionAlert } from "../../components/utilities/use-caution-alert";
import { EditFacet } from "./data-card-types";
import { DataCardSortArea } from "./components/sort-area";
import { safeJsonParse } from "../../utilities/js-utils";
import { mergeTwoDataSets } from "../../models/data/data-set-utils";
import { CustomEditableTileTitle } from "../../components/tiles/custom-editable-tile-title";
import { DataCardToolbarContext } from "./data-card-toolbar-context";
import { CasesCountDisplay } from "./components/cases-count-display";
Expand All @@ -23,9 +21,8 @@ import { useDataCardTileHeight } from "./use-data-card-tile-height";
import "./data-card-tile.scss";

export const DataCardToolComponent: React.FC<ITileProps> = observer(function DataCardToolComponent(props) {
const { documentId, model, readOnly, documentContent, tileElt, onSetCanAcceptDrop, onRegisterTileApi,
scale, onUnregisterTileApi,
height, onRequestRowHeight } = props;
const { documentId, model, readOnly, documentContent, tileElt, onRegisterTileApi,
scale, onUnregisterTileApi, height, onRequestRowHeight } = props;
const backgroundRef = useRef<HTMLDivElement | null>(null);

const content = model.content as DataCardContentModelType;
Expand All @@ -38,7 +35,6 @@ export const DataCardToolComponent: React.FC<ITileProps> = observer(function Dat
const [currEditAttrId, setCurrEditAttrId] = useState<string>("");
const [currEditFacet, setCurrEditFacet] = useState<EditFacet>("");
const [imageUrlToAdd, setImageUrlToAdd] = useState<string>("");
const [highlightDataCard, setHighlightDataCard] = useState(false);

const shouldShowAddCase = !readOnly && isTileSelected;
const shouldShowDeleteCase = !readOnly && isTileSelected && dataSet.cases.length > 1;
Expand Down Expand Up @@ -67,79 +63,6 @@ export const DataCardToolComponent: React.FC<ITileProps> = observer(function Dat
isSingleView: displaySingle
});

/* ==[ Drag and Drop ] == */

const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
const isAcceptableDrag = isAcceptableDataCardDrag(e);
onSetCanAcceptDrop(isAcceptableDrag ? model.id : undefined); //this turns off highlighting outer edge
};

const isAcceptableDataCardDrag = (e: React.DragEvent<HTMLDivElement>) => {
const draggingWithinItself = ui?.selectedTileIds.includes(model.id);
if (draggingWithinItself){
setHighlightDataCard(false);
return false;
}
const tileTypeDragged = extractDragTileType(e.dataTransfer);
const isDraggedTileDataCard = tileTypeDragged === "datacard"; //if two cards dragged, tileTypeDragged is undefined
if (!readOnly && isDraggedTileDataCard) {
const kImgDropMarginPct = 0.1;
const eltBounds = e.currentTarget.getBoundingClientRect();
const kImgDropMarginX = eltBounds.width * kImgDropMarginPct;
const kImgDropMarginY = eltBounds.height * kImgDropMarginPct;
if ((e.clientX > eltBounds.left + kImgDropMarginX) &&
(e.clientX < eltBounds.right - kImgDropMarginX) &&
(e.clientY > eltBounds.top + kImgDropMarginY) &&
(e.clientY < ((eltBounds.bottom - kImgDropMarginY) * 0.95))){
setHighlightDataCard(true); //within bounds
return true;
} else {
setHighlightDataCard(false); //out of bounds
return false;
}
}
else { //not of type Datacard
setHighlightDataCard(false);
return false;
}
};

const highlightContainerClasses = classNames(
"data-card-container",
{"highlight": highlightDataCard},
{"no-highlight": !highlightDataCard}
);

const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {

if (isAcceptableDataCardDrag(e)) {
if (highlightDataCard) {
setHighlightDataCard(false); //after you drop turn off highlighting
}

/* ==[ Merge dragged tile -> dropped tile ] == */
const getDataDraggedTile = e.dataTransfer.getData(kDragTiles);
const parsedDataDraggedTile = safeJsonParse(getDataDraggedTile);
const contentOfDraggedTile= safeJsonParse(parsedDataDraggedTile.sharedModels[0].content);
const dataSetOfDraggedTile = contentOfDraggedTile.dataSet;

mergeTwoDataSets(dataSetOfDraggedTile, dataSet);
e.preventDefault();
e.stopPropagation(); //prevents calling document-content > handleDrop

/* ==[ Delete tile (if within same document) ] == */
const sourceDocIdDraggedTile = parsedDataDraggedTile.sourceDocId;
const docIdDroppedTile = props.docId;
const idDraggedTile = parsedDataDraggedTile.tiles[0].tileId;
if (sourceDocIdDraggedTile === docIdDroppedTile){
ui.removeTileIdFromSelection(idDraggedTile);
// document.deleteTile(idDraggedTile);
//TODO - document cannot be accessed, this would require a refactor
//https://www.pivotaltracker.com/n/projects/2441242/stories/185129553
}
}
};

function nextCase() {
if (content.caseIndex < content.totalCases - 1) {
content.setCaseIndex(content.caseIndex + 1);
Expand Down Expand Up @@ -261,11 +184,9 @@ export const DataCardToolComponent: React.FC<ITileProps> = observer(function Dat
<div
className="data-card-content"
onClick={handleBackgroundClick}
onDragOver={handleDragOver}
onDrop={handleDrop}
ref={element => backgroundRef.current = element}
>
<div className={highlightContainerClasses}>
<div className="data-card-container">
<div className="data-card-header-row">
<div className="panel title">
<CustomEditableTileTitle
Expand Down

0 comments on commit 75b87a9

Please sign in to comment.