diff --git a/app/api/entities.v2/contracts/EntitiesDataSource.ts b/app/api/entities.v2/contracts/EntitiesDataSource.ts index f31c363cd7..2ce9d83b24 100644 --- a/app/api/entities.v2/contracts/EntitiesDataSource.ts +++ b/app/api/entities.v2/contracts/EntitiesDataSource.ts @@ -6,6 +6,7 @@ type MarkAsChangedData = { property: string } | { properties: string[] }; export type MarkAsChangedItems = MarkAsChangedCriteria & MarkAsChangedData; export interface EntitiesDataSource { + updateEntity(entity: Entity): Promise; updateObsoleteMetadataValues( id: Entity['_id'], values: Record diff --git a/app/api/entities.v2/database/MongoEntitiesDataSource.ts b/app/api/entities.v2/database/MongoEntitiesDataSource.ts index 61635e415e..e8f9ff67a3 100644 --- a/app/api/entities.v2/database/MongoEntitiesDataSource.ts +++ b/app/api/entities.v2/database/MongoEntitiesDataSource.ts @@ -7,6 +7,7 @@ import entities from 'api/entities/entities'; import { MongoSettingsDataSource } from 'api/settings.v2/database/MongoSettingsDataSource'; import { MongoTemplatesDataSource } from 'api/templates.v2/database/MongoTemplatesDataSource'; import { Db } from 'mongodb'; +import { MetadataSchema } from 'shared/types/commonTypes'; import { EntitiesDataSource } from '../contracts/EntitiesDataSource'; import { Entity, EntityMetadata, MetadataValue } from '../model/Entity'; import { EntityMappers } from './EntityMapper'; @@ -33,6 +34,20 @@ export class MongoEntitiesDataSource this.settingsDS = settingsDS; } + // eslint-disable-next-line class-methods-use-this + async updateEntity(entity: Entity) { + // This is using V1 so that it gets denormalized to speed up development + // this is a hack and should be changed as soon as we finish AT + const entityToModify = await entities.getById(entity._id); + if (!entityToModify) { + throw new Error(`entity does not exists: ${entity._id}`); + } + + entityToModify.title = entity.title; + entityToModify.metadata = entity.metadata as MetadataSchema; + await entities.save(entityToModify, { user: {}, language: entityToModify.language }); + } + async entitiesExist(sharedIds: string[]) { const languages = await this.settingsDS.getLanguageKeys(); const countInExistence = await this.getCollection().countDocuments({ diff --git a/app/api/entities.v2/model/Entity.ts b/app/api/entities.v2/model/Entity.ts index 6491c59c08..a24a7b6d8e 100644 --- a/app/api/entities.v2/model/Entity.ts +++ b/app/api/entities.v2/model/Entity.ts @@ -1,3 +1,6 @@ +import { CommonProperty } from 'api/templates.v2/model/CommonProperty'; +import { Property } from 'api/templates.v2/model/Property'; + type MetadataValue = unknown; type BaseMetadataValue = { @@ -46,6 +49,27 @@ export class Entity { this.metadata = metadata; this.obsoleteMetadata = obsoleteMetadata ?? []; } + + changePropertyValue(property: Property, value: string) { + if (property.type === 'text') { + const isTitleProperty = property instanceof CommonProperty && property.name === 'title'; + const { metadata } = this; + if (!(property instanceof CommonProperty)) { + metadata[property.name] = this.metadata[property.name] || [{ value: '' }]; + metadata[property.name][0].value = value; + } + return new Entity( + this._id, + this.sharedId, + this.language, + isTitleProperty ? value : this.title, + this.template, + metadata + ); + } + + throw new Error('types other than string are not implemented yet'); + } } export type { Metadata, EntityMetadata, MetadataValue }; diff --git a/app/api/externalIntegrations.v2/automaticTranslation/SaveEntityTranslations.ts b/app/api/externalIntegrations.v2/automaticTranslation/SaveEntityTranslations.ts index 91169687b8..7d7b147915 100644 --- a/app/api/externalIntegrations.v2/automaticTranslation/SaveEntityTranslations.ts +++ b/app/api/externalIntegrations.v2/automaticTranslation/SaveEntityTranslations.ts @@ -30,29 +30,19 @@ export class SaveEntityTranslations { const [, entitySharedId, propertyId] = translationResult.key; - const { property, scope } = await this.getProperty(entitySharedId, propertyId); + const property = await this.getProperty(entitySharedId, propertyId); const entities = this.entitiesDS.getByIds([entitySharedId]); - await entities.forEach(async oneEntity => { - const translation = translationResult.translations.find( - t => t.language === oneEntity.language - ); + await entities.forEach(async entity => { + const translation = translationResult.translations.find(t => t.language === entity.language); if (translation && property) { - if (scope === 'metadata') { - await this.entitiesDS.updateMetadataValues(oneEntity._id, { - [property.name]: [ - { value: `${SaveEntityTranslations.AITranslatedText} ${translation.text}` }, - ], - }); - } - if (scope === 'title') { - await this.entitiesDS.updateMetadataValues( - oneEntity._id, - {}, + await this.entitiesDS.updateEntity( + entity.changePropertyValue( + property, `${SaveEntityTranslations.AITranslatedText} ${translation.text}` - ); - } + ) + ); } }); } @@ -61,24 +51,20 @@ export class SaveEntityTranslations { private async getProperty(entitySharedId: string, propertyId: string) { const entity = await this.entitiesDS.getByIds([entitySharedId]).first(); if (!entity) { - throw new Error('Entity does not exists'); + throw new Error('Entity does not exist'); } const template = await this.templatesDS.getById(entity.template); if (!template) { - throw new Error('Template does not exists'); + throw new Error('Template does not exist'); } - const property = template.properties.find(p => p.id === propertyId); - const commonProperty = template.commonProperties.find(p => p.id === propertyId); + const property = template.getPropertyById(propertyId); - if (!property && !commonProperty) { - throw new Error('Property does not exists'); + if (!property) { + throw new Error('Property does not exist'); } - return { - property: commonProperty || property, - scope: commonProperty ? 'title' : 'metadata', - } as const; + return property; } } diff --git a/app/api/templates.v2/database/TemplateMappers.ts b/app/api/templates.v2/database/TemplateMappers.ts index f123ad041e..9c2ee665d2 100644 --- a/app/api/templates.v2/database/TemplateMappers.ts +++ b/app/api/templates.v2/database/TemplateMappers.ts @@ -9,6 +9,7 @@ import { V1RelationshipProperty } from '../model/V1RelationshipProperty'; import { mapPropertyQuery } from './QueryMapper'; import { TraverseQueryDBO } from './schemas/RelationshipsQueryDBO'; import { RelationshipPropertyDBO, TemplateDBO } from './schemas/TemplateDBO'; +import { CommonProperty } from '../model/CommonProperty'; type PropertyDBO = TemplateDBO['properties'][number]; @@ -20,6 +21,9 @@ function propertyToApp(property: PropertySchema, _templateId: TemplateDBO['_id'] function propertyToApp(property: PropertyDBO, _templateId: TemplateDBO['_id']): Property { const templateId = MongoIdHandler.mapToApp(_templateId); const propertyId = property._id?.toString() || MongoIdHandler.generate(); + if ('isCommonProperty' in property && property.isCommonProperty) { + return new CommonProperty(propertyId, property.type, property.name, property.label, templateId); + } switch (property.type) { case propertyTypes.newRelationship: return new RelationshipProperty( diff --git a/app/api/templates.v2/database/schemas/TemplateDBO.ts b/app/api/templates.v2/database/schemas/TemplateDBO.ts index d7a44c85d3..ffdd8712b0 100644 --- a/app/api/templates.v2/database/schemas/TemplateDBO.ts +++ b/app/api/templates.v2/database/schemas/TemplateDBO.ts @@ -11,6 +11,7 @@ export interface RelationshipPropertyDBO { query: TraverseQueryDBO[]; denormalizedProperty?: string; } + export interface TemplateDBO extends TemplateSchema { _id: ObjectId; properties: (PropertySchema | RelationshipPropertyDBO)[]; diff --git a/app/api/templates.v2/model/CommonProperty.ts b/app/api/templates.v2/model/CommonProperty.ts new file mode 100644 index 0000000000..e331f98326 --- /dev/null +++ b/app/api/templates.v2/model/CommonProperty.ts @@ -0,0 +1,3 @@ +import { Property } from './Property'; + +export class CommonProperty extends Property {} diff --git a/app/api/templates.v2/model/Template.ts b/app/api/templates.v2/model/Template.ts index 90050bc2ff..3229886f09 100644 --- a/app/api/templates.v2/model/Template.ts +++ b/app/api/templates.v2/model/Template.ts @@ -45,6 +45,20 @@ class Template { }); return updateInfo; }; + + getPropertyById(propertyId: string) { + const property = this.properties.find(p => p.id === propertyId); + if (property) { + return property; + } + + const commonProperty = this.commonProperties.find(p => p.id === propertyId); + if (commonProperty) { + return commonProperty; + } + + return null; + } } export { Template }; diff --git a/app/api/utils/handleError.js b/app/api/utils/handleError.js index 875c700c19..044121352a 100644 --- a/app/api/utils/handleError.js +++ b/app/api/utils/handleError.js @@ -69,7 +69,6 @@ const prettifyError = (error, { req = {}, uncaught = false } = {}) => { } if (error instanceof Ajv.ValidationError) { - console.log(util.inspect(error)); result = { code: 422, message: error.message, validations: error.errors, logLevel: 'debug' }; }