Skip to content

Commit

Permalink
188118418 v3 DI Update Component webView (#1408)
Browse files Browse the repository at this point in the history
* Add generic and webView update component handlers.

* Move component handler tests into component folders.
  • Loading branch information
tealefristoe authored Aug 15, 2024
1 parent 0408dd8 commit 7372552
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { getSnapshot } from "mobx-state-tree"
import { isCalculatorModel } from "../../components/calculator/calculator-model"
import { kCalculatorIdPrefix } from "../../components/calculator/calculator-registration"
import { DIComponentInfo } from "../../data-interactive/data-interactive-types"
import { diComponentHandler } from "../../data-interactive/handlers/component-handler"
import { testGetComponent } from "../../data-interactive/handlers/component-handler-test-utils"
import { setupTestDataset } from "../../data-interactive/handlers/handler-test-utils"
import { appState } from "../../models/app-state"
import { toV3Id } from "../../utilities/codap-utils"
import { DIComponentInfo } from "../data-interactive-types"
import { diComponentHandler } from "./component-handler"
import { testGetComponent } from "./component-handler-test-utils"
import { setupTestDataset } from "./handler-test-utils"
import { isCalculatorModel } from "./calculator-model"
import { kCalculatorIdPrefix } from "./calculator-registration"

describe("DataInteractive ComponentHandler Calculator", () => {
const handler = diComponentHandler
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { getSnapshot } from "mobx-state-tree"
import { INumericAxisModel } from "../../components/axis/models/axis-model"
import { kGraphIdPrefix } from "../../components/graph/graph-defs"
import "../../components/graph/graph-registration"
import { IGraphContentModel, isGraphContentModel } from "../../components/graph/models/graph-content-model"
import { V2GetGraph } from "../../data-interactive/data-interactive-component-types"
import { DIComponentInfo } from "../../data-interactive/data-interactive-types"
import { diComponentHandler } from "../../data-interactive/handlers/component-handler"
import { setupTestDataset, testCases } from "../../data-interactive/handlers/handler-test-utils"
import { testGetComponent } from "../../data-interactive/handlers/component-handler-test-utils"
import { appState } from "../../models/app-state"
import { toV3Id } from "../../utilities/codap-utils"
import { V2GetGraph } from "../data-interactive-component-types"
import { DIComponentInfo } from "../data-interactive-types"
import { diComponentHandler } from "./component-handler"
import { setupTestDataset, testCases } from "./handler-test-utils"
import { testGetComponent } from "./component-handler-test-utils"
import { INumericAxisModel } from "../axis/models/axis-model"
import { kGraphIdPrefix } from "./graph-defs"
import "./graph-registration"
import { IGraphContentModel, isGraphContentModel } from "./models/graph-content-model"

describe("DataInteractive ComponentHandler Graph", () => {
const handler = diComponentHandler
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { getSnapshot } from "mobx-state-tree"
import { kMapIdPrefix } from "../../components/map/map-defs"
import "../../components/map/map-registration"
import { IMapContentModel, isMapContentModel } from "../../components/map/models/map-content-model"
import { V2Map } from "../../data-interactive/data-interactive-component-types"
import { DIComponentInfo } from "../../data-interactive/data-interactive-types"
import { diComponentHandler } from "../../data-interactive/handlers/component-handler"
import { testGetComponent } from "../../data-interactive/handlers/component-handler-test-utils"
import { setupTestDataset } from "../../data-interactive/handlers/handler-test-utils"
import { appState } from "../../models/app-state"
import { toV3Id } from "../../utilities/codap-utils"
import { V2Map } from "../data-interactive-component-types"
import { DIComponentInfo } from "../data-interactive-types"
import { diComponentHandler } from "./component-handler"
import { testGetComponent } from "./component-handler-test-utils"
import { setupTestDataset } from "./handler-test-utils"
import { kMapIdPrefix } from "./map-defs"
import "./map-registration"
import { IMapContentModel, isMapContentModel } from "./models/map-content-model"


describe("DataInteractive ComponentHandler Map", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { ISliderModel, isSliderModel } from "../../components/slider/slider-model"
import { kSliderIdPrefix } from "../../components/slider/slider-registration"
import { AnimationDirections, AnimationModes } from "../../components/slider/slider-types"
import { V2GetSlider } from "../../data-interactive/data-interactive-component-types"
import { DIComponentInfo } from "../../data-interactive/data-interactive-types"
import { diComponentHandler } from "../../data-interactive/handlers/component-handler"
import { testGetComponent } from "../../data-interactive/handlers/component-handler-test-utils"
import { appState } from "../../models/app-state"
import { getGlobalValueManager, getSharedModelManager } from "../../models/tiles/tile-environment"
import { toV3Id } from "../../utilities/codap-utils"
import { V2GetSlider } from "../data-interactive-component-types"
import { DIComponentInfo } from "../data-interactive-types"
import { diComponentHandler } from "./component-handler"
import { testGetComponent } from "./component-handler-test-utils"
import { ISliderModel, isSliderModel } from "./slider-model"
import { kSliderIdPrefix } from "./slider-registration"
import { AnimationDirections, AnimationModes } from "./slider-types"


describe("DataInteractive ComponentHandler Slider", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { kV2GameType } from "../../components/web-view/web-view-defs"
import { IWebViewModel, isWebViewModel } from "../../components/web-view/web-view-model"
import { kWebViewIdPrefix } from "../../components/web-view/web-view-registration"
import { kTitleBarHeight } from "../constants"
import { V2Game, V2WebView } from "../../data-interactive/data-interactive-component-types"
import { DIComponentInfo } from "../../data-interactive/data-interactive-types"
import { diComponentHandler } from "../../data-interactive/handlers/component-handler"
import { testGetComponent } from "../../data-interactive/handlers/component-handler-test-utils"
import { appState } from "../../models/app-state"
import { isFreeTileRow } from "../../models/document/free-tile-row"
import { toV3Id } from "../../utilities/codap-utils"
import { V2Game, V2WebView } from "../data-interactive-component-types"
import { DIComponentInfo } from "../data-interactive-types"
import { diComponentHandler } from "./component-handler"
import { testGetComponent } from "./component-handler-test-utils"

import { kV2GameType } from "./web-view-defs"
import { IWebViewModel, isWebViewModel } from "./web-view-model"
import {
kDefaultWebViewHeight, kDefaultWebViewWidth, kWebViewIdPrefix
} from "./web-view-registration"

describe("DataInteractive ComponentHandler WebView and Game", () => {
const handler = diComponentHandler
const documentContent = appState.document.content!

it("create and get webView and game work", () => {
it("create, get, and update webView and game work", () => {
// Create a blank webView
expect(documentContent.tileMap.size).toBe(0)
const result = handler.create!({}, { type: "webView" })
Expand Down Expand Up @@ -46,6 +49,31 @@ describe("DataInteractive ComponentHandler WebView and Game", () => {
expect(URL).toBe((webViewTile.content as IWebViewModel).url)
})

// Update webView
expect(tile2.cannotClose).toBe(false)
expect(tile2.title).toBe("Web Page")
const row = appState.document.content?.findRowContainingTile(tile2.id)
const freeTileRow = row && isFreeTileRow(row) ? row : undefined
const tileLayout = freeTileRow?.getNode(tile2.id)
expect(tileLayout?.x).toBe(100)
expect(tileLayout?.y).toBe(100)
expect(tileLayout?.height).toBe(kDefaultWebViewHeight + kTitleBarHeight)
expect(tileLayout?.width).toBe(kDefaultWebViewWidth)
const newValue = 50
const title = "New Title"
expect(handler.update?.({ component: tile2 }, {
cannotClose: true,
dimensions: { height: newValue, width: newValue },
position: { left: newValue, top: newValue },
title
}).success).toBe(true)
expect(tile2.cannotClose).toBe(true)
expect(tile2.title).toBe(title)
expect(tileLayout?.x).toBe(newValue)
expect(tileLayout?.y).toBe(newValue)
expect(tileLayout?.height).toBe(newValue)
expect(tileLayout?.width).toBe(newValue)

// Create game with url
const multidataUrl = "https://codap.concord.org/multidata-plugin/"
const result3 = handler.create!({}, { type: "game", URL: multidataUrl })
Expand Down
10 changes: 10 additions & 0 deletions v3/src/components/web-view/web-view-registration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,21 @@ const webViewComponentHandler: DIComponentHandler = {
const { URL } = values as V2WebView
return { content: { type: kWebViewTileType, url: URL } as SetRequired<IWebViewSnapshot, "type"> }
},

get(content) {
if (isWebViewModel(content)) {
const type = content.isPlugin ? kV2GameType : kV2WebViewType
return { type, URL: content.url } as V2Game | V2WebView
}
},

update(content, values) {
if (isWebViewModel(content)) {
const { URL } = values as V2WebView
if (URL) content.setUrl(URL)
}

return { success: true }
}
}
registerComponentHandler(kV2GameType, webViewComponentHandler)
Expand Down
30 changes: 23 additions & 7 deletions v3/src/data-interactive/handlers/component-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,30 @@ export const diComponentHandler: DIHandler = {

if (!values) return valuesRequiredResult

const v2Type = getTileContentInfo(content.type)?.getV2Type?.(content) ?? kComponentTypeV3ToV2Map[content.type]
const handler = diComponentHandlers.get(v2Type)
if (handler) {
// TODO: better error message?
return handler.update?.(content, values) ?? errorResult(t("V3.DI.Error.notFound"))
}
let result: DIHandlerFnResult | undefined
component.applyModelChange(() => {
// Handle updating generic component features
const { cannotClose, dimensions, position, title } = values as V2Component
if (cannotClose != null) component.setCannotClose(cannotClose)
if (title) component.setTitle(title)
// TODO Handle string positions?
const _position = position && typeof position !== "string" ? position : undefined
if (dimensions || _position) {
const row = appState.document.content?.findRowContainingTile(component.id)
const freeTileRow = row && isFreeTileRow(row) ? row : undefined
if (dimensions) freeTileRow?.setTileDimensions(component.id, dimensions)
if (_position) freeTileRow?.setTilePosition(component.id, { x: _position.left, y: _position.top })
}

// Handle updating type specific features
const v2Type = getTileContentInfo(content.type)?.getV2Type?.(content) ?? kComponentTypeV3ToV2Map[content.type]
const handler = diComponentHandlers.get(v2Type)
if (handler) {
result = handler.update?.(content, values) ?? { success: true }
}
})

return errorResult(t("V3.DI.Error.unsupportedComponent", { vars: [content.type] }))
return result ?? errorResult(t("V3.DI.Error.unsupportedComponent", { vars: [content.type] }))
}
}

Expand Down
7 changes: 7 additions & 0 deletions v3/src/models/document/free-tile-row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ export const FreeTileRow = TileRowModel
setTileDimensions(tileId: string, dimensions: { width?: number, height?: number }) {
const freeTileLayout = self.getNode(tileId)
freeTileLayout?.setSize(dimensions.width, dimensions.height)
},
setTilePosition(tileId: string, position: { x?: number, y?: number }) {
const freeTileLayout = self.getNode(tileId)
if (freeTileLayout && (position.x != null || position.y != null)) {
const { x = freeTileLayout.x, y = freeTileLayout.y } = position
freeTileLayout?.setPosition(x, y)
}
}
}))
export interface IFreeTileRow extends Instance<typeof FreeTileRow> {}
Expand Down

0 comments on commit 7372552

Please sign in to comment.