diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/index.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/index.ts index 191c6ecd6c..09f798b4e2 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/index.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/index.ts @@ -15,19 +15,27 @@ import organizationsEditProfile from './organizations-edit-profile'; import organizationsMerge from './organizations-merge'; import organizationsUnmerge from './organizations-unmerge'; -export interface LogRenderingConfig { +export interface LogChanges { + removals: string[]; + additions: string[]; + changes: string[]; +} + +interface MergeLogEntity { + id?: string; + displayName?: string; +} + +export interface MergeLogState { + primary: MergeLogEntity; + secondary?: MergeLogEntity; +} + +export interface LogRenderingConfig { label: string; - description: (log: AuditLog) => string; - properties?: (log: AuditLog) => {label: string, value: string;}[]; - changes?: (log: AuditLog) => Promise<{ - removals: string[] - additions: string[] - changes: string[] - } | null> | { - removals: string[] - additions: string[] - changes: string[] - } | null + description(log: AuditLog): string; + properties?(log: AuditLog): {label: string, value: string;}[]; + changes?(log: AuditLog): Promise | LogChanges | null; } export const logRenderingConfig: Record = { diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/integrations-connect.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/integrations-connect.ts index 378eb9133c..8d28c274e9 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/integrations-connect.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/integrations-connect.ts @@ -1,18 +1,18 @@ import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; import { lfIdentities } from '@/config/identities'; -const integrationsConnect: LogRenderingConfig = { +const integrationsConnect: LogRenderingConfig<{ platform?: string }> = { label: 'Integration connected', changes: () => null, description: (log) => { - const integration = lfIdentities[log.newState?.platform || log.oldState?.platform]; + const integration = lfIdentities[log.newState?.platform || log.oldState?.platform || '']; if (integration) { return `Integration: ${integration.name}`; } return ''; }, properties: (log) => { - const integration = lfIdentities[log.newState?.platform || log.oldState?.platform]; + const integration = lfIdentities[log.newState?.platform || log.oldState?.platform || '']; if (integration) { return [{ label: 'Integration', diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/integrations-reconnect.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/integrations-reconnect.ts index efa3b3d0f1..94106ef47d 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/integrations-reconnect.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/integrations-reconnect.ts @@ -1,18 +1,18 @@ import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; import { lfIdentities } from '@/config/identities'; -const integrationsReconnect: LogRenderingConfig = { +const integrationsReconnect: LogRenderingConfig<{ platform?: string }> = { label: 'Integration re-connected', changes: () => null, description: (log) => { - const integration = lfIdentities[log.newState?.platform || log.oldState?.platform]; + const integration = lfIdentities[log.newState?.platform || log.oldState?.platform || '']; if (integration) { return `Integration: ${integration.name}`; } return ''; }, properties: (log) => { - const integration = lfIdentities[log.newState?.platform || log.oldState?.platform]; + const integration = lfIdentities[log.newState?.platform || log.oldState?.platform || '']; if (integration) { return [{ label: 'Integration', diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-create.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-create.ts index 4001b277ee..e34ed04bb7 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-create.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-create.ts @@ -1,6 +1,6 @@ import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; -const membersCreate: LogRenderingConfig = { +const membersCreate: LogRenderingConfig = { label: 'Profile created', changes: () => null, description: (log) => { diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-identities.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-identities.ts index 5e9965c2f0..cc0c3636dd 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-identities.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-identities.ts @@ -1,7 +1,9 @@ import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; import { lfIdentities } from '@/config/identities'; -const membersEditIdentities: LogRenderingConfig = { +type MemberIdentitiesState = Record; + +const membersEditIdentities: LogRenderingConfig = { label: 'Profile identities updated', changes: (log) => { const removals = []; diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-manual-affiliation.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-manual-affiliation.ts index 37f0ea6845..36b895ef6b 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-manual-affiliation.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-manual-affiliation.ts @@ -1,9 +1,16 @@ -import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; +import type { LogChanges, LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; import { OrganizationService } from '@/modules/organization/organization-service'; import { LfService } from '@/modules/lf/segments/lf-segments-service'; import { dateHelper } from '@/shared/date-helper/date-helper'; -const formatDateRange = (dateStart, dateEnd) => { +interface MemberAffiliationStateRow { + organizationId: string | null; + segmentId: string; + dateStart?: string | null; + dateEnd?: string | null; +} + +const formatDateRange = (dateStart?: string | null, dateEnd?: string | null) => { // eslint-disable-next-line no-nested-ternary const dateStartFormat = dateStart ? dateHelper(dateStart).utc().format('MMMM YYYY') @@ -15,10 +22,10 @@ const formatDateRange = (dateStart, dateEnd) => { return `${dateStartFormat} -> ${dateEndFormat}`; }; -const membersEditManualAffiliation: LogRenderingConfig = { +const membersEditManualAffiliation: LogRenderingConfig = { label: 'Profile affiliation updated', changes: async (log) => { - const changes = { + const changes: LogChanges = { removals: [], additions: [], changes: [], @@ -41,15 +48,15 @@ const membersEditManualAffiliation: LogRenderingConfig = { ]), ]; - const orgs = await OrganizationService.listByIds(orgIds); - const segments = await LfService.listSegmentsByIds(segmentIds); + const orgs: { id: string; displayName: string }[] = await OrganizationService.listByIds(orgIds); + const segments: { id: string; name: string }[] = await LfService.listSegmentsByIds(segmentIds); - const orgById = orgs.reduce((obj, org) => ({ + const orgById = orgs.reduce>((obj, org) => ({ ...obj, [org.id]: org.displayName, }), {}); - const segmentById = segments.reduce((obj, org) => ({ + const segmentById = segments.reduce>((obj, org) => ({ ...obj, [org.id]: org.name, }), {}); @@ -65,7 +72,7 @@ const membersEditManualAffiliation: LogRenderingConfig = {
(${formatDateRange(dateStart, dateEnd)})`, ); } else { - const newOrg = newStateMap.get(org.organizationId); + const newOrg = newStateMap.get(org.organizationId)!; if (org.dateStart !== newOrg.dateStart || org.dateEnd !== newOrg.dateEnd || org.segmentId !== newOrg.segmentId) { changes.changes.push( `${org.organizationId ? (orgById[org.organizationId]) : 'Individual'} : diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-organizations.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-organizations.ts index 0ae75231bd..d1ef67503b 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-organizations.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-organizations.ts @@ -1,8 +1,15 @@ -import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; +import type { LogChanges, LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; import { OrganizationService } from '@/modules/organization/organization-service'; import { dateHelper } from '@/shared/date-helper/date-helper'; -const formatDateRange = (dateStart, dateEnd) => { +interface MemberOrganizationStateRow { + organizationId: string; + title?: string | null; + dateStart: string | null; + dateEnd: string | null; +} + +const formatDateRange = (dateStart: string | null, dateEnd: string | null) => { // eslint-disable-next-line no-nested-ternary const dateStartFormat = dateStart ? dateHelper(dateStart) @@ -18,10 +25,10 @@ const formatDateRange = (dateStart, dateEnd) => { return `${dateStartFormat} -> ${dateEndFormat}`; }; -const membersEditOrganizations: LogRenderingConfig = { +const membersEditOrganizations: LogRenderingConfig = { label: 'Profile work experience updated', changes: async (log) => { - const changes = { + const changes: LogChanges = { removals: [], additions: [], changes: [], @@ -41,8 +48,8 @@ const membersEditOrganizations: LogRenderingConfig = { ]), ]; - const orgs = await OrganizationService.listByIds(orgIds); - const orgById = orgs.reduce((obj, org) => ({ + const orgs: { id: string; displayName: string }[] = await OrganizationService.listByIds(orgIds); + const orgById = orgs.reduce>((obj, org) => ({ ...obj, [org.id]: org.displayName, }), {}); @@ -52,7 +59,7 @@ const membersEditOrganizations: LogRenderingConfig = { if (!newStateMap.has(org.organizationId)) { changes.removals.push(`Organization: ${org.organizationId ? (orgById[org.organizationId]) : 'Individual'}`); } else { - const newOrg = newStateMap.get(org.organizationId); + const newOrg = newStateMap.get(org.organizationId)!; if ( formatDateRange(org.dateStart, org.dateEnd) !== formatDateRange(newOrg.dateStart, newOrg.dateEnd) || (org.title || '') !== (newOrg.title || '')) { diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-profile.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-profile.ts index 853d47eb84..68cb6483ac 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-profile.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-edit-profile.ts @@ -19,17 +19,23 @@ function flattenObject(obj) { return flattenedObj; } -const membersEditProfile: LogRenderingConfig = { +interface MemberProfileState { + attributes?: Record>; + [key: string]: unknown; +} + +const membersEditProfile: LogRenderingConfig = { label: 'Profile updated', changes: (log) => { const additions: any[] = []; const removals: any[] = []; const changes: any[] = []; - const oldState = { ...log.oldState, ...flattenObject(log.oldState.attributes) }; - const newState = { ...log.newState, ...flattenObject(log.newState.attributes) }; + const oldState: Record = { ...log.oldState, ...flattenObject(log.oldState.attributes) }; + const newState: Record = { ...log.newState, ...flattenObject(log.newState.attributes) }; const diff = { - ...log.diff, + // diff is the deep-object-diff of the two states, always an object. + ...(log.diff as Record), ...{ ...flattenObject(log.oldState.attributes), ...flattenObject(log.newState.attributes) }, }; delete oldState.attributes; diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-merge.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-merge.ts index f9c00a024e..0d5d3ed970 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-merge.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-merge.ts @@ -1,6 +1,6 @@ -import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; +import type { LogRenderingConfig, MergeLogState } from '@/modules/lf/config/audit-logs/log-rendering/index'; -const membersMerge: LogRenderingConfig = { +const membersMerge: LogRenderingConfig = { label: 'Profiles merged', changes: (log) => { const primary = log.oldState?.primary; diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-unmerge.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-unmerge.ts index 45d5823e04..12b044239d 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/members-unmerge.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/members-unmerge.ts @@ -1,6 +1,6 @@ -import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; +import type { LogRenderingConfig, MergeLogState } from '@/modules/lf/config/audit-logs/log-rendering/index'; -const membersMerge: LogRenderingConfig = { +const membersMerge: LogRenderingConfig = { label: 'Profiles unmerged', changes: (log) => { const primary = log.oldState?.primary; diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-create.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-create.ts index 7b23695f1a..2a18afcb27 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-create.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-create.ts @@ -1,6 +1,6 @@ import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; -const organizationsCreate: LogRenderingConfig = { +const organizationsCreate: LogRenderingConfig = { label: 'Organization created', changes: () => null, description: (log) => { diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-edit-identities.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-edit-identities.ts index 332d49d116..79ee8ef116 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-edit-identities.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-edit-identities.ts @@ -1,7 +1,9 @@ import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; import { lfIdentities } from '@/config/identities'; -const organizationsEditIdentities: LogRenderingConfig = { +type OrganizationIdentitiesState = Record; + +const organizationsEditIdentities: LogRenderingConfig = { label: 'Organization identities updated', changes: ({ oldState, newState }) => { const additions: any[] = []; diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-edit-profile.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-edit-profile.ts index 6817ae3874..19e3c1d0cd 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-edit-profile.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-edit-profile.ts @@ -5,14 +5,15 @@ function camelCaseToName(camelCase) { .replace(/^./, (str) => str.toUpperCase()); } -const organizationsEditProfile: LogRenderingConfig = { +const organizationsEditProfile: LogRenderingConfig> = { label: 'Organization profile updated', changes: ({ oldState, newState, diff }) => { const additions = []; const removals = []; const changes = []; - Object.keys(diff).forEach((key) => { + // diff is the deep-object-diff of the two states, always an object. + Object.keys(diff as Record).forEach((key) => { const keyName = camelCaseToName(key); if (!!oldState[key] && !newState[key] && newState[key] !== undefined) { const display = typeof oldState[key] === 'object' ? JSON.stringify(oldState[key]) : `${oldState[key]}`; diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-merge.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-merge.ts index 1f14c08370..653d5435ac 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-merge.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-merge.ts @@ -1,6 +1,6 @@ -import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; +import type { LogRenderingConfig, MergeLogState } from '@/modules/lf/config/audit-logs/log-rendering/index'; -const organizationsMerge: LogRenderingConfig = { +const organizationsMerge: LogRenderingConfig = { label: 'Organizations merged', changes: (log) => { const primary = log.oldState?.primary; diff --git a/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-unmerge.ts b/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-unmerge.ts index 7f2775dc23..cde326068f 100644 --- a/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-unmerge.ts +++ b/frontend/src/modules/lf/config/audit-logs/log-rendering/organizations-unmerge.ts @@ -1,6 +1,6 @@ -import type { LogRenderingConfig } from '@/modules/lf/config/audit-logs/log-rendering/index'; +import type { LogRenderingConfig, MergeLogState } from '@/modules/lf/config/audit-logs/log-rendering/index'; -const organizationsMerge: LogRenderingConfig = { +const organizationsMerge: LogRenderingConfig = { label: 'Organizations unmerged', changes: (log) => { const primary = log.oldState?.primary; diff --git a/frontend/src/modules/lf/segments/components/logs/sections/log-changes.vue b/frontend/src/modules/lf/segments/components/logs/sections/log-changes.vue index d80bfc87cb..5f7cc9adc4 100644 --- a/frontend/src/modules/lf/segments/components/logs/sections/log-changes.vue +++ b/frontend/src/modules/lf/segments/components/logs/sections/log-changes.vue @@ -33,6 +33,7 @@