Skip to content

Commit 512e8c9

Browse files
committed
feat(customers): Filter insight by person in PersonFeedCanvas
1 parent 74019b0 commit 512e8c9

File tree

4 files changed

+63
-14
lines changed

4 files changed

+63
-14
lines changed

frontend/src/scenes/notebooks/Nodes/NotebookNodeQuery.tsx

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,21 @@ import { insightDataLogic } from 'scenes/insights/insightDataLogic'
99
import { insightLogic } from 'scenes/insights/insightLogic'
1010
import { useSummarizeInsight } from 'scenes/insights/summarizeInsight'
1111
import { createPostHogWidgetNode } from 'scenes/notebooks/Nodes/NodeWrapper'
12+
import { notebookLogic } from 'scenes/notebooks/Notebook/notebookLogic'
1213
import { urls } from 'scenes/urls'
1314

1415
import { Query } from '~/queries/Query/Query'
1516
import { DataTableNode, InsightQueryNode, InsightVizNode, NodeKind, QuerySchema } from '~/queries/schema/schema-general'
16-
import { containsHogQLQuery, isHogQLQuery, isInsightVizNode, isNodeWithSource } from '~/queries/utils'
17+
import {
18+
containsHogQLQuery,
19+
isActorsQuery,
20+
isDataTableNode,
21+
isEventsQuery,
22+
isHogQLQuery,
23+
isInsightVizNode,
24+
isNodeWithSource,
25+
isSavedInsightNode,
26+
} from '~/queries/utils'
1727
import { InsightLogicProps, InsightShortId } from '~/types'
1828

