diff --git a/server/modules/record/manager/_recordManager/nodeCreationManager.js b/server/modules/record/manager/_recordManager/nodeCreationManager.js index f0fd12a933..6ff57f2d80 100644 --- a/server/modules/record/manager/_recordManager/nodeCreationManager.js +++ b/server/modules/record/manager/_recordManager/nodeCreationManager.js @@ -11,11 +11,11 @@ import * as Node from '@core/record/node' import * as ActivityLogRepository from '@server/modules/activityLog/repository/activityLogRepository' import * as NodeRepository from '../../repository/nodeRepository' -const _createUpdateResult = (record, node = null, nodes = {}) => { +const _createUpdateResult = ({ record, node = null, nodes = {}, sideEffect = false }) => { if (!node && Objects.isEmpty(nodes)) { return { record, nodes: {} } } - const recordUpdated = Objects.isEmpty(nodes) ? record : Record.mergeNodes(nodes)(record) + const recordUpdated = Objects.isEmpty(nodes) ? record : Record.mergeNodes(nodes, { sideEffect })(record) const parentNode = Record.getParentNode(node)(recordUpdated) @@ -58,7 +58,17 @@ export const insertNodesInBatch = async ({ user, surveyId, nodes, systemActivity } export const insertNode = async ( - { user, survey, record, node, system, timezoneOffset, persistNodes = true, createMultipleEntities = true }, + { + user, + survey, + record, + node, + system, + timezoneOffset, + persistNodes = true, + createMultipleEntities = true, + sideEffect = false, + }, t ) => { node[Node.keys.created] = true // mark node as created (flag used by RDB manager to update data tables) @@ -72,7 +82,7 @@ export const insertNode = async ( const parentNode = Record.getParentNode(node)(record) const siblings = Record.getNodeChildrenByDefUuid(parentNode, Node.getNodeDefUuid(node))(record) if (siblings.some((sibling) => Objects.isEqual(Node.getValue(sibling), Node.getValue(node)))) { - return _createUpdateResult(record) + return _createUpdateResult({ record, sideEffect }) } } @@ -101,5 +111,5 @@ export const insertNode = async ( ) : nodesCreated - return _createUpdateResult(recordUpdated, node, nodesInserted) + return _createUpdateResult({ record: recordUpdated, node, nodes: nodesInserted, sideEffect }) } diff --git a/server/modules/survey/service/recordCheckJob.js b/server/modules/survey/service/recordCheckJob.js index bc906ace12..084b2caeec 100644 --- a/server/modules/survey/service/recordCheckJob.js +++ b/server/modules/survey/service/recordCheckJob.js @@ -9,7 +9,6 @@ import * as RecordValidation from '@core/record/recordValidation' import * as Node from '@core/record/node' import * as Validation from '@core/validation/validation' import * as ObjectUtils from '@core/objectUtils' -import * as PromiseUtils from '@core/promiseUtils' import BatchPersister from '@server/db/batchPersister' import Job from '@server/job/job' @@ -30,7 +29,7 @@ export default class RecordCheckJob extends Job { this.total = R.length(recordsUuidAndCycle) - await PromiseUtils.each(recordsUuidAndCycle, async ({ uuid: recordUuid, cycle }) => { + for await (const { uuid: recordUuid, cycle } of recordsUuidAndCycle) { const surveyAndNodeDefs = await this._getOrFetchSurveyAndNodeDefsByCycle(cycle) const { requiresCheck } = surveyAndNodeDefs @@ -40,7 +39,7 @@ export default class RecordCheckJob extends Job { } this.incrementProcessedItems() - }) + } } _cleanSurveysCache(cycleToKeep) { @@ -136,10 +135,12 @@ export default class RecordCheckJob extends Job { // 3. insert missing nodes if (!R.isEmpty(nodeDefAddedUuids)) { + // this.logDebug(`inserting missing nodes with node def uuids ${nodeDefAddedUuids}`) const { record: recordUpdateInsert, nodes: nodesUpdatedMissing = {} } = await this._insertMissingSingleNodes({ survey, nodeDefAddedUuids, record, + sideEffect: true, }) record = recordUpdateInsert || record Object.assign(nodesInsertedByUuid, nodesUpdatedMissing) @@ -150,6 +151,7 @@ export default class RecordCheckJob extends Job { const nodeDefAddedOrUpdatedUuids = R.concat(nodeDefAddedUuids, nodeDefUpdatedUuids) if (!R.isEmpty(nodeDefUpdatedUuids) || !R.isEmpty(nodesInsertedByUuid)) { + // this.logDebug('applying default values') const { record: recordUpdate, nodes: nodesUpdatedDefaultValues = {} } = await _applyDefaultValuesAndApplicability( survey, nodeDefAddedOrUpdatedUuids, @@ -162,12 +164,13 @@ export default class RecordCheckJob extends Job { } // 4a. Persist nodes + // this.logDebug('persisting nodes') const allUpdatedNodesArray = Object.values(allUpdatedNodesByUuid) for await (const node of allUpdatedNodesArray) { if (Node.isCreated(node)) { - this.nodesBatchInserter.addItem(node, tx) + await this.nodesBatchInserter.addItem(node, tx) } else if (Node.isUpdated(node)) { - this.nodesBatchUpdater.addItem(node, tx) + await this.nodesBatchUpdater.addItem(node, tx) } } @@ -191,25 +194,26 @@ export default class RecordCheckJob extends Job { // Inserts all the missing single nodes in the specified records having the node def in the specified ones. // Returns an indexed object with all the inserted nodes. - async _insertMissingSingleNodes({ survey, nodeDefAddedUuids, record }) { + async _insertMissingSingleNodes({ survey, nodeDefAddedUuids, record, sideEffect = false }) { const nodesUpdated = {} let recordUpdated = { ...record } - await PromiseUtils.each(nodeDefAddedUuids, async (nodeDefUuid) => { + for await (const nodeDefUuid of nodeDefAddedUuids) { const nodeDef = Survey.getNodeDefByUuid(nodeDefUuid)(survey) const parentNodes = Record.getNodesByDefUuid(NodeDef.getParentUuid(nodeDef))(recordUpdated) - await PromiseUtils.each(parentNodes, async (parentNode) => { - const { record: recordUpdatedNodeInsert, nodes } = await _insertMissingSingleNode( + for await (const parentNode of parentNodes) { + const { record: recordUpdatedNodeInsert, nodes } = await _insertMissingSingleNode({ survey, - nodeDef, - recordUpdated, + childDef: nodeDef, + record: recordUpdated, parentNode, - this.user, - this.tx - ) + user: this.user, + tx: this.tx, + sideEffect, + }) Object.assign(nodesUpdated, nodes) recordUpdated = recordUpdatedNodeInsert || recordUpdated - }) - }) + } + } return { record: recordUpdated, nodes: nodesUpdated } } @@ -232,7 +236,7 @@ export default class RecordCheckJob extends Job { // Inserts a missing single node in a specified parent node. // Returns an indexed object with all the inserted nodes. -const _insertMissingSingleNode = async (survey, childDef, record, parentNode, user, tx) => { +const _insertMissingSingleNode = async ({ survey, childDef, record, parentNode, user, tx, sideEffect = false }) => { if (!NodeDef.isSingle(childDef)) { // multiple node: don't insert it return {} @@ -244,7 +248,10 @@ const _insertMissingSingleNode = async (survey, childDef, record, parentNode, us } // insert missing single node const childNode = Node.newNode(NodeDef.getUuid(childDef), Record.getUuid(record), parentNode) - return RecordManager.insertNode({ user, survey, record, node: childNode, system: true, persistNodes: false }, tx) + return RecordManager.insertNode( + { user, survey, record, node: childNode, system: true, persistNodes: false, sideEffect }, + tx + ) } const _applyDefaultValuesAndApplicability = async (survey, nodeDefUpdatedUuids, record, newNodes, tx) => { @@ -261,7 +268,7 @@ const _applyDefaultValuesAndApplicability = async (survey, nodeDefUpdatedUuids, }) return RecordManager.updateNodesDependents( - { survey, record, nodes: nodesToUpdate, perstistNodes: false, sideEffect: true }, + { survey, record, nodes: nodesToUpdate, persistNodes: false, sideEffect: true }, tx ) } diff --git a/webapp/style/formBase.scss b/webapp/style/formBase.scss index 871f908d4d..4f6dd61ee9 100644 --- a/webapp/style/formBase.scss +++ b/webapp/style/formBase.scss @@ -52,6 +52,7 @@ a:visited { // buttons button, .btn { + cursor: pointer; padding: 0.7rem 0.8rem; font-weight: 400; border: 1px solid $greyBorder;