diff --git a/cypress/e2e/dashboard.cy.ts b/cypress/e2e/dashboard.cy.ts index 959aa5118fb80..294104fdc91a9 100644 --- a/cypress/e2e/dashboard.cy.ts +++ b/cypress/e2e/dashboard.cy.ts @@ -1,5 +1,6 @@ import { randomString } from '../support/random' import { insight, dashboards, dashboard } from '../productAnalytics' +import { urls } from 'scenes/urls' describe('Dashboard', () => { beforeEach(() => { @@ -20,10 +21,10 @@ describe('Dashboard', () => { }) it('Adding new insight to dashboard works', () => { - const dashboardName = randomString('Dashboard with insight A') + const dashboardName = randomString('Dashboard with matching filter') const insightName = randomString('insight to add to dashboard') - // create and visit a dashboard to get it into turbomode cache + // Create and visit a dashboard to get it into turbo mode cache dashboards.createAndGoToEmptyDashboard(dashboardName) insight.create(insightName) @@ -31,6 +32,74 @@ describe('Dashboard', () => { insight.addInsightToDashboard(dashboardName, { visitAfterAdding: true }) cy.get('.CardMeta h4').should('have.text', insightName) + + dashboard.addPropertyFilter() + cy.get('main').contains('There are no matching events for this query').should('not.exist') + + cy.clickNavMenu('dashboards') + const dashboardNonMatching = randomString('Dashboard with non-matching filter') + dashboards.createAndGoToEmptyDashboard(dashboardNonMatching) + + insight.visitInsight(insightName) + insight.addInsightToDashboard(dashboardNonMatching, { visitAfterAdding: true }) + + dashboard.addPropertyFilter('Browser', 'Hogbrowser') + cy.get('main').contains('There are no matching events for this query').should('exist') + + // Go back and forth to make sure the filters are correctly applied + for (let i = 0; i < 3; i++) { + cy.clickNavMenu('dashboards') + dashboards.visitDashboard(dashboardName) + cy.get('.CardMeta h4').should('have.text', insightName) + cy.get('h4').contains('Refreshing').should('not.exist') + cy.get('main').contains('There are no matching events for this query').should('not.exist') + + cy.clickNavMenu('dashboards') + dashboards.visitDashboard(dashboardNonMatching) + cy.get('.CardMeta h4').should('have.text', insightName) + cy.get('h4').contains('Refreshing').should('not.exist') + cy.get('main').contains('There are no matching events for this query').should('exist') + } + }) + + it('Dashboard filter updates are correctly isolated for one insight on multiple dashboards', () => { + const dashboardAName = randomString('Dashboard with insight A') + const dashboardBName = randomString('Dashboard with insight B') + const insightName = randomString('insight to add to dashboard') + + // Create and visit two dashboards to get them into turbo mode cache + dashboards.createAndGoToEmptyDashboard(dashboardAName) + cy.clickNavMenu('dashboards') + dashboards.createAndGoToEmptyDashboard(dashboardBName) + + insight.create(insightName) + + // Add that one insight to both dashboards + insight.addInsightToDashboard(dashboardAName, { visitAfterAdding: false }) + cy.get('[aria-label="close"]').click() + insight.addInsightToDashboard(dashboardBName, { visitAfterAdding: false }) + cy.get('[aria-label="close"]').click() + + // Let's get dashboard A mounted + cy.clickNavMenu('dashboards') + dashboards.visitDashboard(dashboardAName) + cy.get('[data-attr=date-filter]').contains('No date range override') + cy.get('.InsightCard h5').should('have.length', 1).contains('Last 7 days') + // Now let's see dashboard B + cy.clickNavMenu('dashboards') + dashboards.visitDashboard(dashboardBName) + cy.get('[data-attr=date-filter]').contains('No date range override') + cy.get('.InsightCard h5').should('have.length', 1).contains('Last 7 days') + // Override the time range on dashboard B + cy.get('[data-attr=date-filter]').contains('No date range override').click() + cy.get('div').contains('Yesterday').should('exist').click() + cy.get('[data-attr=date-filter]').contains('Yesterday') + cy.get('.InsightCard h5').should('have.length', 1).contains('Yesterday') + // Cool, now back to A and make sure the insight is still using the original range there, not the one from B + cy.clickNavMenu('dashboards') + dashboards.visitDashboard(dashboardAName) + cy.get('[data-attr=date-filter]').contains('No date range override') + cy.get('.InsightCard h5').should('have.length', 1).contains('Last 7 days') // This must not be "Yesterday"! }) it('Adding new insight to dashboard does not clear filters', () => { @@ -38,7 +107,7 @@ describe('Dashboard', () => { const firstInsight = randomString('insight to add to dashboard') const secondInsight = randomString('another insight to add to dashboard') - // create and visit a dashboard to get it into turbomode cache + // Create and visit a dashboard to get it into turbo mode cache dashboards.createAndGoToEmptyDashboard(dashboardName) dashboard.addInsightToEmptyDashboard(firstInsight) diff --git a/cypress/productAnalytics/index.ts b/cypress/productAnalytics/index.ts index 584972cc63968..dfdb2f6502ac5 100644 --- a/cypress/productAnalytics/index.ts +++ b/cypress/productAnalytics/index.ts @@ -67,7 +67,7 @@ export const insight = { }, visitInsight: (insightName: string): void => { cy.clickNavMenu('savedinsights') - cy.contains('.row-name > .Link', insightName).click() + cy.contains('.Link', insightName).click() }, create: (insightName: string, insightType: string = 'TRENDS'): void => { cy.clickNavMenu('savedinsights') @@ -169,6 +169,14 @@ export const dashboard = { cy.get('[data-attr=insight-save-button]').contains('Save & add to dashboard').click() cy.wait('@postInsight') }, + addPropertyFilter(type: string = 'Browser', value: string = 'Chrome'): void { + cy.get('.PropertyFilterButton').should('have.length', 0) + cy.get('[data-attr="property-filter-0"]').click() + cy.get('[data-attr="taxonomic-filter-searchfield"]').click().type('Browser').wait(1000) + cy.get('[data-attr="prop-filter-event_properties-0"]').click({ force: true }) + cy.get('.LemonInput').type(value) + cy.contains('.LemonButton__content', value).click({ force: true }) + }, addAnyFilter(): void { cy.get('.PropertyFilterButton').should('have.length', 0) cy.get('[data-attr="property-filter-0"]').click() diff --git a/frontend/src/lib/components/AddToDashboard/AddToDashboardModal.tsx b/frontend/src/lib/components/AddToDashboard/AddToDashboardModal.tsx index c7ebea301a5f9..e69da14b09f95 100644 --- a/frontend/src/lib/components/AddToDashboard/AddToDashboardModal.tsx +++ b/frontend/src/lib/components/AddToDashboard/AddToDashboardModal.tsx @@ -42,7 +42,6 @@ const DashboardRelationRow = ({ }: DashboardRelationRowProps): JSX.Element => { const logic = addToDashboardModalLogic({ insight: insight, - fromDashboard: insight.dashboards?.[0] || undefined, }) const { addToDashboard, removeFromDashboard } = useActions(logic) const { dashboardWithActiveAPICall } = useValues(logic) @@ -104,7 +103,6 @@ export function AddToDashboardModal({ }: SaveToDashboardModalProps): JSX.Element { const logic = addToDashboardModalLogic({ insight: insight, - fromDashboard: insight.dashboards?.[0] || undefined, }) const { searchQuery, currentDashboards, orderedDashboards, scrollIndex } = useValues(logic) @@ -128,7 +126,10 @@ export function AddToDashboardModal({ return ( { + closeModal() + setSearchQuery('') + }} isOpen={isOpen} title="Add to dashboard" footer={ @@ -139,7 +140,7 @@ export function AddToDashboardModal({ onClick={addNewDashboard} disabledReason={ !canEditInsight - ? 'You do not have permission to add this Insight to dashboards' + ? 'You do not have permission to add this insight to dashboards' : undefined } > @@ -162,9 +163,8 @@ export function AddToDashboardModal({ onChange={(newValue) => setSearchQuery(newValue)} />
- This insight is referenced on{' '} - {insight.dashboard_tiles?.length}{' '} - {pluralize(insight.dashboard_tiles?.length || 0, 'dashboard', 'dashboards', false)} + This insight is referenced on {currentDashboards.length}{' '} + {pluralize(currentDashboards.length, 'dashboard', 'dashboards', false)}
{/* eslint-disable-next-line react/forbid-dom-props */}
diff --git a/frontend/src/lib/components/AddToDashboard/addToDashboardModalLogic.ts b/frontend/src/lib/components/AddToDashboard/addToDashboardModalLogic.ts index b120dcc51c752..7d3d5164d81ea 100644 --- a/frontend/src/lib/components/AddToDashboard/addToDashboardModalLogic.ts +++ b/frontend/src/lib/components/AddToDashboard/addToDashboardModalLogic.ts @@ -14,7 +14,6 @@ import type { addToDashboardModalLogicType } from './addToDashboardModalLogicTyp export interface AddToDashboardModalLogicProps { insight: Partial - fromDashboard?: number } // Helping kea-typegen navigate the exported default class for Fuse @@ -30,16 +29,27 @@ export const addToDashboardModalLogic = kea([ return insight.short_id }), path(['lib', 'components', 'AddToDashboard', 'saveToDashboardModalLogic']), - connect((props: AddToDashboardModalLogicProps) => ({ - actions: [ - insightLogic({ dashboardItemId: props.insight.short_id, cachedInsight: props.insight }), - ['updateInsight', 'updateInsightSuccess', 'updateInsightFailure'], - eventUsageLogic, - ['reportSavedInsightToDashboard', 'reportRemovedInsightFromDashboard', 'reportCreatedDashboardFromModal'], - newDashboardLogic, - ['showNewDashboardModal'], - ], - })), + connect((props: AddToDashboardModalLogicProps) => { + const builtInsightLogic = insightLogic({ + dashboardItemId: props.insight.short_id, + cachedInsight: props.insight, + }) + return { + values: [builtInsightLogic, ['insight']], + actions: [ + builtInsightLogic, + ['updateInsight', 'updateInsightSuccess', 'updateInsightFailure'], + eventUsageLogic, + [ + 'reportSavedInsightToDashboard', + 'reportRemovedInsightFromDashboard', + 'reportCreatedDashboardFromModal', + ], + newDashboardLogic, + ['showNewDashboardModal'], + ], + } + }), actions({ addNewDashboard: true, setSearchQuery: (query: string) => ({ query }), @@ -79,8 +89,8 @@ export const addToDashboardModalLogic = kea([ : nameSortedDashboards, ], currentDashboards: [ - (s, p) => [s.filteredDashboards, p.insight], - (filteredDashboards, insight: InsightModel): DashboardBasicType[] => + (s) => [s.filteredDashboards, s.insight], + (filteredDashboards, insight): DashboardBasicType[] => filteredDashboards.filter((d) => insight.dashboard_tiles?.map((dt) => dt.dashboard_id)?.includes(d.id)), ], availableDashboards: [ diff --git a/frontend/src/lib/components/Cards/TextCard/TextCard.tsx b/frontend/src/lib/components/Cards/TextCard/TextCard.tsx index f0a09c95cfb29..c9b359d82d9b4 100644 --- a/frontend/src/lib/components/Cards/TextCard/TextCard.tsx +++ b/frontend/src/lib/components/Cards/TextCard/TextCard.tsx @@ -133,7 +133,7 @@ export function TextCardInternal( fullWidth data-attr="remove-text-tile-from-dashboard" > - Remove from dashboard + Delete )} diff --git a/frontend/src/mocks/fixtures/api/projects/team_id/insights/stickiness.json b/frontend/src/mocks/fixtures/api/projects/team_id/insights/stickiness.json index f79e4db7a1545..db147c1c744e6 100644 --- a/frontend/src/mocks/fixtures/api/projects/team_id/insights/stickiness.json +++ b/frontend/src/mocks/fixtures/api/projects/team_id/insights/stickiness.json @@ -1,6 +1,6 @@ { "id": 51, - "short_id": "jEAIVJnI", + "short_id": "xEAIVJnI", "name": "", "derived_name": "User stickiness based on Pageview", "filters": { diff --git a/frontend/src/mocks/fixtures/api/projects/team_id/insights/trendsBarBreakdown.json b/frontend/src/mocks/fixtures/api/projects/team_id/insights/trendsBarBreakdown.json index 4a99df0739a55..d6c12efe46b7c 100644 --- a/frontend/src/mocks/fixtures/api/projects/team_id/insights/trendsBarBreakdown.json +++ b/frontend/src/mocks/fixtures/api/projects/team_id/insights/trendsBarBreakdown.json @@ -1,6 +1,6 @@ { "id": 51, - "short_id": "jEAIVJnK", + "short_id": "xEAIVJnK", "name": "", "derived_name": "Pageview count by event's Library Version", "filters": { diff --git a/frontend/src/mocks/fixtures/api/projects/team_id/insights/trendsCumulativeBreakdown.json b/frontend/src/mocks/fixtures/api/projects/team_id/insights/trendsCumulativeBreakdown.json index 5ab85ea0ea2e4..b22148cb81fc4 100644 --- a/frontend/src/mocks/fixtures/api/projects/team_id/insights/trendsCumulativeBreakdown.json +++ b/frontend/src/mocks/fixtures/api/projects/team_id/insights/trendsCumulativeBreakdown.json @@ -1,6 +1,6 @@ { "id": 51, - "short_id": "jEAIVJnM", + "short_id": "xEAIVJnM", "name": "", "derived_name": "Pageview count by event's Browser Version", "filters": { diff --git a/frontend/src/queries/nodes/DataNode/dataNodeLogic.ts b/frontend/src/queries/nodes/DataNode/dataNodeLogic.ts index 56d11af1665b5..104ea71294314 100644 --- a/frontend/src/queries/nodes/DataNode/dataNodeLogic.ts +++ b/frontend/src/queries/nodes/DataNode/dataNodeLogic.ts @@ -113,15 +113,16 @@ export const dataNodeLogic = kea([ if (oldProps.query && props.query.kind !== oldProps.query.kind) { actions.clearResponse() } - if (!queryEqual(props.query, oldProps.query)) { - if ( - !props.cachedResults || - (isInsightQueryNode(props.query) && !props.cachedResults['result'] && !props.cachedResults['results']) - ) { - actions.loadData() - } else { - actions.setResponse(props.cachedResults) - } + if ( + !(props.cachedResults && props.key.includes('dashboard')) && // Don't load data on dashboard if cached results are available + !queryEqual(props.query, oldProps.query) && + (!props.cachedResults || + (isInsightQueryNode(props.query) && !props.cachedResults['result'] && !props.cachedResults['results'])) + ) { + actions.loadData() + } else if (props.cachedResults) { + // Use cached results if available, otherwise this logic will load the data again + actions.setResponse(props.cachedResults) } }), actions({ @@ -624,7 +625,9 @@ export const dataNodeLogic = kea([ }, })), afterMount(({ actions, props }) => { - if (Object.keys(props.query || {}).length > 0) { + if (Object.keys(props.query || {}).length > 0 && !props.key.includes('dashboard')) { + // Attention: When on dashboard we don't want to load data on mount + // as it will have be loaded by some other logic actions.loadData() } diff --git a/frontend/src/scenes/dashboard/dashboardLogic.tsx b/frontend/src/scenes/dashboard/dashboardLogic.tsx index c21233b7b9a52..088b1adc73b34 100644 --- a/frontend/src/scenes/dashboard/dashboardLogic.tsx +++ b/frontend/src/scenes/dashboard/dashboardLogic.tsx @@ -29,7 +29,6 @@ import { clearDOMTextSelection, isUserLoggedIn, shouldCancelQuery, toParams, uui import { DashboardEventSource, eventUsageLogic } from 'lib/utils/eventUsageLogic' import { Layout, Layouts } from 'react-grid-layout' import { calculateLayouts } from 'scenes/dashboard/tileLayouts' -import { insightLogic } from 'scenes/insights/insightLogic' import { Scene } from 'scenes/sceneTypes' import { urls } from 'scenes/urls' import { userLogic } from 'scenes/userLogic' @@ -102,29 +101,6 @@ const layoutsByTile = (layouts: Layouts): Record([ path(['scenes', 'dashboard', 'dashboardLogic']), connect(() => ({ @@ -364,10 +340,11 @@ export const dashboardLogic = kea([ const newTiles = state.tiles.slice() if (tileIndex >= 0) { - if (insight.dashboards?.includes(props.id)) { - newTiles[tileIndex] = { ...newTiles[tileIndex], insight: insight } - if (updateTileOnDashboards?.includes(props.id)) { - newTiles[tileIndex].last_refresh = insight.last_refresh + if (insight.dashboards?.includes(props.id) && updateTileOnDashboards?.includes(props.id)) { + newTiles[tileIndex] = { + ...newTiles[tileIndex], + insight: insight, + last_refresh: insight.last_refresh, } } else { newTiles.splice(tileIndex, 1) @@ -885,7 +862,9 @@ export const dashboardLogic = kea([ let refreshesFinished = 0 let totalResponseBytes = 0 - const hardRefreshWithoutCache = ['refresh', 'load_missing'].includes(action) + const hardRefreshWithoutCache = ['refresh', 'load_missing', 'refresh_insights_on_filters_updated'].includes( + action + ) // array of functions that reload each item const fetchItemFunctions = insights.map((insight) => async () => { @@ -908,7 +887,6 @@ export const dashboardLogic = kea([ const refreshedInsightResponse: Response = await api.getResponse(apiUrl, methodOptions) const refreshedInsight: InsightModel = await getJSONOrNull(refreshedInsightResponse) breakpoint() - updateExistingInsightState({ cachedInsight: insight, dashboardId, refreshedInsight }) dashboardsModel.actions.updateDashboardInsight( refreshedInsight, [], @@ -1046,7 +1024,6 @@ export const dashboardLogic = kea([ allLoaded = false } else { const tilesWithNoResults = values.tiles?.filter((t) => !!t.insight && !t.insight.result) || [] - const tilesWithResults = values.tiles?.filter((t) => !!t.insight && t.insight.result) || [] if (tilesWithNoResults.length) { actions.refreshAllDashboardItems({ @@ -1057,17 +1034,6 @@ export const dashboardLogic = kea([ }) allLoaded = false } - - for (const tile of tilesWithResults) { - if (tile.insight) { - updateExistingInsightState({ - cachedInsight: tile.insight, - dashboardId: dashboard.id, - refreshedInsight: tile.insight, - }) - dashboardsModel.actions.updateDashboardInsight(tile.insight) - } - } } const payload: TimeToSeeDataPayload = { diff --git a/frontend/src/scenes/insights/insightLogic.test.ts b/frontend/src/scenes/insights/insightLogic.test.ts index 6bf04a1aedd95..f274314245e7a 100644 --- a/frontend/src/scenes/insights/insightLogic.test.ts +++ b/frontend/src/scenes/insights/insightLogic.test.ts @@ -609,17 +609,6 @@ describe('insightLogic', () => { }) describe('takes data from other logics if available', () => { - const verifyItLoadsFromALogic = async ( - logicUnderTest: ReturnType, - partialExpectedInsight: Partial - ): Promise => - expectLogic(logicUnderTest) - .toDispatchActions(['setInsight']) - .toNotHaveDispatchedActions(['setFilters', 'loadResults', 'loadInsight', 'updateInsight']) - .toMatchValues({ - insight: partial(partialExpectedInsight), - }) - const verifyItLoadsFromTheAPI = async (logicUnderTest: ReturnType): Promise => expectLogic(logicUnderTest) .toDispatchActions(['loadInsight']) @@ -629,7 +618,7 @@ describe('insightLogic', () => { }), }) - it('loads from the dashboardLogic when in dashboard context', async () => { + it('loads from the api when coming from dashboard context', async () => { // 1. the dashboard is mounted const dashLogic = dashboardLogic({ id: 33 }) dashLogic.mount() @@ -639,12 +628,7 @@ describe('insightLogic', () => { logic = insightLogic({ dashboardItemId: Insight42, dashboardId: 33 }) logic.mount() - // 3. verify it didn't make any API calls - await verifyItLoadsFromALogic(logic, { - id: 42, - result: 'result!', - filters: { insight: InsightType.TRENDS, interval: 'month' }, - }) + await verifyItLoadsFromTheAPI(logic) }) it('does not load from the dashboardLogic when not in that dashboard context', async () => { @@ -660,23 +644,6 @@ describe('insightLogic', () => { await verifyItLoadsFromTheAPI(logic) }) - it('loads from the savedInsightLogic when not in a dashboard context', async () => { - // 1. open saved insights - router.actions.push(urls.savedInsights(), {}, {}) - savedInsightsLogic.mount() - - // 2. the insights are loaded - await expectLogic(savedInsightsLogic).toDispatchActions(['loadInsights', 'loadInsightsSuccess']) - - // 3. mount the insight - logic = insightLogic({ dashboardItemId: Insight42 }) - logic.mount() - - await verifyItLoadsFromALogic(logic, { - short_id: '42' as InsightShortId, - }) - }) - it('does not load from the savedInsightLogic when in a dashboard context', async () => { // 1. open saved insights router.actions.push(urls.savedInsights(), {}, {}) diff --git a/frontend/src/scenes/insights/insightLogic.ts b/frontend/src/scenes/insights/insightLogic.ts index cd6b4b6ac88e5..45afd10e49c3c 100644 --- a/frontend/src/scenes/insights/insightLogic.ts +++ b/frontend/src/scenes/insights/insightLogic.ts @@ -52,7 +52,7 @@ import { import { teamLogic } from '../teamLogic' import { toLocalFilters } from './filters/ActionFilter/entityFilterLogic' import type { insightLogicType } from './insightLogicType' -import { extractObjectDiffKeys, findInsightFromMountedLogic, getInsightId } from './utils' +import { extractObjectDiffKeys, getInsightId } from './utils' const IS_TEST_MODE = process.env.NODE_ENV === 'test' export const UNSAVED_INSIGHT_MIN_REFRESH_INTERVAL_MINUTES = 3 @@ -710,19 +710,7 @@ export const insightLogic = kea([ return } - const insight = findInsightFromMountedLogic( - props.dashboardItemId as string | InsightShortId, - props.dashboardId - ) - if (insight) { - actions.setInsight(insight, { overrideFilter: true, fromPersistentApi: true }) - if (insight?.result) { - actions.reportInsightViewed(insight, insight.filters || {}) - } - return - } - - if (!props.doNotLoad) { + if (!props.doNotLoad && !props.cachedInsight) { actions.loadInsight(props.dashboardItemId as InsightShortId) } }, diff --git a/frontend/src/scenes/insights/utils.tsx b/frontend/src/scenes/insights/utils.tsx index 212eff05f6c75..2ba3b5dca932e 100644 --- a/frontend/src/scenes/insights/utils.tsx +++ b/frontend/src/scenes/insights/utils.tsx @@ -4,11 +4,8 @@ import { CORE_FILTER_DEFINITIONS_BY_GROUP } from 'lib/taxonomy' import { ensureStringIsNotBlank, humanFriendlyNumber, objectsEqual } from 'lib/utils' import { getCurrentTeamId } from 'lib/utils/getAppContext' import { ReactNode } from 'react' -import { dashboardLogic } from 'scenes/dashboard/dashboardLogic' -import { savedInsightsLogic } from 'scenes/saved-insights/savedInsightsLogic' import { urls } from 'scenes/urls' -import { dashboardsModel } from '~/models/dashboardsModel' import { FormatPropertyValueForDisplayFunction } from '~/models/propertyDefinitionsModel' import { examples } from '~/queries/examples' import { ActionsNode, BreakdownFilter, DataWarehouseNode, EventsNode, PathsFilter } from '~/queries/schema' @@ -23,7 +20,6 @@ import { EntityFilter, EntityTypes, EventType, - InsightModel, InsightShortId, InsightType, PathType, @@ -126,35 +122,6 @@ export function extractObjectDiffKeys( return changedKeys } -export function findInsightFromMountedLogic( - insightShortId: InsightShortId | string, - dashboardId: number | undefined -): Partial | null { - if (dashboardId) { - const insightOnDashboard = dashboardLogic - .findMounted({ id: dashboardId }) - ?.values.insightTiles?.find((tile) => tile.insight?.short_id === insightShortId)?.insight - if (insightOnDashboard) { - return insightOnDashboard - } else { - const dashboards = dashboardsModel.findMounted()?.values.rawDashboards - let foundOnModel: Partial | undefined - for (const dashModelId of Object.keys(dashboards || {})) { - foundOnModel = dashboardLogic - .findMounted({ id: parseInt(dashModelId) }) - ?.values.insightTiles?.find((tile) => tile.insight?.short_id === insightShortId)?.insight - } - return foundOnModel || null - } - } else { - return ( - savedInsightsLogic - .findMounted() - ?.values.insights?.results?.find((item) => item.short_id === insightShortId) || null - ) - } -} - export async function getInsightId(shortId: InsightShortId): Promise { const insightId = insightLogic.findMounted({ dashboardItemId: shortId })?.values?.insight?.id diff --git a/frontend/src/scenes/trends/viz/ActionsLineGraph.tsx b/frontend/src/scenes/trends/viz/ActionsLineGraph.tsx index bcee7d21580a8..268e2054ce4cf 100644 --- a/frontend/src/scenes/trends/viz/ActionsLineGraph.tsx +++ b/frontend/src/scenes/trends/viz/ActionsLineGraph.tsx @@ -75,9 +75,13 @@ export function ActionsLineGraph({ isInsightVizNode(query) && isTrendsQuery(query.source) - return indexedResults && - indexedResults[0]?.data && - indexedResults.filter((result) => result.count !== 0).length > 0 ? ( + if ( + !(indexedResults && indexedResults[0]?.data && indexedResults.filter((result) => result.count !== 0).length > 0) + ) { + return + } + + return ( - ) : ( - ) }