1929
import { NotebookNodeAttributeProperties, NotebookNodeProps, NotebookNodeType } from '../types'
@@ -39,6 +49,7 @@ const Component = ({
3949
const nodeLogic = useMountedLogic(notebookNodeLogic)
4050
const { expanded } = useValues(nodeLogic)
4151
const { setTitlePlaceholder } = useActions(nodeLogic)
52+
const { canvasFiltersOverride } = useValues(notebookLogic)
4253
const summarizeInsight = useSummarizeInsight()
4354

4455
const insightLogicProps = {
@@ -77,17 +88,17 @@ const Component = ({
7788
}, [query, insightName])
7889

7990
const modifiedQuery = useMemo(() => {
80-
const modifiedQuery = { ...query, full: false }
91+
let modifiedQuery = { ...query, full: false }
8192

82-
if (NodeKind.DataTableNode === modifiedQuery.kind || NodeKind.SavedInsightNode === modifiedQuery.kind) {
93+
if (isDataTableNode(modifiedQuery) || isSavedInsightNode(modifiedQuery)) {
8394
modifiedQuery.showOpenEditorButton = false
8495
modifiedQuery.full = false
8596
modifiedQuery.showHogQLEditor = false
8697
modifiedQuery.embedded = true
8798
modifiedQuery.showTimings = false
8899
}
89100

90-
if (NodeKind.InsightVizNode === modifiedQuery.kind || NodeKind.SavedInsightNode === modifiedQuery.kind) {
101+
if (isInsightVizNode(modifiedQuery) || isSavedInsightNode(modifiedQuery)) {
91102
modifiedQuery.showFilters = false
92103
modifiedQuery.showHeader = false
93104
modifiedQuery.showTable = false
@@ -96,7 +107,7 @@ const Component = ({
96107
}
97108

98109
return modifiedQuery
99-
}, [query])
110+
}, [query, canvasFiltersOverride])
100111

101112
if (!expanded) {
102113
return null
@@ -129,18 +140,21 @@ const Component = ({
129140

130141
type NotebookNodeQueryAttributes = {
131142
query: QuerySchema
143+
/* Wether canvasFiltersOverride is applied, as we should apply it only once */
144+
isDefaultFilterApplied: boolean
132145
}
133146

134147
export const Settings = ({
135148
attributes,
136149
updateAttributes,
137150
}: NotebookNodeAttributeProperties<NotebookNodeQueryAttributes>): JSX.Element => {
138-
const { query } = attributes
151+
const { query, isDefaultFilterApplied } = attributes
152+
const { canvasFiltersOverride } = useValues(notebookLogic)
139153

140154
const modifiedQuery = useMemo(() => {
141155
const modifiedQuery = { ...query, full: false }
142156

143-
if (NodeKind.DataTableNode === modifiedQuery.kind || NodeKind.SavedInsightNode === modifiedQuery.kind) {
157+
if (isDataTableNode(modifiedQuery) || isSavedInsightNode(modifiedQuery)) {
144158
modifiedQuery.showOpenEditorButton = false
145159
modifiedQuery.showHogQLEditor = true
146160
modifiedQuery.showResultsTable = false
@@ -160,18 +174,33 @@ export const Settings = ({
160174
modifiedQuery.showColumnConfigurator = true
161175
}
162176

163-
if (NodeKind.InsightVizNode === modifiedQuery.kind || NodeKind.SavedInsightNode === modifiedQuery.kind) {
177+
if (isInsightVizNode(modifiedQuery) || isSavedInsightNode(modifiedQuery)) {
164178
modifiedQuery.showFilters = true
165179
modifiedQuery.showHeader = true
166180
modifiedQuery.showResults = false
167181
modifiedQuery.embedded = true
168182
}
169183

184+
if (
185+
isInsightVizNode(modifiedQuery) &&
186+
!isHogQLQuery(modifiedQuery.source) &&
187+
!isActorsQuery(modifiedQuery.source) &&
188+
!isDefaultFilterApplied
189+
) {
190+
modifiedQuery.source.properties = canvasFiltersOverride
191+
updateAttributes({ ...attributes, isDefaultFilterApplied: true })
192+
}
193+
194+
if (isDataTableNode(modifiedQuery) && isEventsQuery(modifiedQuery.source) && !isDefaultFilterApplied) {
195+
modifiedQuery.source.fixedProperties = canvasFiltersOverride
196+
updateAttributes({ ...attributes, isDefaultFilterApplied: true })
197+
}
198+
170199
return modifiedQuery
171-
}, [query])
200+
}, [query, canvasFiltersOverride])
172201

173202
const detachSavedInsight = (): void => {
174-
if (attributes.query.kind === NodeKind.SavedInsightNode) {
203+
if (isSavedInsightNode(attributes.query)) {
175204
const insightProps: InsightLogicProps = { dashboardItemId: attributes.query.shortId }
176205
const dataLogic = insightDataLogic.findMounted(insightProps)
177206

@@ -181,7 +210,7 @@ export const Settings = ({
181210
}
182211
}
183212

184-
return attributes.query.kind === NodeKind.SavedInsightNode ? (
213+
return isSavedInsightNode(attributes.query) ? (
185214
<div className="p-3 deprecated-space-y-2">
186215
<div className="text-lg font-semibold">Insight created outside of this notebook</div>
187216
<div>
@@ -241,9 +270,12 @@ export const NotebookNodeQuery = createPostHogWidgetNode<NotebookNodeQueryAttrib
241270
query: {
242271
default: DEFAULT_QUERY,
243272
},
273+
isDefaultFilterApplied: {
274+
default: false,
275+
},
244276
},
245277
href: ({ query }) =>
246-
query.kind === NodeKind.SavedInsightNode
278+
isSavedInsightNode(query)
247279
? urls.insightView(query.shortId)
248280
: isInsightVizNode(query)
249281
? urls.insightNew({ query })
@@ -257,6 +289,7 @@ export const NotebookNodeQuery = createPostHogWidgetNode<NotebookNodeQueryAttrib
257289
kind: NodeKind.SavedInsightNode,
258290
shortId: match[1] as InsightShortId,
259291
},
292+
isDefaultFilterApplied: false,
260293
}
261294
},
262295
},

frontend/src/scenes/notebooks/Notebook/Notebook.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { NotebookLogicProps, notebookLogic } from 'scenes/notebooks/Notebook/not
1414

1515
import { ErrorBoundary } from '~/layout/ErrorBoundary'
1616
import { SCRATCHPAD_NOTEBOOK } from '~/models/notebooksModel'
17+
import { AnyPropertyFilter } from '~/types'
1718

1819
import { AddInsightsToNotebookModal } from '../AddInsightsToNotebookModal/AddInsightsToNotebookModal'
1920
import { Editor } from './Editor'
@@ -28,6 +29,7 @@ export type NotebookProps = NotebookLogicProps & {
2829
initialAutofocus?: EditorFocusPosition
2930
initialContent?: JSONContent
3031
editable?: boolean
32+
canvasFiltersOverride?: AnyPropertyFilter[]
3133
}
3234

3335
export function Notebook({
@@ -36,8 +38,9 @@ export function Notebook({
3638
editable = true,
3739
initialAutofocus = 'start',
3840
initialContent,
41+
canvasFiltersOverride,
3942
}: NotebookProps): JSX.Element {
40-
const logicProps: NotebookLogicProps = { shortId, mode }
43+
const logicProps: NotebookLogicProps = { shortId, mode, canvasFiltersOverride }
4144
const logic = notebookLogic(logicProps)
4245
const { notebook, notebookLoading, editor, conflictWarningVisible, isEditable, isTemplate, notebookMissing } =
4346
useValues(logic)

frontend/src/scenes/notebooks/Notebook/notebookLogic.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
AccessControlLevel,
2323
AccessControlResourceType,
2424
ActivityScope,
25+
AnyPropertyFilter,
2526
CommentType,
2627
InsightShortId,
2728
SidePanelTab,
@@ -51,6 +52,7 @@ export type NotebookLogicProps = {
5152
shortId: string
5253
mode?: NotebookLogicMode
5354
target?: NotebookTarget
55+
canvasFiltersOverride?: AnyPropertyFilter[]
5456
}
5557

5658
async function runWhenEditorIsReady(waitForEditor: () => boolean, fn: () => any): Promise<any> {
@@ -151,6 +153,7 @@ export const notebookLogic = kea<notebookLogicType>([
151153
setAccessDeniedToNotebook: true,
152154
}),
153155
reducers(({ props }) => ({
156+
canvasFiltersOverride: [props.canvasFiltersOverride ?? ([] as AnyPropertyFilter[])],
154157
isShareModalOpen: [
155158
false,
156159
{

frontend/src/scenes/persons/PersonFeedCanvas.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { uuid } from 'lib/utils'
44
import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic'
55
import { Notebook } from 'scenes/notebooks/Notebook/Notebook'
66

7-
import { PersonType } from '~/types'
7+
import { AnyPropertyFilter, PersonType, PropertyFilterType, PropertyOperator } from '~/types'
88

99
type PersonFeedCanvasProps = {
1010
person: PersonType
@@ -16,11 +16,21 @@ const PersonFeedCanvas = ({ person }: PersonFeedCanvasProps): JSX.Element => {
1616
const id = person.id
1717
const distinctId = person.distinct_ids[0]
1818

19+
const personFilter: AnyPropertyFilter[] = [
20+
{
21+
type: PropertyFilterType.EventMetadata,
22+
key: 'person_id',
23+
value: id,
24+
operator: PropertyOperator.Exact,
25+
},
26+
]
27+
1928
return (
2029
<Notebook
2130
editable={false}
2231
shortId={`canvas-${id}`}
2332
mode="canvas"
33+
canvasFiltersOverride={personFilter}
2434
initialContent={{
2535
type: 'doc',
2636
content: [

0 commit comments

Comments
 (0)