diff --git a/frontend/src/lib/components/ActivityLog/humanizeActivity.tsx b/frontend/src/lib/components/ActivityLog/humanizeActivity.tsx
index ff3045894b810..f52417705f8d6 100644
--- a/frontend/src/lib/components/ActivityLog/humanizeActivity.tsx
+++ b/frontend/src/lib/components/ActivityLog/humanizeActivity.tsx
@@ -46,7 +46,7 @@ export type ActivityLogItem = {
created_at: string
scope: ActivityScope
item_id?: string
- detail: ActivityLogDetail
+ detail?: ActivityLogDetail
unread?: boolean // when used as a notification
is_system?: boolean // when auto-created e.g. an exported image when sharing an insight
}
@@ -140,7 +140,7 @@ export function defaultDescriber(
asNotification = false,
resource?: string | JSX.Element
): HumanizedChange {
- resource = resource || logItem.detail.name || `a ${humanizeScope(logItem.scope, true)}`
+ resource = resource || logItem.detail?.name || `a ${humanizeScope(logItem.scope, true)}`
if (logItem.activity == 'deleted') {
return {
@@ -169,7 +169,7 @@ export function defaultDescriber(
>
)
}
- const commentContent = logItem.detail.changes?.[0].after as string | undefined
+ const commentContent = logItem.detail?.changes?.[0].after as string | undefined
return {
description,
diff --git a/frontend/src/scenes/data-management/dataManagementDescribers.tsx b/frontend/src/scenes/data-management/dataManagementDescribers.tsx
index b53f9911b693b..f36d04c0321a7 100644
--- a/frontend/src/scenes/data-management/dataManagementDescribers.tsx
+++ b/frontend/src/scenes/data-management/dataManagementDescribers.tsx
@@ -72,8 +72,8 @@ const dataManagementActionsMapping: Record<
function nameAndLink(logItem?: ActivityLogItem): JSX.Element {
return logItem?.item_id ? (
- {logItem?.detail.name || 'unknown'}
- ) : logItem?.detail.name ? (
+ {logItem?.detail?.name || 'unknown'}
+ ) : logItem?.detail?.name ? (
<>{logItem?.detail.name}>
) : (
<>unknown>
@@ -106,7 +106,7 @@ export function dataManagementActivityDescriber(logItem: ActivityLogItem, asNoti
>
)
- for (const change of logItem.detail.changes || []) {
+ for (const change of logItem.detail?.changes || []) {
if (!change?.field || !dataManagementActionsMapping[change.field]) {
continue // updates have to have a "field" to be described
}
diff --git a/frontend/src/scenes/feature-flags/activityDescriptions.tsx b/frontend/src/scenes/feature-flags/activityDescriptions.tsx
index c1604013f8f8b..f9e652cb6c34a 100644
--- a/frontend/src/scenes/feature-flags/activityDescriptions.tsx
+++ b/frontend/src/scenes/feature-flags/activityDescriptions.tsx
@@ -267,11 +267,11 @@ export function flagActivityDescriber(logItem: ActivityLogItem, asNotification?:
let changeSuffix: Description = (
<>
on {asNotification && ' the flag '}
- {nameOrLinkToFlag(logItem?.item_id, logItem?.detail.name)}
+ {nameOrLinkToFlag(logItem?.item_id, logItem.detail?.name)}
>
)
- for (const change of logItem.detail.changes || []) {
+ for (const change of logItem.detail?.changes || []) {
if (!change?.field) {
continue // feature flag updates have to have a "field" to be described
}
diff --git a/frontend/src/scenes/notebooks/Notebook/NotebookHistory.tsx b/frontend/src/scenes/notebooks/Notebook/NotebookHistory.tsx
index 7ffd9e158e242..d1a543d1b42f5 100644
--- a/frontend/src/scenes/notebooks/Notebook/NotebookHistory.tsx
+++ b/frontend/src/scenes/notebooks/Notebook/NotebookHistory.tsx
@@ -20,7 +20,7 @@ import { ActivityScope } from '~/types'
import { notebookLogic } from './notebookLogic'
const getFieldChange = (logItem: ActivityLogItem, field: string): any => {
- return logItem.detail.changes?.find((x) => x.field === field)?.after
+ return logItem.detail?.changes?.find((x) => x.field === field)?.after
}
function NotebookHistoryList({ onItemClick }: { onItemClick: (logItem: ActivityLogItem) => void }): JSX.Element {
@@ -101,7 +101,7 @@ export function NotebookHistory(): JSX.Element {
const { setShowHistory, setPreviewContent } = useActions(notebookLogic)
const onRevert = (logItem: ActivityLogItem): void => {
- const content = logItem.detail.changes?.find((x) => x.field === 'content')?.after
+ const content = logItem.detail?.changes?.find((x) => x.field === 'content')?.after
if (!content) {
lemonToast.error('Could not revert to this version')
diff --git a/frontend/src/scenes/notebooks/Notebook/notebookActivityDescriber.tsx b/frontend/src/scenes/notebooks/Notebook/notebookActivityDescriber.tsx
index 1756eb91c275d..51b5f6a5f7133 100644
--- a/frontend/src/scenes/notebooks/Notebook/notebookActivityDescriber.tsx
+++ b/frontend/src/scenes/notebooks/Notebook/notebookActivityDescriber.tsx
@@ -27,9 +27,9 @@ const notebookActionsMapping: Record<
function nameAndLink(logItem?: ActivityLogItem): JSX.Element {
return logItem?.detail?.short_id ? (
- {logItem?.detail.name || 'unknown'}
- ) : logItem?.detail.name ? (
- <>{logItem?.detail.name}>
+ {logItem.detail.name || 'unknown'}
+ ) : logItem?.detail?.name ? (
+ <>{logItem.detail.name}>
) : (
Untitled
)
@@ -45,7 +45,7 @@ export function notebookActivityDescriber(logItem: ActivityLogItem, asNotificati
let changes: Description[] = []
let changeSuffix: Description = <>on {nameAndLink(logItem)}>
- for (const change of logItem.detail.changes || []) {
+ for (const change of logItem.detail?.changes || []) {
if (!change?.field || !notebookActionsMapping[change.field]) {
continue // not all notebook fields are describable
}
diff --git a/frontend/src/scenes/persons/activityDescriptions.tsx b/frontend/src/scenes/persons/activityDescriptions.tsx
index ae904bd5a88d0..17593817aff72 100644
--- a/frontend/src/scenes/persons/activityDescriptions.tsx
+++ b/frontend/src/scenes/persons/activityDescriptions.tsx
@@ -19,7 +19,7 @@ export function personActivityDescriber(logItem: ActivityLogItem, asNotification
return {
description: (
<>
- {userNameForLogItem(logItem)} deleted the person: {logItem.detail.name}
+ {userNameForLogItem(logItem)} deleted the person: {logItem.detail?.name}
>
),
}
@@ -39,7 +39,7 @@ export function personActivityDescriber(logItem: ActivityLogItem, asNotification
}
}
if (logItem.activity === 'people_merged_into') {
- if (logItem.detail.merge?.source) {
+ if (logItem.detail?.merge?.source) {
return {
description: (
{userNameForLogItem(logItem)} merged
>
}
- listParts={logItem.detail.merge.source.flatMap((di) => (
+ listParts={logItem.detail?.merge.source.flatMap((di) => (
@@ -61,7 +61,7 @@ export function personActivityDescriber(logItem: ActivityLogItem, asNotification
}
if (logItem.activity === 'split_person') {
- const distinctIds: string[] | undefined = logItem.detail.changes?.[0].after?.['distinct_ids']
+ const distinctIds: string[] | undefined = logItem.detail?.changes?.[0].after?.['distinct_ids']
if (distinctIds) {
return {
description: (
diff --git a/frontend/src/scenes/plugins/pluginActivityDescriptions.tsx b/frontend/src/scenes/plugins/pluginActivityDescriptions.tsx
index a4889604735c1..1a87bd2f7fd70 100644
--- a/frontend/src/scenes/plugins/pluginActivityDescriptions.tsx
+++ b/frontend/src/scenes/plugins/pluginActivityDescriptions.tsx
@@ -21,7 +21,7 @@ export function pluginActivityDescriber(logItem: ActivityLogItem, asNotification
return {
description: (
<>
- {userNameForLogItem(logItem)} installed the app: {logItem.detail.name}
+ {userNameForLogItem(logItem)} installed the app: {logItem.detail?.name}
>
),
}
@@ -31,7 +31,7 @@ export function pluginActivityDescriber(logItem: ActivityLogItem, asNotification
return {
description: (
<>
- {userNameForLogItem(logItem)} uninstalled the app: {logItem.detail.name}
+ {userNameForLogItem(logItem)} uninstalled the app: {logItem.detail?.name}
>
),
}
@@ -39,7 +39,7 @@ export function pluginActivityDescriber(logItem: ActivityLogItem, asNotification
if (logItem.activity == 'enabled') {
const changes: (string | JSX.Element)[] = []
- for (const change of logItem.detail.changes || []) {
+ for (const change of logItem.detail?.changes || []) {
const newValue = change.after === SECRET_FIELD_VALUE ? '' : change.after
changes.push(
<>
@@ -53,8 +53,8 @@ export function pluginActivityDescriber(logItem: ActivityLogItem, asNotification
listParts={changes}
prefix={
<>
- {userNameForLogItem(logItem)} enabled the app: {logItem.detail.name}{' '}
- with config ID {logItem.item_id}
+ {userNameForLogItem(logItem)} enabled the app:{' '}
+ {logItem.detail?.name} with config ID {logItem.item_id}
{changes.length > 0 ? ', with' : '.'}
>
}
@@ -67,14 +67,14 @@ export function pluginActivityDescriber(logItem: ActivityLogItem, asNotification
return {
description: (
<>
- {userNameForLogItem(logItem)} disabled the app: {logItem.detail.name} with
+ {userNameForLogItem(logItem)} disabled the app: {logItem.detail?.name} with
config ID {logItem.item_id}.
>
),
}
}
- if (logItem.activity == 'job_triggered' && logItem.detail.trigger?.job_type == 'Export historical events V2') {
+ if (logItem.activity == 'job_triggered' && logItem.detail?.trigger?.job_type == 'Export historical events V2') {
const [startDate, endDate] = logItem.detail.trigger.payload.dateRange
return {
description: (
@@ -86,23 +86,23 @@ export function pluginActivityDescriber(logItem: ActivityLogItem, asNotification
}
}
- if (logItem.activity == 'job_triggered' && logItem.detail.trigger) {
+ if (logItem.activity == 'job_triggered' && logItem.detail?.trigger) {
return {
description: (
<>
{userNameForLogItem(logItem)} triggered job:{' '}
- {logItem.detail.trigger.job_type}
with config ID {logItem.item_id}.
+ {logItem.detail?.trigger.job_type}
with config ID {logItem.item_id}.
>
),
extendedDescription: (
<>
- Payload: {JSON.stringify(logItem.detail.trigger.payload, null, 2)}
+ Payload: {JSON.stringify(logItem.detail?.trigger.payload, null, 2)}
>
),
}
}
- if (logItem.activity == 'export_success' && logItem.detail.trigger) {
+ if (logItem.activity == 'export_success' && logItem.detail?.trigger) {
const { dateFrom, dateTo } = logItem.detail.trigger.payload
const startDate = dayjs(dateFrom).format('YYYY-MM-DD')
// :TRICKY: Internally export date range is non-inclusive so transform it to be inclusive
@@ -117,7 +117,7 @@ export function pluginActivityDescriber(logItem: ActivityLogItem, asNotification
}
}
- if (logItem.activity == 'export_fail' && logItem.detail.trigger) {
+ if (logItem.activity == 'export_fail' && logItem.detail?.trigger) {
const { dateFrom, dateTo } = logItem.detail.trigger.payload
const startDate = dayjs(dateFrom).format('YYYY-MM-DD')
// :TRICKY: Internally export date range is non-inclusive so transform it to be inclusive
@@ -135,7 +135,7 @@ export function pluginActivityDescriber(logItem: ActivityLogItem, asNotification
if (logItem.activity == 'config_updated') {
const changes: (string | JSX.Element)[] = []
- for (const change of logItem.detail.changes || []) {
+ for (const change of logItem.detail?.changes || []) {
let changeWording: string | JSX.Element = ''
const changeBefore = change.before === SECRET_FIELD_VALUE ? '' : change.before
const changeAfter = change.after === SECRET_FIELD_VALUE ? '' : change.after
@@ -168,7 +168,7 @@ export function pluginActivityDescriber(logItem: ActivityLogItem, asNotification
listParts={changes}
suffix={
<>
- on app {logItem.detail.name} with config ID {logItem.item_id}.
+ on app {logItem.detail?.name} with config ID {logItem.item_id}.
>
}
/>
@@ -177,7 +177,7 @@ export function pluginActivityDescriber(logItem: ActivityLogItem, asNotification
}
if (logItem.activity.startsWith('attachment_')) {
- for (const change of logItem.detail.changes || []) {
+ for (const change of logItem.detail?.changes || []) {
let changeWording: string | JSX.Element = ''
if (logItem.activity === 'attachment_created') {
@@ -213,7 +213,7 @@ export function pluginActivityDescriber(logItem: ActivityLogItem, asNotification
description: (
<>
{userNameForLogItem(logItem)} {changeWording} on app:{' '}
- {logItem.detail.name} with config ID {logItem.item_id}
+ {logItem.detail?.name} with config ID {logItem.item_id}
>
),
}
diff --git a/frontend/src/scenes/saved-insights/activityDescriptions.tsx b/frontend/src/scenes/saved-insights/activityDescriptions.tsx
index bca2dacda8cbe..feb72e5ef65e3 100644
--- a/frontend/src/scenes/saved-insights/activityDescriptions.tsx
+++ b/frontend/src/scenes/saved-insights/activityDescriptions.tsx
@@ -64,7 +64,7 @@ const insightActionsMapping: Record<
description: [
<>
renamed {asNotification && 'the insight '}"{change?.before}" to{' '}
- "{nameOrLinkToInsight(logItem?.detail.short_id, change?.after as string)}"
+ "{nameOrLinkToInsight(logItem.detail?.short_id, change?.after as string)}"
>,
],
suffix: <>>,
@@ -96,7 +96,7 @@ const insightActionsMapping: Record<
{asNotification && ' the insight '}
>,
],
- suffix: <>{nameOrLinkToInsight(logItem?.detail.short_id, logItem?.detail.name)}>,
+ suffix: <>{nameOrLinkToInsight(logItem.detail?.short_id, logItem.detail?.name)}>,
}
},
short_id: function onShortId(change, _, asNotification) {
@@ -114,7 +114,7 @@ const insightActionsMapping: Record<
description: [
<>
renamed {asNotification && ' the insight '}"{change?.before}" to{' '}
- "{nameOrLinkToInsight(logItem?.detail.short_id, change?.after as string)}"
+ "{nameOrLinkToInsight(logItem.detail?.short_id, change?.after as string)}"
>,
],
suffix: <>>,
@@ -140,7 +140,7 @@ const insightActionsMapping: Record<
>,
],
- suffix: <>{nameOrLinkToInsight(logItem?.detail.short_id, logItem?.detail.name)}>,
+ suffix: <>{nameOrLinkToInsight(logItem.detail?.short_id, logItem.detail?.name)}>,
}
},
tags: function onTags(change) {
@@ -185,7 +185,7 @@ const insightActionsMapping: Record<
prefix={
<>
added {asNotification && ' the insight '}
- {nameOrLinkToInsight(logItem?.detail.short_id, logItem?.detail.name)} to
+ {nameOrLinkToInsight(logItem.detail?.short_id, logItem.detail?.name)} to
>
}
listParts={addedDashboards.map((d) => (
@@ -199,7 +199,7 @@ const insightActionsMapping: Record<
prefix={
<>
removed {asNotification && ' the insight '}
- {nameOrLinkToInsight(logItem?.detail.short_id, logItem?.detail.name)} from
+ {nameOrLinkToInsight(logItem.detail?.short_id, logItem.detail?.name)} from
>
}
listParts={removedDashboards.map((d) => (
@@ -255,7 +255,7 @@ export function insightActivityDescriber(logItem: ActivityLogItem, asNotificatio
description: (
<>
{userNameForLogItem(logItem)} created the insight:{' '}
- {nameOrLinkToInsight(logItem?.detail.short_id, logItem?.detail.name)}
+ {nameOrLinkToInsight(logItem.detail?.short_id, logItem.detail?.name)}
>
),
}
@@ -266,7 +266,7 @@ export function insightActivityDescriber(logItem: ActivityLogItem, asNotificatio
description: (
<>
{userNameForLogItem(logItem)} deleted {asNotification ? 'your' : 'the'} insight:{' '}
- {logItem.detail.name}
+ {logItem.detail?.name}
>
),
}
@@ -276,7 +276,7 @@ export function insightActivityDescriber(logItem: ActivityLogItem, asNotificatio
return {
description: (
<>
- PostHog exported {asNotification ? 'your' : 'the'} insight: {logItem.detail.name}{' '}
+ PostHog exported {asNotification ? 'your' : 'the'} insight: {logItem.detail?.name}{' '}
as an image for the shared insight link.
>
),
@@ -288,7 +288,7 @@ export function insightActivityDescriber(logItem: ActivityLogItem, asNotificatio
description: (
<>
{userNameForLogItem(logItem)} shared {asNotification ? 'your' : 'the'} insight:{' '}
- {logItem.detail.name}.
+ {logItem.detail?.name}.
>
),
}
@@ -299,7 +299,7 @@ export function insightActivityDescriber(logItem: ActivityLogItem, asNotificatio
description: (
<>
{userNameForLogItem(logItem)} deleted shared link for{' '}
- {asNotification ? 'your' : 'the'} insight: {logItem.detail.name}.
+ {asNotification ? 'your' : 'the'} insight: {logItem.detail?.name}.
>
),
}
@@ -311,12 +311,12 @@ export function insightActivityDescriber(logItem: ActivityLogItem, asNotificatio
let changeSuffix: Description = (
<>
on {asNotification && ' the insight '}
- {nameOrLinkToInsight(logItem?.detail.short_id, logItem?.detail.name)}
+ {nameOrLinkToInsight(logItem.detail?.short_id, logItem.detail?.name)}
>
)
try {
- for (const change of logItem.detail.changes || []) {
+ for (const change of logItem.detail?.changes || []) {
if (!change?.field || !insightActionsMapping[change.field]) {
continue // insight updates have to have a "field" to be described
}
@@ -357,7 +357,7 @@ export function insightActivityDescriber(logItem: ActivityLogItem, asNotificatio
}
}
if (logItem.activity === 'exported') {
- const exportFormat = logItem.detail.changes?.[0]?.after
+ const exportFormat = logItem.detail?.changes?.[0]?.after
let exportType = 'in an unknown format'
if (typeof exportFormat === 'string') {
exportType = exportFormat.split('/')[1]
@@ -367,11 +367,11 @@ export function insightActivityDescriber(logItem: ActivityLogItem, asNotificatio
description: (
<>
{userNameForLogItem(logItem)} exported{' '}
- {nameOrLinkToInsight(logItem?.detail.short_id, logItem?.detail.name)} as a {exportType}
+ {nameOrLinkToInsight(logItem.detail?.short_id, logItem.detail?.name)} as a {exportType}
>
),
}
}
- return defaultDescriber(logItem, asNotification, nameOrLinkToInsight(logItem?.detail.short_id))
+ return defaultDescriber(logItem, asNotification, nameOrLinkToInsight(logItem.detail?.short_id))
}