Skip to content
3 changes: 2 additions & 1 deletion src/meta/assessment/activityLog/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ export enum ActivityLogMessage {
originalDataPointRemove = 'originalDataPointRemove',
originalDataPointUpdate = 'originalDataPointUpdate',
originalDataPointUpdateDataSources = 'originalDataPointUpdateDataSources',
originalDataPointUpdateDescription = 'originalDataPointUpdateDescription',
originalDataPointUpdateCommentExtentOfForest = 'originalDataPointUpdateCommentExtentOfForest',
originalDataPointUpdateCommentForestCharacteristics = 'originalDataPointUpdateCommentForestCharacteristics',
originalDataPointUpdateNationalClasses = 'originalDataPointUpdateNationalClasses',
originalDataPointUpdateOriginalData = 'originalDataPointUpdateOriginalData',
originalDataPointUpdateYear = 'originalDataPointUpdateYear',
Expand Down
39 changes: 28 additions & 11 deletions src/meta/assessment/activityLogs/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { TFunction } from 'i18next'

import { AreaCode } from 'meta/area'
import { AreaCode, CountryStatus } from 'meta/area'
import { ActivityLog, ActivityLogMessage } from 'meta/assessment/activityLog'
import { AssessmentName } from 'meta/assessment/assessment'
import { Cycle, CycleName } from 'meta/assessment/cycle'
import { Labels } from 'meta/assessment/labels'
import { SectionName, SectionNames, SubSection } from 'meta/assessment/section'
import { Routes } from 'meta/routes'
import { Users } from 'meta/user'
import { RoleName, Users } from 'meta/user'

type ActivityLogTarget = {
assessment?: AssessmentName
file?: string
role?: RoleName
status?: CountryStatus
user?: string
}

const messageToKey: { [key in keyof typeof ActivityLogMessage]?: string } = {
[ActivityLogMessage.assessmentStatusUpdate]: 'updateAssessmentStatus',
Expand All @@ -21,15 +29,16 @@ const messageToKey: { [key in keyof typeof ActivityLogMessage]?: string } = {
[ActivityLogMessage.originalDataPointCreate]: 'added',
[ActivityLogMessage.originalDataPointRemove]: 'deleted',
[ActivityLogMessage.originalDataPointUpdateDataSources]: 'updated',
[ActivityLogMessage.originalDataPointUpdateDescription]: 'updated',
[ActivityLogMessage.originalDataPointUpdateCommentExtentOfForest]: 'updated',
[ActivityLogMessage.originalDataPointUpdateCommentForestCharacteristics]: 'updated',
[ActivityLogMessage.originalDataPointUpdateNationalClasses]: 'updated',
[ActivityLogMessage.originalDataPointUpdateOriginalData]: 'updated',
[ActivityLogMessage.originalDataPointUpdateYear]: 'updated',
[ActivityLogMessage.originalDataPointUpdate]: 'updated',
[ActivityLogMessage.topicStatusChange]: 'resolved',
}

const _getLabelActionKey = (activity: ActivityLog<any>) => {
const _getLabelActionKey = (activity: ActivityLog<ActivityLogTarget>): string => {
const { message } = activity

const key = messageToKey[message]
Expand All @@ -39,9 +48,12 @@ const _getLabelActionKey = (activity: ActivityLog<any>) => {
return 'landing.recentActivity.actions.edited'
}

const _getLabelActionParams = (activity: ActivityLog<any>, t: TFunction) => {
const _getLabelActionParams = (
activity: ActivityLog<ActivityLogTarget>,
t: TFunction
): Record<string, string | null> => {
const { target } = activity
let params = {}
let params: Record<string, string | null> = {}
const { assessment, file, role, status, user } = target ?? {}
if (user)
params = {
Expand All @@ -57,15 +69,15 @@ const _getLabelActionParams = (activity: ActivityLog<any>, t: TFunction) => {
return params
}

const getLabelAction = (props: { activity: ActivityLog<any>; t: TFunction }) => {
const getLabelAction = (props: { activity: ActivityLog<ActivityLogTarget>; t: TFunction }): string => {
const { activity, t } = props
const labelActionKey = _getLabelActionKey(activity)
const messageParams = _getLabelActionParams(activity, t)
const label = t(labelActionKey, messageParams)
return label !== labelActionKey ? label : t('landing.recentActivity.actions.edited')
}

const getLabelSectionKey = (activity: ActivityLog<any>) => {
const getLabelSectionKey = (activity: ActivityLog<ActivityLogTarget>): string => {
const { section } = activity
if (section.indexOf('odp') !== -1) {
return 'nationalDataPoint.nationalDataPoint'
Expand All @@ -78,18 +90,23 @@ const getLabelSectionKey = (activity: ActivityLog<any>) => {
return `${section}.${section}`
}

const hasSectionLink = (activity: ActivityLog<any>) => {
const hasSectionLink = (activity: ActivityLog<ActivityLogTarget>): boolean => {
const { section } = activity
return !['users', 'assessment'].includes(section)
}

const isSectionLinkDisabled = (activity: ActivityLog<any>) => {
const isSectionLinkDisabled = (activity: ActivityLog<ActivityLogTarget>): boolean => {
const { section } = activity
const labelSectionKey = getLabelSectionKey(activity)
return ['fileRepository', 'messageBoard', 'odp'].includes(section) || labelSectionKey === 'dashboard.actions.deleted'
}

const getLabelSection = (props: { cycle: Cycle; section?: SubSection; activity: ActivityLog<any>; t: TFunction }) => {
Comment thread
minotogna marked this conversation as resolved.
const getLabelSection = (props: {
activity: ActivityLog<ActivityLogTarget>
cycle: Cycle
section?: SubSection
t: TFunction
}): string => {
const { activity, cycle, section, t } = props
const labels = section?.props?.labels
const labelSectionKey = labels ? Labels.getCycleLabel({ cycle, labels, t }) : getLabelSectionKey(activity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ActivityLogMessage } from 'meta/assessment/activityLog'
import { Assessment } from 'meta/assessment/assessment'
import { Cycle } from 'meta/assessment/cycle'
import { OriginalDataPoint, OriginalDataPointCommentKey } from 'meta/assessment/originalDataPoint'
import { TableNames } from 'meta/assessment/table'
import { User } from 'meta/user'

import { BaseProtocol, DB } from 'server/db'
Expand All @@ -19,6 +20,11 @@ type Props = {
user: User
}

const activities: Record<OriginalDataPointCommentKey, ActivityLogMessage> = {
[TableNames.extentOfForest]: ActivityLogMessage.originalDataPointUpdateCommentExtentOfForest,
[TableNames.forestCharacteristics]: ActivityLogMessage.originalDataPointUpdateCommentForestCharacteristics,
}

export const updateOriginalDataPointDescription = async (
props: Props,
client: BaseProtocol = DB
Expand All @@ -32,10 +38,12 @@ export const updateOriginalDataPointDescription = async (
t
)

const message = activities[field]

const activityLog = {
target: updatedOriginalDataPoint,
section: 'odp',
message: ActivityLogMessage.originalDataPointUpdateDescription,
message,
countryIso,
user,
}
Expand Down
52 changes: 52 additions & 0 deletions src/server/repository/adapter/originalDataPoint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Objects } from 'utils/objects'

import { CountryIso } from 'meta/area'
import { ODPNationalClass, OriginalDataPoint, OriginalDataPointComments } from 'meta/assessment/originalDataPoint'
import {
OriginalDataPointCommentKey,
OriginalDataPointValues,
} from 'meta/assessment/originalDataPoint/originalDataPoint'
import { TableNames } from 'meta/assessment/table'

import { ODPCommentColumns } from 'server/repository/assessmentCycle/originalDataPoint/commentColumns'

type ODPCommentColName<K extends OriginalDataPointCommentKey = OriginalDataPointCommentKey> = `comments_${Lowercase<K>}`

export type OriginalDataPointDB = {
[K in ODPCommentColName]: string
} & {
country_iso: CountryIso
data_source_additional_comments: string | null
data_source_methods: string | null
data_source_references: string | null
id_legacy: number | null
id: number
national_classes: Array<ODPNationalClass>
values: OriginalDataPointValues
year: number
}

const commentColumnExtent = ODPCommentColumns[TableNames.extentOfForest] as ODPCommentColName<TableNames.extentOfForest>
const commentColumnForestCharacteristics = ODPCommentColumns[
TableNames.forestCharacteristics
] as ODPCommentColName<TableNames.forestCharacteristics>

export const OriginalDataPointAdapter = (row: OriginalDataPointDB): OriginalDataPoint => {
if (Objects.isNil(row)) return null

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When can this be bull ?

@yaguzmang yaguzmang Nov 7, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be null when a query returns no rows, so some tests fail without this check

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange . Which query ? Do we use oneRoNone or map ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's check this in the next pr @yaguzmang we merge this now . It was too big this pr to handle it properly


const {
[commentColumnExtent]: commentsExtentOfForest,
[commentColumnForestCharacteristics]: commentsForestCharacteristics,
...rest
} = row

const comments: OriginalDataPointComments = {
[TableNames.extentOfForest]: commentsExtentOfForest,
[TableNames.forestCharacteristics]: commentsForestCharacteristics,
}

return {
...(Objects.camelize(rest) as OriginalDataPoint),
comments,
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { CountryStatus } from 'meta/area'
import { Assessment } from 'meta/assessment/assessment'
import { Cycle } from 'meta/assessment/cycle'
import { TableNames } from 'meta/assessment/table'

import { Schemas } from 'server/db'
import { NodeExtQueries } from 'server/repository/assessmentCycle/nodeExt/queries'
import { ODPCommentColumns } from 'server/repository/assessmentCycle/originalDataPoint/commentColumns'
import { OriginalDataPointQueries } from 'server/repository/assessmentCycle/originalDataPoint/queries'

export const getCreateSchemaDDL = (schemaName: string): string => {
Expand Down Expand Up @@ -123,7 +125,8 @@ export const getCreateSchemaCycleDDL = (assessmentSchemaName: string, assessment
data_source_additional_comments varchar,
data_source_methods jsonb,
data_source_references text,
comments jsonb not null default '{}'::jsonb,
${ODPCommentColumns[TableNames.extentOfForest]} text default '' not null,
${ODPCommentColumns[TableNames.forestCharacteristics]} text default '' not null,
national_classes jsonb,
values jsonb,
id_legacy bigint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export const acceptedMessages = [
ActivityLogMessage.originalDataPointRemove,
ActivityLogMessage.originalDataPointUpdate,
ActivityLogMessage.originalDataPointUpdateDataSources,
ActivityLogMessage.originalDataPointUpdateDescription,
ActivityLogMessage.originalDataPointUpdateCommentExtentOfForest,
ActivityLogMessage.originalDataPointUpdateCommentForestCharacteristics,
ActivityLogMessage.originalDataPointUpdateNationalClasses,
ActivityLogMessage.originalDataPointUpdateOriginalData,
ActivityLogMessage.originalDataPointUpdateYear,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export const activitiesLastEdit = [
ActivityLogMessage.originalDataPointRemove,
ActivityLogMessage.originalDataPointUpdate,
ActivityLogMessage.originalDataPointUpdateDataSources,
ActivityLogMessage.originalDataPointUpdateDescription,
ActivityLogMessage.originalDataPointUpdateCommentExtentOfForest,
ActivityLogMessage.originalDataPointUpdateCommentForestCharacteristics,
ActivityLogMessage.originalDataPointUpdateNationalClasses,
ActivityLogMessage.originalDataPointUpdateOriginalData,
ActivityLogMessage.originalDataPointUpdateYear,
Expand All @@ -25,7 +26,8 @@ export const activitiesLastEditOdpData = [
ActivityLogMessage.originalDataPointRemove,
ActivityLogMessage.originalDataPointUpdate,
ActivityLogMessage.originalDataPointUpdateDataSources,
ActivityLogMessage.originalDataPointUpdateDescription,
ActivityLogMessage.originalDataPointUpdateCommentExtentOfForest,
ActivityLogMessage.originalDataPointUpdateCommentForestCharacteristics,
ActivityLogMessage.originalDataPointUpdateNationalClasses,
ActivityLogMessage.originalDataPointUpdateOriginalData,
ActivityLogMessage.originalDataPointUpdateYear,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { OriginalDataPointCommentKey } from 'meta/assessment/originalDataPoint'
import { TableNames } from 'meta/assessment/table'

export const ODPCommentColumns: Record<OriginalDataPointCommentKey, string> = {
[TableNames.extentOfForest]: `comments_${TableNames.extentOfForest.toLocaleLowerCase()}`,
[TableNames.forestCharacteristics]: `comments_${TableNames.forestCharacteristics.toLocaleLowerCase()}`,
}
18 changes: 12 additions & 6 deletions src/server/repository/assessmentCycle/originalDataPoint/create.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Objects } from 'utils/objects'

import { Assessment } from 'meta/assessment/assessment'
import { Cycle } from 'meta/assessment/cycle'
import { OriginalDataPoint } from 'meta/assessment/originalDataPoint'
import { TableNames } from 'meta/assessment/table'

import { BaseProtocol, DB, Schemas } from 'server/db'
import { OriginalDataPointAdapter } from 'server/repository/adapter/originalDataPoint'
import { ODPCommentColumns } from 'server/repository/assessmentCycle/originalDataPoint/commentColumns'

export const create = async (
params: {
Expand All @@ -31,6 +32,9 @@ export const create = async (

const schemaName = Schemas.getNameCycle(assessment, cycle)

const commentColumnExtent = ODPCommentColumns[TableNames.extentOfForest]
const commentColumnForestCharacteristics = ODPCommentColumns[TableNames.forestCharacteristics]

return client.one<OriginalDataPoint>(
`
insert into ${schemaName}.original_data_point (
Expand All @@ -39,20 +43,22 @@ export const create = async (
data_source_additional_comments,
data_source_methods,
data_source_references,
comments,
${commentColumnExtent},
${commentColumnForestCharacteristics},
national_classes,
values
) values ($1, $2, $3, $4::jsonb, $5, $6::jsonb, $7::jsonb, $8::jsonb) returning *;`,
) values ($1, $2, $3, $4::jsonb, $5, $6, $7, $8::jsonb, $9::jsonb) returning *;`,
[
countryIso,
year,
dataSourceAdditionalComments || '',
dataSourceMethods ? JSON.stringify(dataSourceMethods) : '[]',
dataSourceReferences || '',
JSON.stringify(comments ?? {}),
comments?.[TableNames.extentOfForest] ?? '',
comments?.[TableNames.forestCharacteristics] ?? '',
nationalClasses ? JSON.stringify(nationalClasses) : '[]',
values ? JSON.stringify(values) : '{}',
],
Objects.camelize
OriginalDataPointAdapter
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Cycle } from 'meta/assessment/cycle'
import { OriginalDataPoint } from 'meta/assessment/originalDataPoint'

import { BaseProtocol, DB } from 'server/db'
import { OriginalDataPointAdapter, OriginalDataPointDB } from 'server/repository/adapter/originalDataPoint'
import { OriginalDataPointQueries } from 'server/repository/assessmentCycle/originalDataPoint/queries'

type Props = {
Expand All @@ -25,6 +26,6 @@ export const getLastAccepted = async (props: Props, client: BaseProtocol = DB):
where a.row_number = 1
`,
[],
({ odp }) => odp
(row?: { odp: OriginalDataPointDB } | null) => (row ? OriginalDataPointAdapter(row.odp) : null)
)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Objects } from 'utils/objects'

import { CountryIso } from 'meta/area'
import { Assessment } from 'meta/assessment/assessment'
import { Cycle } from 'meta/assessment/cycle'
import { OriginalDataPoint } from 'meta/assessment/originalDataPoint'

import { BaseProtocol, DB, Schemas } from 'server/db'
import { OriginalDataPointAdapter } from 'server/repository/adapter/originalDataPoint'

export const getMany = async (
props: { assessment: Assessment; cycle: Cycle; countryIso: CountryIso },
Expand All @@ -18,6 +17,6 @@ export const getMany = async (
return client.map<OriginalDataPoint>(
`select * from ${schemaName}.original_data_point where country_iso = $1;`,
[countryIso],
(row) => Objects.camelize(row)
OriginalDataPointAdapter
)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Objects } from 'utils/objects'

import { Assessment } from 'meta/assessment/assessment'
import { Cycle } from 'meta/assessment/cycle'
import { OriginalDataPoint } from 'meta/assessment/originalDataPoint'
import { TableNames } from 'meta/assessment/table'

import { BaseProtocol, DB, Schemas } from 'server/db'
import { OriginalDataPointAdapter } from 'server/repository/adapter/originalDataPoint'

import { ODPCommentColumns } from './commentColumns'

type Props = {
assessment: Assessment
Expand All @@ -20,13 +21,16 @@ export const getManyWithDescriptionLinks = async (

const schemaName = Schemas.getNameCycle(assessment, cycle)

const commentColumnExtent = ODPCommentColumns[TableNames.extentOfForest]
const commentColumnForestCharacteristics = ODPCommentColumns[TableNames.forestCharacteristics]

return client.map<OriginalDataPoint>(
`
select * from ${schemaName}.original_data_point
where coalesce(comments ->> '${TableNames.extentOfForest}', '') ilike '%href%'
or coalesce(comments ->> '${TableNames.forestCharacteristics}', '') ilike '%href%'
where coalesce(${commentColumnExtent}, '') ilike '%href%'
or coalesce(${commentColumnForestCharacteristics}, '') ilike '%href%'
`,
[],
(row) => Objects.camelize(row)
OriginalDataPointAdapter
)
}
Loading