From e9dfa69634764a8c0adc6135ea817b896426e3c0 Mon Sep 17 00:00:00 2001 From: Evangeline Ireland Date: Wed, 2 Oct 2024 11:54:44 -0700 Subject: [PATCH] 186182704 formula column background (#1529) * Adds formula column background color * Adds formula background styling to case card value cell. Disables value editing when attribute has a formula * Adds Cypress test to verify background color when attribute is a formula Splits case card test to 2 context so mouseSensor does not interfere with attribute menu clicks * PR fix --- v3/cypress/e2e/case-card.spec.ts | 43 +++++++++++++++---- v3/cypress/e2e/table.spec.ts | 2 + .../components/case-card/case-attr-view.scss | 7 ++- .../components/case-card/case-attr-view.tsx | 6 ++- v3/src/components/case-table/case-table.scss | 4 ++ v3/src/components/case-table/use-columns.tsx | 8 ++-- 6 files changed, 56 insertions(+), 14 deletions(-) diff --git a/v3/cypress/e2e/case-card.spec.ts b/v3/cypress/e2e/case-card.spec.ts index 964ad9370f..eff1c604cd 100644 --- a/v3/cypress/e2e/case-card.spec.ts +++ b/v3/cypress/e2e/case-card.spec.ts @@ -287,6 +287,19 @@ context("case card", () => { cy.get('[data-testid="case-card-view"]').should("have.length", 2) cy.get('[data-testid="case-card-view-title"]').first().should("have.text", "Diets") }) + }) +}) + +context("case card inspector panel", () => { + beforeEach(() => { + // cy.scrollTo() doesn't work as expected with `scroll-behavior: smooth` + const queryParams = "?sample=mammals&scrollBehavior=auto" + const url = `${Cypress.config("index")}${queryParams}` + cy.visit(url) + cy.wait(2000) + }) + + describe("case card inspector panel", () => { it("displays inspector panel when in focus", () => { table.toggleCaseView() cy.wait(500) @@ -378,14 +391,14 @@ context("case card", () => { cy.wait(500) card.getShowAllHiddenAttributesButton().should("be.disabled") // FIXME: Reinstate the below after figuring out why clicking attribute buttons does nothing in Cypress - // cy.get('[data-testid="case-card-attr-name"]').eq(8).click() - // cy.get('[data-testid="attribute-menu-list"]').should("be.visible") - // cy.get('[data-testid="attribute-menu-list"]').find("button").contains("Hide Attribute").click() - // cy.get('[data-testid="case-card-attr"]').should("have.length", 8) - // card.getHideShowButton().click() - // cy.get('[data-testid="hide-show-menu-list"]').should("be.visible") - // cy.get('[data-testid="hide-show-menu-show-all-hidden-attributes"]').should("not.be.disabled").click() - // cy.get('[data-testid="case-card-attr"]').should("have.length", 9) + cy.get('[data-testid="case-card-attr-name"]').eq(8).click() + cy.get('[data-testid="attribute-menu-list"]').should("be.visible") + cy.get('[data-testid="attribute-menu-list"]').find("button").contains("Hide Attribute").click() + cy.get('[data-testid="case-card-attr"]').should("have.length", 8) + card.getHideShowButton().click() + cy.get('[data-testid="hide-show-menu-list"]').should("be.visible") + cy.get('[data-testid="hide-show-menu-show-all-hidden-attributes"]').should("not.be.disabled").click() + cy.get('[data-testid="case-card-attr"]').should("have.length", 9) }) it("allows user to add an attribute from inspector panel", () => { table.toggleCaseView() @@ -397,6 +410,20 @@ context("case card", () => { cy.wait(500) cy.get('[data-testid="column-name-input"]').should("exist").type("Friendliness{enter}") cy.get('[data-testid="case-card-attr"]').should("have.length", 10) + + cy.log("add a formula to the new attribute") + cy.get('[data-testid="case-card-attr-name"]').eq(9).click() + cy.wait(500) + cy.get('[data-testid="attribute-menu-list"]').should("be.visible") + cy.get("[data-testid=attribute-menu-list] button").contains("Edit Formula...").click() + cy.get('[data-testid="attr-formula-input"]').should("be.visible") + cy.get('[data-testid="attr-formula-input"]') + .type("if(LifeSpan>20, \"Friendly\", \"Unfriendly\")", {force:true}) + cy.get("[data-testid=Apply-button]").click() + cy.get('[data-testid="attr-formula-input"]').should("not.exist") + cy.get('[data-testid="case-card-attr-value"]').eq(9).should("have.text", "Friendly, Unfriendly") + cy.get('[data-testid="case-card-attr-value"] .formula-attr-value') + .should("have.css", "background-color", "rgba(255, 255, 0, 0.2)") }) }) }) diff --git a/v3/cypress/e2e/table.spec.ts b/v3/cypress/e2e/table.spec.ts index 594c9c5d8f..963c42db1c 100644 --- a/v3/cypress/e2e/table.spec.ts +++ b/v3/cypress/e2e/table.spec.ts @@ -431,6 +431,8 @@ context("case table ui", () => { random1 = +cell.text() expect(random1 >= 0).to.eq(true) expect(random1 < 1).to.eq(true) + // verify cell background color is not white + cy.wrap(cell).should("have.css", "background-color", "rgba(255, 255, 0, 0.2)") }) // Rerandomize let random2 = 0 diff --git a/v3/src/components/case-card/case-attr-view.scss b/v3/src/components/case-card/case-attr-view.scss index 4bc9e78683..1ff3d4c9d4 100644 --- a/v3/src/components/case-card/case-attr-view.scss +++ b/v3/src/components/case-card/case-attr-view.scss @@ -2,7 +2,7 @@ .case-card-attr { height: 25px; - + &:nth-child(2) { .case-card-attr-value { border-top: solid 1px #b2b2b2; @@ -45,6 +45,11 @@ text-align: left; } + &.formula-attr-value { + background-color: rgba(255, 255, 0, 0.2); + font-style: italic; + } + span { border-radius: 0; display: inline-block; diff --git a/v3/src/components/case-card/case-attr-view.tsx b/v3/src/components/case-card/case-attr-view.tsx index 7f47a0b4a4..fc10e7ece2 100644 --- a/v3/src/components/case-card/case-attr-view.tsx +++ b/v3/src/components/case-card/case-attr-view.tsx @@ -29,6 +29,7 @@ export const CaseAttrView = observer(function CaseAttrView (props: ICaseAttrView const { caseId, collection, attrId, unit, value, getDividerBounds, onSetContentElt } = props const cardModel = useCaseCardModel() const data = cardModel?.data + const attr = collection.getAttribute(attrId) const isCollectionSummarized = !!cardModel?.summarizedCollections.includes(collection.id) const displayValue = value ? String(value) : "" const showUnitWithValue = isFiniteNumber(Number(value)) && unit @@ -63,7 +64,7 @@ export const CaseAttrView = observer(function CaseAttrView (props: ICaseAttrView const renderEditableOrSummaryValue = () => { if (isCollectionSummarized) { return ( -
+
{displayValue}
) @@ -71,8 +72,9 @@ export const CaseAttrView = observer(function CaseAttrView (props: ICaseAttrView return ( setIsEditing(true)} diff --git a/v3/src/components/case-table/case-table.scss b/v3/src/components/case-table/case-table.scss index 9bd4adc56f..fbc9d1757d 100644 --- a/v3/src/components/case-table/case-table.scss +++ b/v3/src/components/case-table/case-table.scss @@ -303,6 +303,10 @@ $table-body-font-size: 8pt; } } + &.formula-column { + background-color: rgba(255, 255, 0, 0.2); + } + .cell-color-swatch { width: 100%; height: 100%; diff --git a/v3/src/components/case-table/use-columns.tsx b/v3/src/components/case-table/use-columns.tsx index 053630b24e..41c902fffc 100644 --- a/v3/src/components/case-table/use-columns.tsx +++ b/v3/src/components/case-table/use-columns.tsx @@ -12,6 +12,7 @@ import { kDefaultColumnWidth, TColumn } from "./case-table-types" import CellTextEditor from "./cell-text-editor" import ColorCellTextEditor from "./color-cell-text-editor" import { ColumnHeader } from "./column-header" +import clsx from "clsx" interface IUseColumnsProps { data?: IDataSet @@ -30,7 +31,8 @@ export const useColumns = ({ data, indexColumn }: IUseColumnsProps) => { const collection = data?.getCollection(collectionId) const attrs: IAttribute[] = collection ? getCollectionAttrs(collection, data) : [] const visible: IAttribute[] = attrs.filter(attr => attr && !caseMetadata?.isHidden(attr.id)) - return visible.map(({ id, name, type, userType, isEditable }) => ({ id, name, type, userType, isEditable })) + return visible.map(({ id, name, type, userType, isEditable, hasFormula }) => + ({ id, name, type, userType, isEditable, hasFormula })) }, entries => { // column definitions @@ -38,7 +40,7 @@ export const useColumns = ({ data, indexColumn }: IUseColumnsProps) => { ? [ ...(indexColumn ? [indexColumn] : []), // attribute column definitions - ...entries.map(({ id, name, userType, isEditable }): TColumn => ({ + ...entries.map(({ id, name, userType, isEditable, hasFormula }): TColumn => ({ key: id, name, // If a default column width isn't supplied, RDG defaults to "auto", @@ -47,7 +49,7 @@ export const useColumns = ({ data, indexColumn }: IUseColumnsProps) => { resizable: true, headerCellClass: `codap-column-header`, renderHeaderCell: ColumnHeader, - cellClass: "codap-data-cell", + cellClass: clsx("codap-data-cell", {"formula-column": hasFormula}), renderCell: AttributeValueCell, editable: row => isCaseEditable(data, row.__id__), renderEditCell: isEditable