Skip to content

Commit

Permalink
3804 - add MetadataController.addColumn + add 2023 col to fra 2025 ta…
Browse files Browse the repository at this point in the history
…bles 5a and 5b (#3806)
  • Loading branch information
minotogna authored May 14, 2024
1 parent dbb8679 commit 669923a
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 48 deletions.
2 changes: 1 addition & 1 deletion src/meta/assessment/col.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export interface ColProps {
linkedNodes?: Record<CycleUuid, ColLinkedNode>
readonly?: boolean
select?: ColSelectProps
style: Record<CycleUuid, ColStyle>
style?: Record<CycleUuid, ColStyle>
validateFns?: Record<CycleUuid, Array<string>>
variableNo?: Record<CycleUuid, string>

Expand Down
57 changes: 57 additions & 0 deletions src/server/controller/metadata/addColumn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Assessment, ColProps, Cycle, Row, Table, TableProps } from 'meta/assessment'

import { BaseProtocol, DB } from 'server/db'
import { ColRepository } from 'server/repository/assessment/col'
import { TableRepository } from 'server/repository/assessment/table'

type Props = {
assessment: Assessment
cycles: Array<Cycle>
table: Table
colProps: ColProps
}

export const addColumn = async (props: Props, client: BaseProtocol = DB): Promise<void> => {
const { assessment, cycles, table, colProps } = props

// split rows
const rows = table.rows.reduce<[Array<Row>, Array<Row>]>(
(acc, row) => {
if (row.cols?.length === 2) acc[0].push(row) // header
if (row.cols?.length > 2) acc[1].push(row) // data
return acc
},
[[], []]
)

// insert cols
const colLengths = await Promise.all(
rows[1].map<Promise<number>>(async (row) => {
await ColRepository.create({ assessment, cycles, row, colProps }, client)
return row.cols.length + 1
})
)

// update col header colSpan
await Promise.all(
rows[0].map(async (row) => {
const col = row.cols.at(-1)
const style = cycles.reduce<ColProps['style']>((acc, cycle) => {
const colSpan = Math.max(...colLengths) - 1
return { ...acc, [cycle.uuid]: { ...acc[cycle.uuid], colSpan } }
}, col.props.style ?? {})

await ColRepository.update({ assessment, colId: col.id, colProps: { style } }, client)
})
)

// update table props column names
const columnsExport = cycles.reduce<TableProps['columnsExport']>((acc, cycle) => {
return { ...acc, [cycle.uuid]: [...(table.props.columnsExport?.[cycle.uuid] ?? []), colProps.colName] }
}, table.props.columnsExport ?? {})
const columnNames = cycles.reduce<TableProps['columnNames']>((acc, cycle) => {
return { ...acc, [cycle.uuid]: [...(table.props.columnNames?.[cycle.uuid] ?? []), colProps.colName] }
}, table.props.columnNames ?? {})

await TableRepository.update({ assessment, tableId: table.id, tableProps: { columnsExport, columnNames } }, client)
}
3 changes: 3 additions & 0 deletions src/server/controller/metadata/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { TableRepository } from 'server/repository/assessment/table'
import { TableSectionRepository } from 'server/repository/assessment/tableSection'
import { SectionRedisRepository } from 'server/repository/redis/section'

import { addColumn } from './addColumn'
import { createSection } from './createSection'
import { createSubSection } from './createSubSection'
import { createTable } from './createTable'
Expand Down Expand Up @@ -36,4 +37,6 @@ export const MetadataController = {
createTable,
updateTable,
removeTable,

addColumn,
}
35 changes: 15 additions & 20 deletions src/server/controller/metadata/updateTable.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
import { ActivityLogMessage, Assessment, Table } from 'meta/assessment'
import { ActivityLogMessage, Assessment, Table, TableProps } from 'meta/assessment'
import { User } from 'meta/user'

import { BaseProtocol, DB } from 'server/db'
import { TableRepository } from 'server/repository/assessment/table'
import { ActivityLogRepository } from 'server/repository/public/activityLog'

type Props = {
assessment: Assessment
table: Table
tableProps: Partial<TableProps>
user: User
}

// Controller to update Table
export const updateTable = async (
props: { user: User; assessment: Assessment; table: Table },
client: BaseProtocol = DB
): Promise<Table> => {
const { user, assessment, table } = props
export const updateTable = async (props: Props, client: BaseProtocol = DB): Promise<Table> => {
const { assessment, table, tableProps, user } = props

return client.tx(async (t) => {
const updatedTable = await TableRepository.update({ table, assessment }, t)
const target = await TableRepository.update({ assessment, tableId: table.id, tableProps }, t)

const activityLog = { target, section: 'table', message: ActivityLogMessage.tableUpdate, user }
await ActivityLogRepository.insertActivityLog({ assessment, activityLog }, t)

await ActivityLogRepository.insertActivityLog(
{
activityLog: {
target: updatedTable,
section: 'table',
message: ActivityLogMessage.tableUpdate,
user,
},
assessment,
},
t
)
return updatedTable
return target
})
}
28 changes: 28 additions & 0 deletions src/server/repository/assessment/col/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Assessment, Col, ColProps, Cycle, Row } from 'meta/assessment'

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

type Props = {
assessment: Assessment
cycles: Array<Cycle>
row: Row
colProps: ColProps
}

export const create = async (props: Props, client: BaseProtocol = DB): Promise<Col> => {
const { assessment, cycles, row } = props

const colProps = { ...props.colProps, cycles: cycles.map(({ uuid }) => uuid) }

const schemaName = Schemas.getName(assessment)

return client.one<Col>(
`
insert into ${schemaName}.col (props, row_id)
values ($1::jsonb, $2)
returning *`,
[JSON.stringify(colProps), +row.id],
ColAdapter
)
}
4 changes: 4 additions & 0 deletions src/server/repository/assessment/col/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { create } from './create'
import { getMany } from './getMany'
import { update } from './update'

export const ColRepository = {
create,
getMany,
update,
}
26 changes: 26 additions & 0 deletions src/server/repository/assessment/col/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Assessment, Col } from 'meta/assessment'

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

