977 lines
45 KiB
C#
977 lines
45 KiB
C#
using adas_core.Application.Exceptions;
|
|
using adas_core.Application.Repositories.Interfaces;
|
|
using adas_core.Domain.Enums;
|
|
using adas_core.Domain.Models.AppSettings;
|
|
using adas_core.Domain.Models.DTO.Display;
|
|
using adas_core.Domain.Models.Filter;
|
|
using adas_core.Domain.Models.GroupedObservations;
|
|
using adas_core.Domain.Models.MongoModels;
|
|
using adas_core.Domain.Models.Responses;
|
|
using adas_core.Domain.Utils;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using MongoDB.Bson;
|
|
using MongoDB.Driver;
|
|
using Newtonsoft.Json;
|
|
using Serilog;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace adas_core.Infrastructure.Repositories;
|
|
|
|
/// <summary>
|
|
/// Repository implementation for managing DisplayConfig entities in MongoDB.
|
|
/// Provides CRUD operations and specialized queries for display configurations.
|
|
/// </summary>
|
|
public class DisplayConfigRepository : MongoRepository<DisplayConfig>, IDisplayConfigRepository
|
|
{
|
|
private readonly ApiSettings _apiSettings;
|
|
private readonly ILogger<DisplayConfigRepository> _logger;
|
|
private readonly IUnitRepository _unitRepository;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the DisplayConfigRepository.
|
|
/// </summary>
|
|
/// <param name="database">The MongoDB database instance.</param>
|
|
/// <param name="apiSettings">API settings containing collection names configuration.</param>
|
|
/// <param name="logger">Logger for repository operations.</param>
|
|
/// <param name="unitRepository">Repository for unit-related operations.</param>
|
|
public DisplayConfigRepository(
|
|
IMongoDatabase database,
|
|
ApiSettings apiSettings,
|
|
ILogger<DisplayConfigRepository> logger,
|
|
IUnitRepository unitRepository) : base(database)
|
|
{
|
|
_apiSettings = apiSettings;
|
|
_logger = logger;
|
|
_unitRepository = unitRepository;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the name of the collection for display configurations.
|
|
/// </summary>
|
|
/// <returns>The collection name from API settings.</returns>
|
|
public override string GetCollectionName()
|
|
{
|
|
return _apiSettings.DisplaysConfig;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves all display configurations from the database.
|
|
/// </summary>
|
|
/// <returns>A list of all DisplayConfig entities.</returns>
|
|
public async Task<List<DisplayConfig>> GetAll()
|
|
{
|
|
var result = await Collection.Find(Builders<DisplayConfig>.Filter.Empty).ToListAsync();
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves paginated display configurations with optional filtering.
|
|
/// </summary>
|
|
/// <param name="filter">The pagination and filtering parameters.</param>
|
|
/// <returns>A fluent queryable for DisplayConfigSummary results.</returns>
|
|
/// <exception cref="BadRequestException">Thrown when the text filter exceeds 100 characters.</exception>
|
|
public IFindFluent<DisplayConfig, DisplayConfigSummary> GetAllPaginated(PaginationFilter filter)
|
|
{
|
|
var filterBuilder = Builders<DisplayConfig>.Filter;
|
|
var sort = Builders<DisplayConfig>.Sort.Ascending("hospital");
|
|
var filters = new List<FilterDefinition<DisplayConfig>>();
|
|
|
|
if (filter.FilteredRequest == null)
|
|
return CreateFindFluentMinimal(filters, sort);
|
|
|
|
if (!string.IsNullOrWhiteSpace(filter.FilteredRequest.Text))
|
|
{
|
|
var textFilter = filter.FilteredRequest.Text;
|
|
|
|
if (textFilter.Length > 100)
|
|
throw new BadRequestException("Text filter too long");
|
|
|
|
var textFilterEscaped = Regex.Escape(textFilter);
|
|
|
|
var orFilters = new List<FilterDefinition<DisplayConfig>>
|
|
{
|
|
filterBuilder.Regex(p => p.Hospital, new BsonRegularExpression(textFilterEscaped, "i"))
|
|
};
|
|
|
|
// búsqueda por Id solo si es válido
|
|
if (ObjectId.TryParse(textFilter, out var id))
|
|
{
|
|
orFilters.Add(filterBuilder.Eq("_id", id));
|
|
}
|
|
|
|
filters.Add(filterBuilder.Or(orFilters));
|
|
}
|
|
|
|
if (filter.FilteredRequest.DisplayType != null)
|
|
{
|
|
filters.Add(filterBuilder.Eq(d => d.Type, filter.FilteredRequest.DisplayType));
|
|
}
|
|
|
|
return CreateFindFluentMinimal(filters, sort);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves all display configurations of a specific type.
|
|
/// </summary>
|
|
/// <param name="type">The display type to filter by.</param>
|
|
/// <returns>A list of DisplayConfig entities matching the specified type.</returns>
|
|
public async Task<List<DisplayConfig>> GetByType(DisplayConfigEnums.DisplayType type)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq(p => p.Type, type);
|
|
var result = await Collection.Find(filter).ToListAsync();
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves a display configuration by its ID with related configurations populated.
|
|
/// Performs aggregation to include CardConfig, DetailConfig, ChartConfig, and rotating layout data.
|
|
/// </summary>
|
|
/// <param name="id">The ObjectId of the display configuration to retrieve.</param>
|
|
/// <returns>The DisplayConfig with related data, or null if not found.</returns>
|
|
public async Task<DisplayConfig?> GetById(ObjectId id)
|
|
{
|
|
try
|
|
{
|
|
var aggregate = Collection.Aggregate()
|
|
.Match(Builders<DisplayConfig>.Filter.Eq(p => p.Id, id))
|
|
|
|
// CardConfig
|
|
.Lookup(
|
|
_apiSettings.DisplayCardConfig,
|
|
"cardConfigId",
|
|
"_id",
|
|
"cardConfig"
|
|
)
|
|
.Unwind("cardConfig", new AggregateUnwindOptions<BsonDocument>
|
|
{
|
|
PreserveNullAndEmptyArrays = true
|
|
})
|
|
|
|
// DetailConfig
|
|
.Lookup(
|
|
_apiSettings.DisplayDetailConfig,
|
|
"detailConfigId",
|
|
"_id",
|
|
"detailConfig"
|
|
)
|
|
.Unwind("detailConfig", new AggregateUnwindOptions<BsonDocument>
|
|
{
|
|
PreserveNullAndEmptyArrays = true
|
|
})
|
|
// ChartConfig
|
|
.Lookup(
|
|
_apiSettings.DisplayChartConfig,
|
|
"chartConfigIdList",
|
|
"_id",
|
|
"chartConfig"
|
|
)
|
|
// Lookup para cardRotatingLayout.dataId
|
|
.Lookup(
|
|
_apiSettings.DisplayCardConfig,
|
|
"cardRotatingLayout.dataId",
|
|
"_id",
|
|
"rotatingLayoutData"
|
|
)
|
|
|
|
// Enriquecer cada elemento del array
|
|
.AppendStage<BsonDocument>(new BsonDocument("$addFields",
|
|
new BsonDocument("cardRotatingLayout",
|
|
new BsonDocument("$map",
|
|
new BsonDocument
|
|
{
|
|
{ "input", "$cardRotatingLayout" },
|
|
{ "as", "item" },
|
|
{
|
|
"in",
|
|
new BsonDocument("$mergeObjects", new BsonArray
|
|
{
|
|
"$$item",
|
|
new BsonDocument("data",
|
|
new BsonDocument("$arrayElemAt", new BsonArray
|
|
{
|
|
new BsonDocument("$filter", new BsonDocument
|
|
{
|
|
{ "input", "$rotatingLayoutData" },
|
|
{ "as", "d" },
|
|
{
|
|
"cond",
|
|
new BsonDocument("$eq", new BsonArray
|
|
{
|
|
"$$d._id",
|
|
"$$item.dataId"
|
|
})
|
|
}
|
|
}),
|
|
0
|
|
})
|
|
)
|
|
})
|
|
}
|
|
})
|
|
)
|
|
))
|
|
|
|
// limpiar auxiliar
|
|
.AppendStage<BsonDocument>(new BsonDocument("$unset", "rotatingLayoutData"))
|
|
.As<DisplayConfig>();
|
|
|
|
return await aggregate.FirstOrDefaultAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError("Error on config display repository on GetById Exception: {ex}", ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves the default display configuration for a given type.
|
|
/// Default configurations are identified by having "Default" as the hospital name.
|
|
/// </summary>
|
|
/// <param name="type">The display type to search for.</param>
|
|
/// <returns>The default DisplayConfig for the specified type, or null if not found.</returns>
|
|
public async Task<DisplayConfig?> GetDefault(DisplayConfigEnums.DisplayType type)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.And(
|
|
Builders<DisplayConfig>.Filter.Eq(p => p.Type, type),
|
|
Builders<DisplayConfig>.Filter.Eq(p => p.Hospital, "Default")
|
|
);
|
|
|
|
var result = await Collection.FindAsync(filter);
|
|
return result.FirstOrDefault();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Inserts a new display configuration and returns the inserted document.
|
|
/// </summary>
|
|
/// <param name="config">The DisplayConfig to insert.</param>
|
|
/// The inserted DisplayConfig, or null if insertion fails.
|
|
/// <returns></returns>
|
|
public async Task<DisplayConfig?> InsertOneAsyncAndReturn(DisplayConfig config)
|
|
{
|
|
try
|
|
{
|
|
await Collection.InsertOneAsync(config);
|
|
return config;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the smart display configuration for a specific display.
|
|
/// </summary>
|
|
/// <param name="displayConfigId">The ObjectId of the display configuration to update.</param>
|
|
/// <param name="newDisplayConfig">The new SmartDisplay configuration to apply.</param>
|
|
/// <returns>The updated SmartDisplay configuration, or null if update fails.</returns>
|
|
public async Task<SmartDisplay?> UpdateSmartDisplay(ObjectId displayConfigId, SmartDisplay? newDisplayConfig)
|
|
{
|
|
try
|
|
{
|
|
if (newDisplayConfig == null) return null;
|
|
|
|
var filter = Builders<DisplayConfig>.Filter.Eq("Id", displayConfigId);
|
|
var update = Builders<DisplayConfig>.Update
|
|
.Set(c => ((SmartDisplay)c).Pumps, newDisplayConfig.Pumps)
|
|
.Set(c => ((SmartDisplay)c).HasCameras, newDisplayConfig.HasCameras)
|
|
.Set(c => ((SmartDisplay)c).HasSound, newDisplayConfig.HasSound)
|
|
.Set(c => ((SmartDisplay)c).CamerasAreActive, newDisplayConfig.CamerasAreActive)
|
|
.Set(c => ((SmartDisplay)c).IsRotationEnabled, newDisplayConfig.IsRotationEnabled)
|
|
.Set(c => ((SmartDisplay)c).CanChangeCameraMode, newDisplayConfig.CanChangeCameraMode)
|
|
.Set(c => ((SmartDisplay)c).FieldList, newDisplayConfig.FieldList)
|
|
.Set(c => ((SmartDisplay)c).ChartConfig, newDisplayConfig.ChartConfig)
|
|
.Set(c => ((SmartDisplay)c).GraphLayout, newDisplayConfig.GraphLayout)
|
|
.Set(c => ((SmartDisplay)c).SensorList, newDisplayConfig.SensorList)
|
|
.Set(c => ((SmartDisplay)c).AlarmFieldList, newDisplayConfig.AlarmFieldList)
|
|
.Set(c => c.HomeConfig, newDisplayConfig.HomeConfig)
|
|
.Set(c => c.DetailConfigId, newDisplayConfig.DetailConfigId)
|
|
.Set(c => ((SmartDisplay)c).CameraStreamType, newDisplayConfig.CameraStreamType)
|
|
.Set(c => ((SmartDisplay)c).ColorConfig, newDisplayConfig.ColorConfig)
|
|
.Set(c => ((SmartDisplay)c).RequestGroupedFieldList, newDisplayConfig.RequestGroupedFieldList)
|
|
.Set(c => c.Hospital, newDisplayConfig.Hospital)
|
|
// .Set(c => c.CardConfig, newDisplayConfig.CardConfig)
|
|
.Set(c => c.DisplaySectionIdList, newDisplayConfig.DisplaySectionIdList)
|
|
;
|
|
|
|
var c = await Collection.FindOneAndUpdateAsync(filter, update,
|
|
new FindOneAndUpdateOptions<DisplayConfig, DisplayConfig> { ReturnDocument = ReturnDocument.After });
|
|
return c as SmartDisplay;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.LogError($"Error on config display repository on UpdateSmartDisplay Exception: {e.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the color configuration for a specific display.
|
|
/// </summary>
|
|
/// <param name="objectIdConfigDisplay">The ObjectId of the display configuration to update.</param>
|
|
/// <param name="colorConfig">The new ColorConfig to apply.</param>
|
|
/// <returns>True if the update was successful; otherwise, false.</returns>
|
|
/// <exception cref="Exception">Throws an exception if MongoDB update fails.</exception>
|
|
public async Task<bool> UpdateConfigColor(ObjectId objectIdConfigDisplay, ColorConfig colorConfig)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq("Id", objectIdConfigDisplay);
|
|
var updateDefinition = new List<UpdateDefinition<DisplayConfig>>();
|
|
if (colorConfig.Level != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("colorConfig.level", colorConfig.Level));
|
|
if (colorConfig.Text != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("colorConfig.text", colorConfig.Text));
|
|
if (colorConfig.Arrow != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("colorConfig.arrow", colorConfig.Arrow));
|
|
if (colorConfig.Indicator != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("colorConfig.indicator", colorConfig.Indicator));
|
|
if (colorConfig.Graph != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("colorConfig.graph", colorConfig.Graph));
|
|
if (colorConfig.BoxNumber != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("colorConfig.boxNumber", colorConfig.BoxNumber));
|
|
if (colorConfig.BoxStatusColor != null)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set("colorConfig.boxStatusColor", colorConfig.BoxStatusColor));
|
|
if (colorConfig.Test != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("colorConfig.test", colorConfig.Test));
|
|
if (colorConfig.Therapy != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("colorConfig.therapy", colorConfig.Therapy));
|
|
if (colorConfig.Procedure != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("colorConfig.procedure", colorConfig.Procedure));
|
|
var update = Builders<DisplayConfig>.Update.Combine(updateDefinition);
|
|
try
|
|
{
|
|
var result = await Collection.UpdateOneAsync(filter, update);
|
|
if (result.ModifiedCount > 0) return true; // Retorna el objeto actualizado si la modificación fue exitosa
|
|
|
|
return false; // Retorna nulo si no se encontró el documento o no se modificó
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Error UpdateConfigColor: {name}. Exception: {ex}", objectIdConfigDisplay, ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the header configuration for a specific display.
|
|
/// </summary>
|
|
/// <param name="objectIdConfigDisplay">The ObjectId of the display configuration to update.</param>
|
|
/// <param name="headerConfig">The new HeaderConfig to apply.</param>
|
|
/// <returns>True if the update was successful; otherwise, false.</returns>
|
|
/// <exception cref="Exception">Throws an exception if MongoDB update fails.</exception>
|
|
public async Task<bool> UpdateHeaderConfig(ObjectId objectIdConfigDisplay, HeaderConfig headerConfig)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq("Id", objectIdConfigDisplay);
|
|
var updateDefinition = new List<UpdateDefinition<DisplayConfig>>();
|
|
if (headerConfig.PartnerLogo != null)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set("headerConfig.partnerLogo", headerConfig.PartnerLogo));
|
|
if (headerConfig.CompanyLogo != null)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set("headerConfig.companyLogo", headerConfig.CompanyLogo));
|
|
if (headerConfig.CenterLogo != null)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set("headerConfig.centerLogo", headerConfig.CenterLogo));
|
|
if (headerConfig.MeddisLogo != null)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set("headerConfig.meddisLogo", headerConfig.MeddisLogo));
|
|
if (headerConfig.UnitName != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("headerConfig.unitName", headerConfig.UnitName));
|
|
if (headerConfig.Cameras != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("headerConfig.cameras", headerConfig.Cameras));
|
|
if (headerConfig.Sensors != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("headerConfig.sensors", headerConfig.Sensors));
|
|
if (headerConfig.Fullscreen != null)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set("headerConfig.fullscreen", headerConfig.Fullscreen));
|
|
if (headerConfig.Sounds != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("headerConfig.sounds", headerConfig.Sounds));
|
|
if (headerConfig.Sidebar != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("headerConfig.sidebar", headerConfig.Sidebar));
|
|
if (headerConfig.CurrentDateTime != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set("headerConfig.currentDateTime",
|
|
headerConfig.CurrentDateTime));
|
|
if (headerConfig.SectionTitle != null)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set("headerConfig.sectionTitle", headerConfig.SectionTitle));
|
|
var update = Builders<DisplayConfig>.Update.Combine(updateDefinition);
|
|
try
|
|
{
|
|
var result = await Collection.UpdateOneAsync(filter, update);
|
|
if (result.ModifiedCount > 0) return true;
|
|
|
|
return false;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Error UpdateConfigColor: {name}. Exception: {ex}", objectIdConfigDisplay, ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the home banner configuration for a specific display.
|
|
/// </summary>
|
|
/// <param name="objectIdConfigDisplay">The ObjectId of the display configuration to update.</param>
|
|
/// <param name="bannerItems">The list of banner items to set.</param>
|
|
/// <returns>True if the update was successful; otherwise, false.</returns>
|
|
/// <exception cref="Exception">Throws an exception if MongoDB update fails.</exception>
|
|
public async Task<bool> UpdateSetHomeBanner(ObjectId objectIdConfigDisplay, List<BannerItem> bannerItems)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq("Id", objectIdConfigDisplay);
|
|
var update = Builders<DisplayConfig>.Update
|
|
.Set(c => ((DisplayNurse)c).HomeBanner, bannerItems);
|
|
try
|
|
{
|
|
var result = await Collection.UpdateOneAsync(filter, update);
|
|
if (result.ModifiedCount > 0) return true; // Retorna el objeto actualizado si la modificación fue exitosa
|
|
|
|
return false; // Retorna nulo si no se encontró el documento o no se modificó
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Error UpdateConfigColor: {name}. Exception: {ex}", objectIdConfigDisplay, ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the base configuration for a specific display.
|
|
/// </summary>
|
|
/// <param name="objectIdConfigDisplay">The ObjectId of the display configuration to update.</param>
|
|
/// <param name="baseConfig">The base DisplayConfig with updated values.</param>
|
|
/// <returns>True if the update was successful; otherwise, false.</returns>
|
|
/// <exception cref="Exception">Throws an exception if MongoDB update fails.</exception>
|
|
public async Task<bool> UpdateBaseConfig(ObjectId objectIdConfigDisplay, DisplayConfig baseConfig)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq("Id", objectIdConfigDisplay);
|
|
// TODO NO ESPERA EL CARDCONFIG
|
|
var (updateDefinition, _) = GetBaseUpdateDefinition(baseConfig);
|
|
var update = Builders<DisplayConfig>.Update.Combine(updateDefinition);
|
|
|
|
try
|
|
{
|
|
var result = await Collection.UpdateOneAsync(filter, update);
|
|
if (result.ModifiedCount > 0)
|
|
// await UpdateFieldList(objectIdConfigDisplay, GenerateFieldListFromStrig(fieldList));
|
|
return true; // Retorna el objeto actualizado si la modificación fue exitosa
|
|
|
|
return false; // Retorna nulo si no se encontró el documento o no se modificó
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Error UpdateBaseConfig: {name}. Exception: {ex}", objectIdConfigDisplay, ex);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the nurse display configuration with additional observation fields.
|
|
/// </summary>
|
|
/// <param name="displayConfigId">The ObjectId of the display configuration to update.</param>
|
|
/// <param name="newDisplayConfig">The new DisplayNurseDto configuration to apply.</param>
|
|
/// <param name="nurseObs">List of observation names to mark as "last".</param>
|
|
/// <returns>The updated DisplayNurse configuration, or null if update fails.</returns>
|
|
public async Task<DisplayNurse?> UpdateDisplayNurse(ObjectId displayConfigId, DisplayNurseDto? newDisplayConfig,
|
|
List<string> nurseObs)
|
|
{
|
|
try
|
|
{
|
|
if (newDisplayConfig == null) return null;
|
|
var filter = Builders<DisplayConfig>.Filter.Eq("Id", displayConfigId);
|
|
var updateDefinition = new List<UpdateDefinition<DisplayConfig>>();
|
|
if (newDisplayConfig.CardConfigId != null)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set(c => c.CardConfigId, newDisplayConfig.CardConfigId));
|
|
if (newDisplayConfig.DetailConfigId != null)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set(c => c.DetailConfigId, newDisplayConfig.DetailConfigId));
|
|
if (newDisplayConfig.HomeConfig != null)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set(c => c.HomeConfig, newDisplayConfig.HomeConfig));
|
|
if (newDisplayConfig.Hospital != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set(c => c.Hospital, newDisplayConfig.Hospital));
|
|
if (newDisplayConfig.HeaderConfig != null)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set(c => c.HeaderConfig, newDisplayConfig.HeaderConfig));
|
|
if (newDisplayConfig.HomeBanner != null && newDisplayConfig.HomeBanner.Count != 0)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set(c => ((DisplayNurse)c).HomeBanner,
|
|
newDisplayConfig.HomeBanner));
|
|
if (newDisplayConfig.ColorConfig != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set(c => ((DisplayNurse)c).ColorConfig,
|
|
newDisplayConfig.ColorConfig));
|
|
if (newDisplayConfig.FormConfig != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set(c => ((DisplayNurse)c).FormConfig,
|
|
newDisplayConfig.FormConfig));
|
|
|
|
var originalList = ExtractObservationFields(newDisplayConfig, nurseObs);
|
|
if (originalList.Count > 0)
|
|
updateDefinition.Add(
|
|
Builders<DisplayConfig>.Update.Set(c => ((DisplayNurse)c).FieldList, originalList));
|
|
|
|
var update = Builders<DisplayConfig>.Update.Combine(updateDefinition);
|
|
var c = await Collection.FindOneAndUpdateAsync(filter, update,
|
|
new FindOneAndUpdateOptions<DisplayConfig, DisplayConfig> { ReturnDocument = ReturnDocument.After });
|
|
if (c == null)
|
|
{
|
|
_logger.LogError("Error on config display repository on UpdateDisplayNurse unable to FindOneAndUpdate");
|
|
return null;
|
|
}
|
|
|
|
return c as DisplayNurse;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.LogError("Error on config display repository on UpdateDisplayNurse Exception: {eMessage}",
|
|
e.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the hospital name for a specific display configuration.
|
|
/// </summary>
|
|
/// <param name="objectIdConfigDisplay">The ObjectId of the display configuration to update.</param>
|
|
/// <param name="name">The new hospital name.</param>
|
|
/// <returns>True if the update was successful; otherwise, false.</returns>
|
|
public async Task<bool> UpdateDisplayConfigHospitalName(ObjectId objectIdConfigDisplay, string name)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq(c => c.Id, objectIdConfigDisplay);
|
|
var update = Builders<DisplayConfig>.Update.Set(c => c.Hospital, name);
|
|
|
|
var updatedConfig = await Collection.FindOneAndUpdateAsync(
|
|
filter,
|
|
update,
|
|
new FindOneAndUpdateOptions<DisplayConfig> { ReturnDocument = ReturnDocument.After }
|
|
);
|
|
|
|
if (updatedConfig == null)
|
|
{
|
|
_logger.LogError("Error in UpdateDisplayConfigHospitalName: Unable to find and update DisplayConfig.");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the field list for a specific display configuration.
|
|
/// </summary>
|
|
/// <param name="objectIdConfigDisplay">The ObjectId of the display configuration to update.</param>
|
|
/// <param name="fields">The new list of fields to set.</param>
|
|
/// <returns>True if the update was successful; otherwise, false.</returns>
|
|
public async Task<bool> UpdateFieldList(ObjectId objectIdConfigDisplay, List<Field> fields)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq(x => x.Id, objectIdConfigDisplay);
|
|
var update = Builders<DisplayConfig>.Update.Set(x => x.FieldList, fields);
|
|
|
|
var result = await Collection.UpdateOneAsync(filter, update);
|
|
return result.ModifiedCount > 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the default display configuration for a unit based on its ID and display type.
|
|
/// </summary>
|
|
/// <param name="unitId">The ObjectId of the unit.</param>
|
|
/// <param name="displayType">The type of display configuration to retrieve.</param>
|
|
/// <returns>The default DisplayConfig for the unit, or null if not found.</returns>
|
|
public async Task<DisplayConfig?> GetDefaultByUnitIdAndType(ObjectId unitId,
|
|
DisplayConfigEnums.DisplayType displayType)
|
|
{
|
|
var unit = await _unitRepository.FindById(unitId);
|
|
switch (displayType)
|
|
{
|
|
case DisplayConfigEnums.DisplayType.DisplayNurse:
|
|
if (unit?.Configuration.PlanDisplayConfiguration == null) return null;
|
|
return await GetById(unit.Configuration.PlanDisplayConfiguration.Value) as DisplayNurse;
|
|
case DisplayConfigEnums.DisplayType.SmartDisplay:
|
|
if (unit?.Configuration.SmartDisplayConfiguration == null) return null;
|
|
return await GetById(unit.Configuration.SmartDisplayConfiguration.Value) as SmartDisplay;
|
|
case DisplayConfigEnums.DisplayType.StandarDisplay:
|
|
if (unit?.Configuration.StandarDisplayConfiguration == null) return null;
|
|
return await GetById(unit.Configuration.StandarDisplayConfiguration.Value) as StandarDisplay;
|
|
default: return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes a display configuration by its ID.
|
|
/// </summary>
|
|
/// <param name="objectIdConfigDisplay">The ObjectId of the display configuration to delete.</param>
|
|
/// <returns>The deleted DisplayConfig, or null if not found.</returns>
|
|
public async Task<DisplayConfig?> DeleteDisplayConfig(ObjectId objectIdConfigDisplay)
|
|
{
|
|
return await DeleteAsync(objectIdConfigDisplay);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves all display configurations in compact format (minimal response).
|
|
/// </summary>
|
|
/// <returns>A list of DisplayConfigMinimalResponse containing Id, Hospital, and Type.</returns>
|
|
public Task<List<DisplayConfigMinimalResponse>> GetAllCompact()
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Empty;
|
|
return Collection
|
|
.Find(filter)
|
|
.Project(d => new DisplayConfigMinimalResponse
|
|
{
|
|
Id = d.Id,
|
|
Hospital = d.Hospital ?? "",
|
|
Type = d.Type
|
|
}).ToListAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves all display configuration IDs associated with a specific card configuration.
|
|
/// </summary>
|
|
/// <param name="cardConfigId">The ObjectId of the card configuration.</param>
|
|
/// <returns>A list of ObjectIds for display configurations using the specified card config.</returns>
|
|
public async Task<List<ObjectId>> GetAllByCardConfigId(ObjectId cardConfigId)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq(d => d.CardConfigId, cardConfigId);
|
|
|
|
var result = await Collection.Find(filter)
|
|
.Project(d => d.Id)
|
|
.ToListAsync();
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves all display configuration IDs associated with a card config, including rotating layouts.
|
|
/// </summary>
|
|
/// <param name="cardConfigId">The ObjectId of the card configuration.</param>
|
|
/// <returns>A list of ObjectIds for display configurations using the specified card config in main or rotating layout.</returns>
|
|
public async Task<List<ObjectId>> GetAllByCardConfigIdAndRotating(ObjectId cardConfigId)
|
|
{
|
|
var mainFilter = Builders<DisplayConfig>.Filter.Eq(d => d.CardConfigId, cardConfigId);
|
|
|
|
var rotatingFilter = Builders<DisplayConfig>.Filter.ElemMatch(
|
|
"cardRotatingLayout",
|
|
Builders<BsonDocument>.Filter.Eq("dataId", cardConfigId)
|
|
);
|
|
|
|
var combinedFilter = Builders<DisplayConfig>.Filter.Or(mainFilter, rotatingFilter);
|
|
|
|
var result = await Collection.Find(combinedFilter)
|
|
.Project(d => d.Id)
|
|
.ToListAsync();
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the card configuration ID for a specific display.
|
|
/// </summary>
|
|
/// <param name="displayConfigId">The ObjectId of the display configuration to update.</param>
|
|
/// <param name="resultId">The new card configuration ID to set.</param>
|
|
/// <returns>True if the update was successful; otherwise, false.</returns>
|
|
public async Task<bool> UpdateCardConfigId(ObjectId? displayConfigId, ObjectId? resultId)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq(x => x.Id, displayConfigId);
|
|
var update = Builders<DisplayConfig>.Update.Set(x => x.CardConfigId, resultId);
|
|
|
|
var result = await Collection.UpdateOneAsync(filter, update);
|
|
return result.ModifiedCount > 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a new chart configuration ID to a smart display's chart config list.
|
|
/// </summary>
|
|
/// <param name="displayConfigId">The ObjectId of the display configuration to update.</param>
|
|
/// <param name="newChartIdToAdd">The new chart configuration ID to add.</param>
|
|
/// <returns>True if the update was successful; otherwise, false.</returns>
|
|
public async Task<bool> AddChartId(ObjectId? displayConfigId, ObjectId newChartIdToAdd)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq(x => x.Id, displayConfigId);
|
|
var update = Builders<DisplayConfig>.Update
|
|
.AddToSet(c => ((SmartDisplay)c).ChartConfigIdList, newChartIdToAdd);
|
|
|
|
var result = await Collection.UpdateOneAsync(filter, update);
|
|
return result.ModifiedCount > 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes a deleted chart configuration ID from all display configurations.
|
|
/// </summary>
|
|
/// <param name="deletedId">The ObjectId of the chart configuration that was deleted.</param>
|
|
/// <returns>The MongoDB UpdateResult indicating the number of modified documents.</returns>
|
|
/// <exception cref="Exception">Throws an exception if MongoDB operation fails.</exception>
|
|
public async Task<UpdateResult> UpdateDeletedChartConfig(ObjectId deletedId)
|
|
{
|
|
try
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.AnyEq("chartConfigIdList", deletedId);
|
|
|
|
var update = Builders<DisplayConfig>.Update.Pull("chartConfigIdList", deletedId);
|
|
|
|
return await Collection.UpdateManyAsync(filter, update);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError("Error actualizando referencias de ChartConfig borrado: {ex}", ex.Message);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a chart configuration by ID. This method is not implemented.
|
|
/// </summary>
|
|
/// <param name="objectIdConfigChart">The ObjectId of the chart configuration.</param>
|
|
/// <returns>Always throws NotImplementedException.</returns>
|
|
/// <exception cref="NotImplementedException">This method is not implemented.</exception>
|
|
public Task<ChartConfig> GetChartConfig(ObjectId objectIdConfigChart)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the detail configuration ID for a specific display.
|
|
/// </summary>
|
|
/// <param name="displayConfigId">The ObjectId of the display configuration to update.</param>
|
|
/// <param name="resultId">The new detail configuration ID to set.</param>
|
|
/// <returns>True if the update was successful; otherwise, false.</returns>
|
|
public async Task<bool> UpdateDetailConfigId(ObjectId? displayConfigId, ObjectId? resultId)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq(x => x.Id, displayConfigId);
|
|
var update = Builders<DisplayConfig>.Update.Set(x => x.DetailConfigId, resultId);
|
|
|
|
var result = await Collection.UpdateOneAsync(filter, update);
|
|
return result.ModifiedCount > 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves all display configuration IDs associated with a specific detail configuration.
|
|
/// </summary>
|
|
/// <param name="baseConfigId">The ObjectId of the detail configuration.</param>
|
|
/// <returns>A list of ObjectIds for display configurations using the specified detail config.</returns>
|
|
public async Task<List<ObjectId>> GetAllByCardDetailConfigId(ObjectId baseConfigId)
|
|
{
|
|
var filter = Builders<DisplayConfig>.Filter.Eq(d => d.DetailConfigId, baseConfigId);
|
|
|
|
var result = await Collection.Find(filter)
|
|
.Project(d => d.Id)
|
|
.ToListAsync();
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs initial data load by creating default configurations for each display type if they don't exist.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This method runs on application startup to ensure default configurations exist for:
|
|
/// - DisplayNurse
|
|
/// - SmartDisplay
|
|
/// - StandarDisplay
|
|
/// </remarks>
|
|
public sealed override async Task InsertInitialLoad()
|
|
{
|
|
// 1. Obtener todos los valores y castear al tipo IEnumerable<DisplayType>
|
|
var allTypes = (DisplayConfigEnums.DisplayType[])Enum.GetValues(typeof(DisplayConfigEnums.DisplayType));
|
|
|
|
// 2. Usar LINQ para filtrar y convertir de nuevo a un array (o lista)
|
|
var displayTypesToIterate = allTypes
|
|
.Where(dt => dt != DisplayConfigEnums.DisplayType.Unknown) // Filtra el valor 'Unknown'
|
|
.ToArray();
|
|
foreach (var type in displayTypesToIterate)
|
|
{
|
|
var defaultConfigByType = await GetDefault(type);
|
|
if (defaultConfigByType == null)
|
|
switch (type)
|
|
{
|
|
case DisplayConfigEnums.DisplayType.DisplayNurse:
|
|
var nurse = new DisplayNurse
|
|
{
|
|
Hospital = "Default",
|
|
Type = DisplayConfigEnums.DisplayType.DisplayNurse,
|
|
ColorConfig = new ColorConfig(),
|
|
FormConfig = new FormConfig
|
|
{
|
|
Admission = new FormItemOverview { Nhc = true },
|
|
Demographic = new FormItemOverview { Nhc = true },
|
|
Discharge = new FormItemOverview { Nhc = true },
|
|
IncomeInfo = new FormItemOverview { Nhc = true }
|
|
},
|
|
HomeBanner = []
|
|
};
|
|
await InsertOneAsyncAndReturn(nurse);
|
|
break;
|
|
case DisplayConfigEnums.DisplayType.SmartDisplay:
|
|
var smart = new SmartDisplay
|
|
{
|
|
Hospital = "Default",
|
|
Type = DisplayConfigEnums.DisplayType.SmartDisplay,
|
|
ColorConfig = new ColorConfig()
|
|
};
|
|
await InsertOneAsyncAndReturn(smart);
|
|
break;
|
|
case DisplayConfigEnums.DisplayType.StandarDisplay:
|
|
var standar = new StandarDisplay
|
|
{
|
|
Type = DisplayConfigEnums.DisplayType.StandarDisplay,
|
|
Hospital = "Default"
|
|
};
|
|
await InsertOneAsyncAndReturn(standar);
|
|
break;
|
|
}
|
|
}
|
|
// Si alguno no existe crearlos
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extracts observation field names from a DisplayNurseDto configuration.
|
|
/// </summary>
|
|
/// <param name="newDisplayConfig">The DisplayNurseDto configuration to extract fields from.</param>
|
|
/// <param name="nurseObs">List of observation names to mark as "last" priority.</param>
|
|
/// <returns>A list of Field objects with extracted observation names.</returns>
|
|
private List<Field> ExtractObservationFields(DisplayNurseDto newDisplayConfig, List<string> nurseObs)
|
|
{
|
|
var fieldSet = new HashSet<string>();
|
|
var regex = new Regex(@"""ManualObservationName""\s*:\s*\[\s*((?:""[^""]*""\s*,?\s*)+)\]",
|
|
RegexOptions.Compiled);
|
|
|
|
// --- 1. CardConfig ---
|
|
if (newDisplayConfig.CardConfig?.Rows is { Count: > 0 })
|
|
FillHashSet(JsonConvert.SerializeObject(newDisplayConfig.CardConfig.Rows), regex, fieldSet);
|
|
if (newDisplayConfig.CardConfig?.Rows is { Count: > 0 })
|
|
foreach (var row in newDisplayConfig.CardConfig.Rows)
|
|
ExtractFromCells(row.Cells, fieldSet);
|
|
// --- 2. DetailConfig ---
|
|
if (newDisplayConfig.DetailConfig?.NurseRows is { Count: > 0 })
|
|
FillHashSet(JsonConvert.SerializeObject(newDisplayConfig.DetailConfig?.NurseRows), regex, fieldSet);
|
|
if (newDisplayConfig.DetailConfig?.NurseRows is { Count: > 0 })
|
|
foreach (var row in newDisplayConfig.DetailConfig.NurseRows)
|
|
ExtractFromDetailsCells(row.Cells, fieldSet);
|
|
// --- Result: convert to List<Field> ---
|
|
return fieldSet
|
|
.Distinct()
|
|
.Select(name => new Field { Name = name, Last = nurseObs.Contains(name) ? 1 : 2 })
|
|
.ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fills a hash set with observation names extracted from JSON using regex.
|
|
/// </summary>
|
|
/// <param name="newDisplayConfig">The JSON string to search for observation names.</param>
|
|
/// <param name="regex">The regex pattern to match observation name arrays.</param>
|
|
/// <param name="fieldSet">The hash set to populate with field names.</param>
|
|
private void FillHashSet(string newDisplayConfig, Regex regex, HashSet<string> fieldSet)
|
|
{
|
|
var matches = regex.Matches(newDisplayConfig);
|
|
|
|
foreach (Match match in matches)
|
|
if (match.Groups.Count > 1)
|
|
{
|
|
var arrayContent = match.Groups[1].Value;
|
|
var items = Regex.Matches(arrayContent, @"""([^""]+)""");
|
|
foreach (Match item in items) fieldSet.Add(item.Groups[1].Value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recursively extracts observation names from cell configurations.
|
|
/// </summary>
|
|
/// <param name="cells">The list of cells to extract from.</param>
|
|
/// <param name="fieldSet">The hash set to populate with field names.</param>
|
|
private void ExtractFromCells(List<Cell>? cells, HashSet<string> fieldSet)
|
|
{
|
|
if (cells is null)
|
|
return;
|
|
|
|
foreach (var cell in cells)
|
|
{
|
|
// 1. Extraer ObservationName
|
|
if (cell.ObservationName is { Count: > 0 })
|
|
foreach (var obsName in cell.ObservationName)
|
|
fieldSet.Add(obsName);
|
|
|
|
// 2. Recursión: sub-observaciones
|
|
if (cell.SubObs is { Count: > 0 })
|
|
ExtractFromCells(cell.SubObs, fieldSet);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recursively extracts observation names from detail cell configurations.
|
|
/// </summary>
|
|
/// <param name="cells">The list of detail cells to extract from.</param>
|
|
/// <param name="fieldSet">The hash set to populate with field names.</param>
|
|
private void ExtractFromDetailsCells(List<CellDetails>? cells, HashSet<string> fieldSet)
|
|
{
|
|
if (cells is null)
|
|
return;
|
|
|
|
foreach (var cell in cells)
|
|
{
|
|
// 1. Extraer ObservationName
|
|
if (cell.ObservationName is { Count: > 0 })
|
|
foreach (var obsName in cell.ObservationName)
|
|
fieldSet.Add(obsName);
|
|
|
|
// 2. Recursión: sub-observaciones
|
|
if (cell.Cells is { Count: > 0 })
|
|
ExtractFromDetailsCells(cell.Cells, fieldSet);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a minimal fluent query for paginated display configs with optional filters.
|
|
/// </summary>
|
|
/// <param name="filters">List of filter definitions to apply.</param>
|
|
/// <param name="sort">Sort definition for the query results.</param>
|
|
/// <returns>A fluent queryable for DisplayConfigSummary.</returns>
|
|
private IFindFluent<DisplayConfig, DisplayConfigSummary> CreateFindFluentMinimal(
|
|
List<FilterDefinition<DisplayConfig>> filters,
|
|
SortDefinition<DisplayConfig> sort)
|
|
{
|
|
var combinedFilter = filters.Any()
|
|
? Builders<DisplayConfig>.Filter.And(filters)
|
|
: Builders<DisplayConfig>.Filter.Empty;
|
|
|
|
return Collection
|
|
.Find(combinedFilter)
|
|
.Sort(sort)
|
|
.Project(d => new DisplayConfigSummary
|
|
{
|
|
Id = d.Id,
|
|
Name = d.Hospital ?? "",
|
|
Type = d.Type
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates update definitions from a base DisplayConfig.
|
|
/// </summary>
|
|
/// <param name="baseConfig">The base DisplayConfig with values to update.</param>
|
|
/// <returns>A tuple containing list of update definitions and list of field names.</returns>
|
|
private (List<UpdateDefinition<DisplayConfig>> Updates, List<string> Fields) GetBaseUpdateDefinition(
|
|
DisplayConfig baseConfig)
|
|
{
|
|
var fieldList = new List<string>();
|
|
var updateDefinition = new List<UpdateDefinition<DisplayConfig>>();
|
|
// if (baseConfig.CardConfig != null)
|
|
// {
|
|
// updateDefinition.Add(Builders<DisplayConfig>.Update.Set(c => c.CardConfig, baseConfig.CardConfig));
|
|
// fieldList.AddRange(baseConfig.CardConfig.GetAllObservationNames());
|
|
// }
|
|
if (baseConfig.DetailConfig != null)
|
|
{
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set(c => c.DetailConfig, baseConfig.DetailConfig));
|
|
fieldList.AddRange(baseConfig.DetailConfig.GetAllObservationNames());
|
|
}
|
|
|
|
if (baseConfig.HomeConfig != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set(c => c.HomeConfig, baseConfig.HomeConfig));
|
|
if (baseConfig.Hospital != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set(c => c.Hospital, baseConfig.Hospital));
|
|
if (baseConfig.HeaderConfig != null)
|
|
updateDefinition.Add(Builders<DisplayConfig>.Update.Set(c => c.HeaderConfig, baseConfig.HeaderConfig));
|
|
return (updateDefinition, fieldList);
|
|
}
|
|
}
|
|
|
|
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member |