diff --git a/v3/src/components/graph/graph-registration.ts b/v3/src/components/graph/graph-registration.ts index 78c7393009..5eeb5b48a8 100644 --- a/v3/src/components/graph/graph-registration.ts +++ b/v3/src/components/graph/graph-registration.ts @@ -4,7 +4,7 @@ import GraphIcon from "../../assets/icons/icon-graph.svg" import { registerComponentHandler } from "../../data-interactive/handlers/component-handler" import { registerDataDisplayHandler } from "../../data-interactive/handlers/data-display-handler" import { idOfChildmostCollectionForAttributes } from "../../models/data/data-set-utils" -import { SharedDataSet } from "../../models/shared/shared-data-set" +import { ISharedDataSet, SharedDataSet } from "../../models/shared/shared-data-set" import { getMetadataFromDataSet } from "../../models/shared/shared-data-utils" import { registerTileComponentInfo } from "../../models/tiles/tile-component-info" import { ITileLikeModel, registerTileContentInfo } from "../../models/tiles/tile-content-info" @@ -36,19 +36,42 @@ registerTileContentInfo({ prefix: kGraphIdPrefix, modelClass: GraphContentModel, defaultContent: options => { - // auto-connect to data set if there's only one available const sharedModelManager = options?.env?.sharedModelManager const sharedDataSets = sharedModelManager?.getSharedModelsByType("SharedDataSet") - const onlyDataSet = sharedDataSets?.length === 1 ? sharedDataSets[0].dataSet : undefined - const onlyMetadata = onlyDataSet && getMetadataFromDataSet(onlyDataSet) + + // Determine which dataset to auto-connect to, if any + let targetSharedDataSet: ISharedDataSet | undefined + if (sharedDataSets?.length === 1) { + // auto-connect to data set if there's only one available + targetSharedDataSet = sharedDataSets[0] + } else if (sharedDataSets && sharedDataSets.length > 1) { + // if multiple datasets exist, use the one with a visible table or card (if exactly one qualifies) + const content = options?.documentContent + const datasetsWithVisibleTiles = sharedDataSets.filter(sds => { + const metadata = getMetadataFromDataSet(sds.dataSet) + if (!metadata) return false + const { caseTableTileId, caseCardTileId } = metadata + const hasVisibleTable = !!(caseTableTileId && content?.getTile(caseTableTileId) + && !content?.isTileHidden(caseTableTileId)) + const hasVisibleCard = !!(caseCardTileId && content?.getTile(caseCardTileId) + && !content?.isTileHidden(caseCardTileId)) + return hasVisibleTable || hasVisibleCard + }) + if (datasetsWithVisibleTiles.length === 1) { + targetSharedDataSet = datasetsWithVisibleTiles[0] + } + } + + const targetDataSet = targetSharedDataSet?.dataSet + const targetMetadata = targetDataSet && getMetadataFromDataSet(targetDataSet) const graphTileSnapshot: SetRequired = { type: kGraphTileType, layers: [{ type: kGraphPointLayerType, dataConfiguration: { type: kGraphDataConfigurationType, - dataset: onlyDataSet?.id, - metadata: onlyMetadata?.id + dataset: targetDataSet?.id, + metadata: targetMetadata?.id } }] } diff --git a/v3/src/models/codap/add-default-content.ts b/v3/src/models/codap/add-default-content.ts index 73dda76832..7bcf29fdf6 100644 --- a/v3/src/models/codap/add-default-content.ts +++ b/v3/src/models/codap/add-default-content.ts @@ -19,7 +19,7 @@ type ILayoutOptions = IFreeTileInRowOptions | IMosaicTileInRowOptions | undefine export function createDefaultTileOfType(tileType: string, options?: INewTileOptions) { const env = getTileEnvironment(appState.document) - return createTileOfType(tileType, env, options) + return createTileOfType(tileType, env, appState.document.content, options) } export function addDefaultComponents() { diff --git a/v3/src/models/codap/create-tile.ts b/v3/src/models/codap/create-tile.ts index 8aa0b47eaa..371544ffb4 100644 --- a/v3/src/models/codap/create-tile.ts +++ b/v3/src/models/codap/create-tile.ts @@ -1,7 +1,7 @@ import { v3Id } from "../../utilities/codap-utils" import { ITileContentSnapshotWithType } from "../tiles/tile-content" -import { getTileContentInfo } from "../tiles/tile-content-info" +import { getTileContentInfo, IDocumentContentLike } from "../tiles/tile-content-info" import { ITileEnvironment } from "../tiles/tile-environment" import { TileModel } from "../tiles/tile-model" @@ -20,18 +20,24 @@ export interface INewTileOptions { width?: number } -export function createTileSnapshotOfType(tileType: string, env?: ITileEnvironment, options?: INewTileOptions) { +export function createTileSnapshotOfType( + tileType: string, env?: ITileEnvironment, + documentContent?: IDocumentContentLike, options?: INewTileOptions +) { const info = getTileContentInfo(tileType) const id = v3Id(info?.prefix || "TILE") const name = options?.name ?? info?.defaultName?.({ env }) - const content = options?.content ?? info?.defaultContent({ env }) + const content = options?.content ?? info?.defaultContent({ env, documentContent }) const cannotClose = options?.cannotClose const title = options?.title return content ? { cannotClose, content, id, name, title } : undefined } -export function createTileOfType(tileType: string, env?: ITileEnvironment, options?: INewTileOptions) { - const snapshot = createTileSnapshotOfType(tileType, env, options) +export function createTileOfType( + tileType: string, env?: ITileEnvironment, + documentContent?: IDocumentContentLike, options?: INewTileOptions +) { + const snapshot = createTileSnapshotOfType(tileType, env, documentContent, options) const tile = snapshot ? TileModel.create(snapshot) : undefined if (tile && options?.markNewlyCreated) { tile.setNewlyCreated(true) diff --git a/v3/src/models/document/document-content.ts b/v3/src/models/document/document-content.ts index 23b1cadf8c..6bfc7b82d8 100644 --- a/v3/src/models/document/document-content.ts +++ b/v3/src/models/document/document-content.ts @@ -138,6 +138,23 @@ export const DocumentContentModel = BaseDocumentContentModel } } })) + .views(self => ({ + isTileHidden(tileId?: string) { + if (tileId) { + const tileLayout = self.getTileLayoutById(tileId) + if (isFreeTileLayout(tileLayout)) { + return !!tileLayout.isHidden + } + } + return false + }, + get gaussianFitEnabled() { + return self._gaussianFitEnabled || urlParams.gaussianFit !== undefined + }, + get iciEnabled() { + return urlParams.ICI !== undefined + } + })) .actions(self => ({ createDataSet(snapshot?: IDataSetSnapshot, providerId?: string) { const sharedModelManager = getSharedModelManager(self) @@ -168,7 +185,7 @@ export const DocumentContentModel = BaseDocumentContentModel const row = self.getRowByIndex(0) if (row) { const env = getTileEnvironment(self) - const newTileSnapshot = createTileSnapshotOfType(tileType, env, options) + const newTileSnapshot = createTileSnapshotOfType(tileType, env, self, options) if (newTileSnapshot) { if (isFreeTileRow(row)) { const newTileSize = {width, height} @@ -184,23 +201,6 @@ export const DocumentContentModel = BaseDocumentContentModel } } })) - .views(self => ({ - isTileHidden(tileId?: string) { - if (tileId) { - const tileLayout = self.getTileLayoutById(tileId) - if (isFreeTileLayout(tileLayout)) { - return !!tileLayout.isHidden - } - } - return false - }, - get gaussianFitEnabled() { - return self._gaussianFitEnabled || urlParams.gaussianFit !== undefined - }, - get iciEnabled() { - return urlParams.ICI !== undefined - } - })) .actions(self => ({ toggleSingletonTileVisibility(tileType: string, options?: INewTileOptions) { const tiles = self?.getTilesOfType(tileType) diff --git a/v3/src/models/tiles/tile-content-info.ts b/v3/src/models/tiles/tile-content-info.ts index f91e8448a0..0fdc5ab59d 100644 --- a/v3/src/models/tiles/tile-content-info.ts +++ b/v3/src/models/tiles/tile-content-info.ts @@ -10,9 +10,17 @@ export interface ITileLikeModel { content: ITileContentModel } +// Avoids circular dependency on IDocumentContentModel +export interface IDocumentContentLike { + getTile(tileId: string): Maybe + isTileHidden(tileId?: string): boolean +} + export interface IDefaultContentOptions { // environment in which the tile will be created env?: ITileEnvironment; + // document content for tile visibility checks during auto-connection + documentContent?: IDocumentContentLike; // title is only currently used by the Geometry and Table tiles title?: string; // url is added so the CLUE core can add an image tile to the document when a user