type Props = {
assessment: Assessment
colId: number
colProps: Partial<Col['props']>
}

export const update = async (props: Props, client: BaseProtocol = DB): Promise<Col> => {
const { assessment, colId, colProps } = props

const schemaName = Schemas.getName(assessment)

return client.one<Col>(
`
update ${schemaName}.col
set props = props || $1::jsonb
where id = $2
returning *;`,
[JSON.stringify(colProps), +colId],
ColAdapter
)
}
14 changes: 9 additions & 5 deletions src/server/repository/assessment/table/getOne.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { Assessment, Cycle, Table } from 'meta/assessment'
import { Assessment, Cycle, Table, TableName } from 'meta/assessment'

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

export const getOne = async (
props: { assessment: Assessment; cycle: Cycle; tableName: string },
client: BaseProtocol = DB
): Promise<Table> => {
type Props = {
assessment: Assessment
cycle: Cycle
tableName: TableName
}

export const getOne = async (props: Props, client: BaseProtocol = DB): Promise<Table> => {
const { assessment, cycle } = props

const schemaName = Schemas.getName(assessment)

return client.one<Table>(
Expand Down
32 changes: 16 additions & 16 deletions src/server/repository/assessment/table/update.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { Objects } from 'utils/objects'

import { Assessment, Table } from 'meta/assessment'
import { Assessment, Table, TableProps } from 'meta/assessment'

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

type Props = {
assessment: Assessment
tableId: number
tableProps: Partial<TableProps>
}

export const update = async (params: Props, client: BaseProtocol = DB): Promise<Table> => {
const { assessment, tableId, tableProps } = params

// Update table in database
export const update = async (
params: {
table: Table
assessment: Assessment
},
client: BaseProtocol = DB
): Promise<Table> => {
const { table, assessment } = params
const schemaName = Schemas.getName(assessment)

return client.one<Table>(
`
update ${schemaName}.table
set props = $1::jsonb, table_section_id = $2
where id = $3 returning *;`,
[JSON.stringify(table.props), +table.tableSectionId, +table.id],
Objects.camelize
set props = props || $1::jsonb
where id = $2
returning *;`,
[JSON.stringify(tableProps), +tableId],
TableAdapter
)
}
9 changes: 3 additions & 6 deletions src/test/integration/table/updateTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,9 @@ export default () =>
const tableUpdated = await MetadataController.updateTable({
assessment,
user,
table: {
...table,
props: {
...table.props,
name: 'updated name',
},
table,
tableProps: {
name: 'updated name',
},
})

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { AssessmentNames, ColProps, ColType, Table, TableName, TableSection } from 'meta/assessment'

import { AssessmentController } from 'server/controller/assessment'
import { MetadataController } from 'server/controller/metadata'
import { BaseProtocol } from 'server/db'

const assessmentName = AssessmentNames.fra
const cycleName = '2025'
const sectionNames = ['disturbances', 'areaAffectedByFire']
const colProps: ColProps = { colName: '2023', colType: ColType.decimal }

const findTable = (tableSections: Array<TableSection>, tableName: TableName): Table => {
for (let i = 0; i < tableSections.length; i += 1) {
const table = tableSections[i].tables.find((table) => table.props.name === tableName)
if (table) return table
}
return undefined
}

export default async (client: BaseProtocol) => {
const { assessment, cycle } = await AssessmentController.getOneWithCycle({ assessmentName, cycleName }, client)

const sectionsMetadata = await MetadataController.getSectionsMetadata({ assessment, cycle, sectionNames }, client)

await Promise.all(
sectionNames.map((sectionName) => {
const table = findTable(sectionsMetadata[sectionName], sectionName)
return MetadataController.addColumn({ assessment, cycles: [cycle], table, colProps }, client)
})
)

await AssessmentController.generateMetadataCache({ assessment }, client)
}

0 comments on commit 669923a

Please sign in to comment.