Skip to content

Commit

Permalink
Adds tile list menu to tile list toolshelf button (#1346)
Browse files Browse the repository at this point in the history
* Adds tile list menu to tile list toolshelf button

* Fixes bug where all tile show Web Page when there is no data context

PR Fixes

* Changes Tiles toolshelf button data-testid

* Adds cypress test for Tile toolshelf button

* toolshelf test linting

* Fixes jest tests because of the change in tile content info  model

* Adds the functions  to return the component title from the component registration

* Update case card and case table getTitle returned value

* Fixes webview icon size in the tiles list menu

* Gets getTitle function from component content registration instead of individual components

* Removes graph title when there is no data context

Fixes broken cypress test

* Clean up

Case table gets title for tile or from dataset

Changing case table title changes title in both dataset and tile model.

* Clean up linting errors

* More cleanup

* Fixes case table/case card title in table menu.

Removes code that accesses table tile title directly

* Fixes broken Cypress test

* chore: code review tweaks

* PR Fixes

* PR Fix

Adds a box shadow on the component when it is focused, or when it is hovered over in the tile list menu

* Creates a utitlity function that returns the function for getting the componenet title.

PR Fixes

* Fix double declaration

* Fixes failing cypress test

---------

Co-authored-by: Kirk Swenson <[email protected]>
  • Loading branch information
eireland and kswenson authored Jul 24, 2024
1 parent 4abef72 commit 119b070
Show file tree
Hide file tree
Showing 36 changed files with 258 additions and 54 deletions.
8 changes: 4 additions & 4 deletions v3/cypress/e2e/graph.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,14 @@ context("Graph UI", () => {
table.getGridCell(2, 2).should("contain", "African Elephant")
cy.log("double-clicking the cell")
// double-click to initiate editing cell
table.getGridCell(3, 4).dblclick()
table.getGridCell(3, 4).find("input").type("700{enter}")
table.getGridCell(3, 4).click().dblclick()
cy.get("[data-testid=cell-text-editor]").type("700{enter}")

table.getGridCell(2, 2).should("contain", "African Elephant")
cy.log("double-clicking the cell")
// double-click to initiate editing cell
table.getGridCell(3, 5).dblclick()
table.getGridCell(3, 5).find("input").type("300{enter}")
table.getGridCell(3, 5).click().dblclick()
cy.get("[data-testid=cell-text-editor]").type("300{enter}")

// get the rescale button
c.getComponentTitle("graph").should("have.text", collectionName).click()
Expand Down
2 changes: 1 addition & 1 deletion v3/cypress/e2e/plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ context("codap plugins", () => {
cy.log("Broadcast deleteCollection notifications when deleting the final attribute")
cfm.openExampleDocument("Four Seals")
cy.wait(2000)
table.getTableTile().should("contain.text", "Data_Set_1")
table.getTableTile().should("contain.text", "Tracks/Measurements")
table.deleteAttrbute("species")
openAPITester()
webView.toggleAPITesterFilter()
Expand Down
49 changes: 45 additions & 4 deletions v3/cypress/e2e/toolbar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ context("codap toolbar", () => {
it("will open a graph", () => {
c.getIconFromToolshelf("graph").click()
graph.getGraphTile().should("be.visible")
c.getComponentTitle("graph").should("have.text", "New Dataset")
// graphs with no associated data set should not have a title
c.getComponentTitle("graph").should("have.text", "")
})
it("will open a map", () => {
c.getIconFromToolshelf("map").click()
Expand All @@ -50,9 +51,7 @@ context("codap toolbar", () => {
})
it('will display a webpage', ()=>{
const url='https://www.wikipedia.org'
let deleteUrl = ""
for (let i = 0; i < url.length; i++) deleteUrl += "{backspace}"
const url2=`${deleteUrl}https://en.wikipedia.org/wiki/Concord_Consortium`
const url2='https://en.wikipedia.org/wiki/Concord_Consortium'
toolbar.getOptionsButton().click()
toolbar.getWebViewButton().click()
webView.getUrlModal().should("exist")
Expand All @@ -66,4 +65,46 @@ context("codap toolbar", () => {
cy.wait(1000)
webView.getIFrame().find(`.mw-page-title-main`).should("contain.text", "Concord Consortium")
})
it('will show a list of open tiles when there is no data context', ()=>{
// Don't open a table as this automatically creates a data context
c.getIconFromToolshelf("graph").click()
c.getIconFromToolshelf("map").click()
c.getIconFromToolshelf("slider").click()
c.getIconFromToolshelf("calc").click()
c.getIconFromToolshelf("plugins").click()
toolbar.getPluginSelection().eq(0).click()
//TODO need to add check for Text component
toolbar.getTilesButton().click()
toolbar.getTilesListMenu().should("be.visible")
toolbar.getTilesListMenuItem().should("have.length", 5)

toolbar.getTilesListMenuItem().eq(0).should("have.text", "")
toolbar.getTilesListMenuIcon().eq(0).should("have.class", "Graph")
toolbar.getTilesListMenuItem().eq(1).should("have.text", "Map")
toolbar.getTilesListMenuIcon().eq(1).should("have.class", "Map")
toolbar.getTilesListMenuItem().eq(2).should("have.text", "v1")
toolbar.getTilesListMenuIcon().eq(2).should("have.class", "CodapSlider")
toolbar.getTilesListMenuItem().eq(3).should("have.text", "Calculator")
toolbar.getTilesListMenuIcon().eq(3).should("have.class", "Calculator")
toolbar.getTilesListMenuItem().eq(4).should("have.text", "Sampler")
toolbar.getTilesListMenuIcon().eq(4).should("have.class", "WebView")
})
it('will show correct title for a new table', ()=>{
c.getIconFromToolshelf("table").click()
toolbar.getNewCaseTable().click()
toolbar.getTilesButton().click()
toolbar.getTilesListMenu().should("be.visible")
toolbar.getTilesListMenuItem().should("have.length", 1)
toolbar.getTilesListMenuItem().eq(0).should("have.text", "New Dataset")
toolbar.getTilesListMenuIcon().eq(0).should("have.class", "CaseTable")
})
it('will show a list of open tiles when there is a data context', ()=>{
cy.visit("#file=examples:Four%20Seals")
toolbar.getTilesButton().click()
toolbar.getTilesListMenu().should("be.visible")
toolbar.getTilesListMenuItem().should("have.length", 3)
toolbar.getTilesListMenuItem().eq(0).should("have.text", "Tracks/Measurements")
toolbar.getTilesListMenuItem().eq(1).should("have.text", "Measurements")
toolbar.getTilesListMenuItem().eq(2).should("have.text", "Measurements")
})
})
12 changes: 12 additions & 0 deletions v3/cypress/support/elements/toolbar-elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ export const ToolbarElements = {
getConfirmDeleteDatasetModal() {
return cy.get(`[data-testid=delete-data-set-button-delete]`)
},
getTilesButton() {
return cy.get(`[data-testid=tool-shelf-button-tiles]`)
},
getTilesListMenu() {
return cy.get(`[data-testid=tiles-list-menu]`)
},
getTilesListMenuItem() {
return cy.get(`[data-testid=tiles-list-menu-item]`)
},
getTilesListMenuIcon() {
return cy.get(`[data-testid=tile-list-menu-icon]`)
},
getOptionsButton() {
return cy.get(`[data-testid=tool-shelf-button-options]`)
},
Expand Down
1 change: 1 addition & 0 deletions v3/cypress/support/elements/web-view-tile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const WebViewTileElements = {
return cy.get(`.chakra-modal__content`)
},
enterUrl(url: string) {
cy.get(`[data-testid=web-view-url-input]`).clear()
cy.get(`[data-testid=web-view-url-input]`).type(url)
cy.get(`[data-testid=OK-button]`).click()
},
Expand Down
8 changes: 6 additions & 2 deletions v3/src/components/calculator/calculator-registration.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { registerTileComponentInfo } from "../../models/tiles/tile-component-info"
import { registerTileContentInfo } from "../../models/tiles/tile-content-info"
import { ITileLikeModel, registerTileContentInfo } from "../../models/tiles/tile-content-info"
import { ITileModelSnapshotIn } from "../../models/tiles/tile-model"
import { CalculatorComponent } from "./calculator"
import { kCalculatorTileClass, kCalculatorTileType } from "./calculator-defs"
Expand All @@ -9,6 +9,7 @@ import CalcIcon from '../../assets/icons/icon-calc.svg'
import { toV3Id } from "../../utilities/codap-utils"
import { registerV2TileImporter } from "../../v2/codap-v2-tile-importers"
import { isV2CalculatorComponent } from "../../v2/codap-v2-types"
import { t } from "../../utilities/translation/translate"

export const kCalculatorIdPrefix = "CALC"

Expand All @@ -17,7 +18,10 @@ registerTileContentInfo({
prefix: kCalculatorIdPrefix,
modelClass: CalculatorModel,
defaultContent: () => ({ type: kCalculatorTileType }),
isSingleton: true
isSingleton: true,
getTitle: (tile: ITileLikeModel) => {
return tile.title || t("DG.DocumentController.calculatorTitle")
}
})

registerTileComponentInfo({
Expand Down
5 changes: 2 additions & 3 deletions v3/src/components/calculator/calculator-title-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import React, { useCallback } from "react"
import { observer } from "mobx-react-lite"
import { ComponentTitleBar } from "../component-title-bar"
import { useDocumentContent } from "../../hooks/use-document-content"
import { t } from "../../utilities/translation/translate"
import { ITileTitleBarProps } from "../tiles/tile-base-props"
import { kCalculatorTileType } from "./calculator-defs"
import { getTitle } from "../../models/tiles/tile-content-info"

export const CalculatorTitleBar =
observer(function CalculatorTitleBar({ tile, onCloseTile, ...others }: ITileTitleBarProps) {
const getTitle = () => tile?.title || t("DG.DocumentController.calculatorTitle")
const documentContent = useDocumentContent()
const closeCalculator = useCallback(() => {
documentContent?.applyModelChange(() => {
Expand All @@ -19,6 +18,6 @@ export const CalculatorTitleBar =
})
}, [documentContent])
return (
<ComponentTitleBar tile={tile} getTitle={getTitle} onCloseTile={closeCalculator} {...others} />
<ComponentTitleBar tile={tile} getTitle={getTitle(tile)} onCloseTile={closeCalculator} {...others} />
)
})
6 changes: 6 additions & 0 deletions v3/src/components/case-card/case-card-registration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { kCaseCardTileType } from "./case-card-defs"
import { CaseCardModel } from "./case-card-model"
import { CaseTableCardTitleBar } from "../case-table-card-common/case-table-card-title-bar"
import CardIcon from '../../assets/icons/icon-case-card.svg'
import { t } from "../../utilities/translation/translate"
import { getTileDataSet } from "../../models/shared/shared-data-utils"
/*
import { CaseCardInspector } from "./case-card-inspector"
*/
Expand All @@ -16,6 +18,10 @@ registerTileContentInfo({
prefix: kCaseCardIdPrefix,
modelClass: CaseCardModel,
defaultContent: () => ({ type: kCaseCardTileType }),
getTitle: (tile) => {
const data = tile.content && getTileDataSet(tile.content)
return data?.title || t("DG.DocumentController.caseTableTitle")
},
hideOnClose: true
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { kCaseTableTileType } from "../case-table/case-table-defs"
import { ComponentTitleBar } from "../component-title-bar"
import { ITileTitleBarProps } from "../tiles/tile-base-props"
import { toggleCardTable } from "./case-table-card-utils"
import { getTitle } from "../../models/tiles/tile-content-info"

import "./case-table-card-title-bar.scss"

Expand Down Expand Up @@ -56,8 +57,6 @@ export const CaseTableCardTitleBar =
observer(function CaseTableTitleBar({tile, onCloseTile, ...others}: ITileTitleBarProps) {
const tileInfo = getTileInfo(tile?.content.type)
const data = tile?.content && getTileDataSet(tile?.content)
// title reflects DataSet title
const getTitle = () => data?.title ?? ""
const [showSwitchMessage, setShowSwitchMessage] = useState(false)
const cardTableToggleRef = useRef(null)
const documentContent = useDocumentContent()
Expand Down Expand Up @@ -112,7 +111,7 @@ export const CaseTableCardTitleBar =
const cardOrTableIconClass = tileInfo.iconClass

return (
<ComponentTitleBar tile={tile} getTitle={getTitle} {...others}
<ComponentTitleBar tile={tile} getTitle={getTitle(tile)} {...others}
onHandleTitleChange={handleChangeTitle} onCloseTile={closeCaseTableOrCard}
preventTitleChange={preventTitleChange}>
<div className="header-left"
Expand Down
6 changes: 6 additions & 0 deletions v3/src/components/case-table/case-table-registration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { registerV2TileImporter } from "../../v2/codap-v2-tile-importers"
import { isCodapV2Attribute, isV2TableComponent } from "../../v2/codap-v2-types"
import { CaseTableInspector } from "./case-table-inspector"
import { CaseTableToolShelfButton } from "./case-table-tool-shelf-button"
import { getTileDataSet } from "../../models/shared/shared-data-utils"
import { t } from "../../utilities/translation/translate"

export const kCaseTableIdPrefix = "TABL"

Expand All @@ -20,6 +22,10 @@ registerTileContentInfo({
prefix: kCaseTableIdPrefix,
modelClass: CaseTableModel,
defaultContent: () => ({ type: kCaseTableTileType }),
getTitle: (tile) => {
const data = tile.content && getTileDataSet(tile.content)
return data?.title || t("DG.DocumentController.caseTableTitle")
},
hideOnClose: true
})

Expand Down
3 changes: 3 additions & 0 deletions v3/src/components/codap-component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ $corner-drag-size: calc($border-drag-width * 2);
height: 100%;
border-radius: vars.$border-radius-four-corners;
// z-index: 20;
&.shadowed {
box-shadow: 0 1px 20px 0 rgba(0, 0, 0, 0.4);
}

input {
&:focus {
Expand Down
3 changes: 2 additions & 1 deletion v3/src/components/codap-component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export const CodapComponent = observer(function CodapComponent({
if (!info) return null

const { TitleBar, Component, tileEltClass, isFixedWidth, isFixedHeight } = info
const classes = clsx("codap-component", tileEltClass, { minimized: isMinimized })
const classes = clsx("codap-component", tileEltClass, { minimized: isMinimized },
{ shadowed: uiState.isFocusedTile(tile.id) || uiState.isHoveredTile(tile.id) })
return (
<TileModelContext.Provider value={tile}>
<div className={classes} key={tile.id} data-testid={tileEltClass}
Expand Down
2 changes: 1 addition & 1 deletion v3/src/components/component-title-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const ComponentTitleBar = observer(function ComponentTitleBar({
tile, getTitle, children, onHandleTitleChange, onMinimizeTile, onCloseTile, preventTitleChange
}: ITileTitleBarProps) {
// perform all title-related model access here so only title is re-rendered when properties change
const title = getTitle?.() || tile?.title || t("DG.AppController.createDataSet.name")
const title = (tile && getTitle?.(tile)) || tile?.title || ""
const [isEditing, setIsEditing] = useState(false)
const [editingTitle, setEditingTitle] = useState(title)
const tileId = tile?.id || ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import React from "react"
import { ComponentTitleBar } from "../../component-title-bar"
import { observer } from "mobx-react-lite"
import { ITileTitleBarProps } from "../../tiles/tile-base-props"
import {isGraphContentModel} from "../models/graph-content-model"
import { getTitle } from "../../../models/tiles/tile-content-info"

export const GraphComponentTitleBar = observer(function GraphComponentTitleBar(props: ITileTitleBarProps) {
const {tile, ...others} = props
const data = isGraphContentModel(tile?.content) ? tile?.content.dataset : undefined
const getTitle = () => tile?.title || data?.name

return (
<ComponentTitleBar tile={tile} getTitle={getTitle} {...others} />
<ComponentTitleBar tile={tile} getTitle={getTitle(tile)} {...others} />
)
})
8 changes: 6 additions & 2 deletions v3/src/components/graph/graph-registration.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { SetRequired } from "type-fest"
import { registerTileComponentInfo } from "../../models/tiles/tile-component-info"
import { registerTileContentInfo } from "../../models/tiles/tile-content-info"
import { ITileLikeModel, registerTileContentInfo } from "../../models/tiles/tile-content-info"
import { kGraphIdPrefix, kGraphTileClass, kGraphTileType } from "./graph-defs"
import { SharedDataSet } from "../../models/shared/shared-data-set"
import { getSharedCaseMetadataFromDataset } from "../../models/shared/shared-data-utils"
import { GraphContentModel, IGraphContentModelSnapshot } from "./models/graph-content-model"
import { GraphContentModel, IGraphContentModelSnapshot, isGraphContentModel } from "./models/graph-content-model"
import { kGraphDataConfigurationType } from "./models/graph-data-configuration-model"
import { kGraphPointLayerType } from "./models/graph-point-layer-model"
import { GraphComponentTitleBar } from "./components/graph-component-title-bar"
Expand Down Expand Up @@ -36,6 +36,10 @@ registerTileContentInfo({
}]
}
return graphTileSnapshot
},
getTitle: (tile: ITileLikeModel) => {
const data = isGraphContentModel(tile?.content) ? tile.content.dataset : undefined
return tile.title || data?.title || ""
}
})

Expand Down
5 changes: 2 additions & 3 deletions v3/src/components/map/components/map-component-title-bar.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import React from "react"
import { t } from "../../../utilities/translation/translate"
import { ComponentTitleBar } from "../../component-title-bar"
import { observer } from "mobx-react-lite"
import { ITileTitleBarProps } from "../../tiles/tile-base-props"
import { getTitle } from "../../../models/tiles/tile-content-info"

export const MapComponentTitleBar = observer(function MapComponentTitleBar(props: ITileTitleBarProps) {
const {tile, ...others} = props
const getTitle = () => tile?.title || t("DG.DocumentController.mapTitle")

return (
<ComponentTitleBar tile={tile} getTitle={getTitle} {...others} />
<ComponentTitleBar tile={tile} getTitle={getTitle(tile)} {...others} />
)
})
8 changes: 6 additions & 2 deletions v3/src/components/map/map-registration.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { registerTileComponentInfo } from "../../models/tiles/tile-component-info"
import { registerTileContentInfo } from "../../models/tiles/tile-content-info"
import { ITileLikeModel, registerTileContentInfo } from "../../models/tiles/tile-content-info"
import {kMapIdPrefix, kMapTileClass, kMapTileType} from "./map-defs"
import {kDefaultMapHeight, kDefaultMapWidth} from "./map-types"
import MapIcon from "../../assets/icons/icon-map.svg"
Expand All @@ -9,13 +9,17 @@ import {MapComponent} from "./components/map-component"
import {MapInspector} from "./components/map-inspector"
import {registerV2TileImporter} from "../../v2/codap-v2-tile-importers"
import {v2MapImporter} from "./v2-map-importer"
import { t } from "../../utilities/translation/translate"


registerTileContentInfo({
type: kMapTileType,
prefix: kMapIdPrefix,
modelClass: MapContentModel,
defaultContent: () => createMapContentModel()
defaultContent: () => createMapContentModel(),
getTitle: (tile: ITileLikeModel) => {
return tile.title || t("DG.DocumentController.mapTitle")
}
})

registerTileComponentInfo({
Expand Down
12 changes: 10 additions & 2 deletions v3/src/components/slider/slider-registration.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SetRequired } from "type-fest"
import { registerTileComponentInfo } from "../../models/tiles/tile-component-info"
import { registerTileContentInfo } from "../../models/tiles/tile-content-info"
import { ITileLikeModel, registerTileContentInfo } from "../../models/tiles/tile-content-info"
import { getGlobalValueManager } from "../../models/tiles/tile-environment"
import { ITileModelSnapshotIn } from "../../models/tiles/tile-model"
import { toV3GlobalId, toV3Id } from "../../utilities/codap-utils"
Expand All @@ -9,11 +9,13 @@ import { isV2SliderComponent } from "../../v2/codap-v2-types"
import { SliderComponent } from "./slider-component"
import { SliderInspector } from "./slider-inspector"
import { kSliderTileType, kSliderTileClass } from "./slider-defs"
import { ISliderSnapshot, SliderModel } from "./slider-model"
import { ISliderSnapshot, SliderModel, isSliderModel } from "./slider-model"
import { SliderTitleBar } from "./slider-title-bar"
import { AnimationDirections, AnimationModes, kDefaultAnimationDirection, kDefaultAnimationMode } from "./slider-types"
import SliderIcon from '../../assets/icons/icon-slider.svg'
import { kDefaultSliderName, kDefaultSliderValue } from "./slider-utils"
import { t } from "../../utilities/translation/translate"
import { isAliveSafe } from "../../utilities/mst-utils"

export const kSliderIdPrefix = "SLID"

Expand All @@ -31,6 +33,12 @@ registerTileContentInfo({
type: kSliderTileType, globalValue: globalValue?.id ?? ""
}
return sliderTileSnap
},
getTitle: (tile: ITileLikeModel) => {
const { title, content } = tile || {}
const sliderModel = isAliveSafe(content) && isSliderModel(content) ? content : undefined
const { name } = sliderModel || {}
return title || name || t("DG.DocumentController.sliderTitle")
}
})

Expand Down
Loading

0 comments on commit 119b070

Please sign in to comment.