Untitled
unknown
plain_text
10 months ago
19 kB
22
Indexable
const includeFeatured = async data => {
const { items, featuredData, dataset, isSuperAdmin, dsScope, isQualitrack = false } = data;
const levelsPromise = levelDAO.find({}, 'name');
const attributesPromise = attributeDAO.find({}, 'name values type translations entityLevel unit isUrl library');
const librariesPromise = libraryDAO.find({}, 'name type objectSchema');
const [levelsData, attributesData, librariesData] = await Promise.all([
levelsPromise,
attributesPromise,
librariesPromise
]);
const levelsMap = new Map(levelsData.map(level => [level._id.toString(), level]));
const attributesMap = new Map(attributesData.map(attr => [attr._id.toString(), attr]));
const librariesMap = new Map(librariesData.map(lib => [lib._id.toString(), lib]));
let batchEntityIds = [];
let allRelationItemIds = new Set();
let allUserIds = new Set();
let allLevelIds = new Set();
let allAttributeIds = new Set();
for (const item of items) {
// Collect relation item IDs
for (const relation of item?.relations || []) {
if (relation?.items) {
relation.items.forEach(id => allRelationItemIds.add(id));
}
}
for (const attribute of item?.populatedAttributes || []) {
const level = attributesMap.get(attribute?.attribute?.toString());
if (level?.type === 'Entity') {
const values = attribute?.values || [];
values.forEach(value => {
if (value?.value) {
batchEntityIds.push(value.value);
}
});
}
}
}
for (const currentFeatured of featuredData || []) {
if (
currentFeatured?.type === 'DEFAULT' &&
['createdBy', 'updatedBy'].includes(currentFeatured?.value?.default)
) {
items.forEach(item => {
if (item[currentFeatured?.value?.default]) {
allUserIds.add(item[currentFeatured?.value?.default]);
}
});
}
if (currentFeatured?.type === 'RELATION') {
allLevelIds.add(currentFeatured?.value?.entity);
}
if (currentFeatured?.type === 'ATTRIBUTE') {
allAttributeIds.add(currentFeatured?.value?.attribute);
}
}
const [batchRelationItems, batchEntityData, batchUsers, batchLevels, batchAttributes] = await Promise.all([
itemDAO.find({ _id: { $in: Array.from(allRelationItemIds) } }, 'name attributes'),
itemDAO.find({ _id: { $in: batchEntityIds } }, 'name attributes'),
userDAO.find({ _id: { $in: Array.from(allUserIds) } }, 'firstName familyName active'),
levelDAO.find({ _id: { $in: Array.from(allLevelIds) } }, 'name translations'),
attributeDAO.find(
{ _id: { $in: Array.from(allAttributeIds) } },
'name type unit values entityLevel translations form boundaries isUrl'
)
]);
const relationItemsMap = new Map(batchRelationItems.map(item => [item._id.toString(), item]));
const entityDataCache = new Map(batchEntityData.map(item => [item._id.toString(), item]));
const usersMap = new Map(batchUsers.map(user => [user._id.toString(), user]));
const levelsMapBatch = new Map(batchLevels.map(level => [level._id.toString(), level]));
const attributesMapBatch = new Map(batchAttributes.map(attr => [attr._id.toString(), attr]));
for (const item of items) {
for (const [index, relation] of item?.relations?.entries() || []) {
item.relations[index].level = levelsMap.get(relation?.level?.toString());
const relationItems = relation?.items || [];
relation.items = relationItems
.map(id => relationItemsMap.get(id.toString()))
.filter(Boolean)
.map(i => ({ ...i, isRemoved: !dsScope.includes(i._id.toString()) }));
}
for (const [index, attribute] of item?.populatedAttributes?.entries() || []) {
const level = attributesMap.get(attribute?.attribute?.toString());
if (['Values', 'Entity', 'User'].includes(level?.type)) {
attribute.values = attribute?.values?.filter(value => value?.value || value?.name || value?.firstName);
if (level?.type === 'Values') {
attribute.values = attribute?.values?.map(value => {
const itemValue = level?.values?.find(v => v?.name === value?.name);
return {
name: itemValue?.name,
_id: itemValue?._id,
id: itemValue?._id,
value: itemValue?.name,
color: itemValue?.color
};
});
}
if (level?.type === 'Entity') {
const values = attribute?.values || [];
attribute.values = values.map(value => {
const entityItem = entityDataCache.get(value?.value?.toString());
return {
_id: entityItem?._id,
value: entityItem?.name,
name: entityItem?.name,
id: entityItem?._id,
isRemoved: !dsScope.includes(entityItem?._id?.toString())
};
});
}
if (level?.type === 'User') {
attribute.values = attribute?.values?.map(value => {
return {
name: value?.familyName ? `${value?.firstName} ${value?.familyName}` : value?.firstName,
_id: value?._id,
id: value?._id,
firstName: value?.firstName,
familyName: value?.familyName
};
});
}
}
item.populatedAttributes[index] = {
values: attribute.values,
level: level,
attribute: attribute?.attribute
};
}
}
// Pre-fetch all attributes needed for featured data
const featuredAttributeIds = featuredData
?.filter(f => (f?.type === 'ATTRIBUTE' && f?.isAllowedToEdit) || f?.type === 'ATTRIBUTE_RELATION')
?.map(f => f?.value?.attribute)
?.filter(Boolean);
const featuredAttributes = featuredAttributeIds?.length
? await attributeDAO.find(
{ _id: { $in: featuredAttributeIds } },
'level entityLevel values businessRoles form boundaries'
)
: [];
const featuredAttributesMap = new Map(featuredAttributes.map(attr => [attr._id.toString(), attr]));
// Pre-fetch all entity levels needed
const entityLevelIds = featuredData
?.filter(f => f?.entityReference && f?.entityLevel)
?.map(f => f.entityLevel)
?.filter(Boolean);
const entityLevels = entityLevelIds?.length
? await levelDAO.find({ _id: { $in: entityLevelIds } }, 'name translations')
: [];
const entityLevelsMap = new Map(entityLevels.map(level => [level._id.toString(), level]));
// Process featured data with pre-fetched data
for (let i = 0; i < featuredData?.length; i++) {
const currentFeatured = featuredData[i];
if (
(currentFeatured?.type === 'ATTRIBUTE' && currentFeatured?.isAllowedToEdit) ||
currentFeatured?.type === 'ATTRIBUTE_RELATION'
) {
const attribute = featuredAttributesMap.get(currentFeatured?.value?.attribute?.toString());
if (!attribute) continue;
// add values for entity, user, and values
if (currentFeatured?.attributeType === 'User') {
const query = attribute?.businessRoles?.length
? {
$or: [
{ businessRole: { $in: attribute?.businessRoles } },
{ 'datasets.businessRole': { $in: attribute?.businessRoles } }
]
}
: {};
const users = await userDAO.find(query, 'firstName familyName active');
currentFeatured.users = users?.map(user => ({
_id: user?._id,
active: user?.active,
name: `${user?.firstName} ${user?.familyName}`,
firstName: user?.firstName,
familyName: user?.familyName
}));
} else if (currentFeatured?.attributeType === 'Entity') {
const pipeLine = await buildItemsPipeline(
currentFeatured?.restrictions,
attribute?.entityLevel,
dataset,
isSuperAdmin,
batchEntityIds
);
currentFeatured.items = await itemDAO.aggregate(pipeLine);
currentFeatured.items = currentFeatured.items.map(i => ({
...i,
isRemoved: !dsScope.includes(i._id.toString())
}));
} else if (currentFeatured?.attributeType === 'Values') {
currentFeatured.allValues = attribute?.values.map(value => ({
...value,
id: value?._id,
value: value?.name
}));
} else if (currentFeatured?.attributeType === 'String') {
currentFeatured.form = attribute?.form;
if (currentFeatured?.entityReference && currentFeatured?.entityLevel) {
currentFeatured.entityLevel = entityLevelsMap.get(currentFeatured.entityLevel?.toString());
}
} else if (currentFeatured?.attributeType === 'Number') {
currentFeatured.boundaries = attribute?.boundaries;
if (currentFeatured?.entityReference && currentFeatured?.entityLevel) {
currentFeatured.entityLevel = entityLevelsMap.get(currentFeatured.entityLevel?.toString());
}
}
}
}
for (const [index, item] of items.entries()) {
const relations = item.relations.map(relation => ({
level: relation.level,
values: relation.items.map(i => ({ ...i, isRemoved: !dsScope.includes(i._id.toString()) }))
}));
const attributes = item.populatedAttributes.map(attr => ({ level: attr?.level, values: attr.values }));
const featuredRelations = relations.filter(relation =>
featuredData.map(f => f.value.entity?.toString()).includes(relation?.level?._id?.toString())
);
const featuredAttributes = attributes.filter(attribute =>
featuredData
.map(f => f.value?.attribute?.toString())
.includes(attribute?.level?.attribute?.toString() || attribute?.level?._id?.toString())
);
const featured = [];
const featuredLength = featuredData?.length;
for (let index = 0; index < featuredLength; ++index) {
const currentFeatured = featuredData[index];
if (currentFeatured.type === 'DEFAULT') {
let value;
if (['createdBy', 'updatedBy'].includes(currentFeatured?.value?.default)) {
const user = usersMap.get(item[currentFeatured?.value?.default]?.toString());
value = user ? user?.firstName + ' ' + user?.familyName : '';
} else {
value = currentFeatured?.value?.default ? { value: item[currentFeatured?.value?.default] } : null;
}
const values = value ? [value] : [];
const level = { name: currentFeatured?.value?.default, type: 'Default' };
featured.push({ level, values });
} else if (currentFeatured.type === 'RELATION') {
const relation = featuredRelations?.find(
f2 => f2?.level?._id?.toString() === currentFeatured?.value?.entity.toString()
);
if (relation) featured.push({ level: relation?.level, values: relation?.values });
else {
const level =
levelsMapBatch.get(currentFeatured.value?.entity?.toString()) ||
levelsMap.get(currentFeatured.value?.entity?.toString());
let values = await itemDAO.find({ 'relations.items': item?._id });
values = values.map(i => ({ ...i, isRemoved: !dsScope.includes(i._id.toString()) }));
featured.push({ level, values });
}
} else if (currentFeatured.type === 'ATTRIBUTE') {
let featuredAttribute = featuredAttributes?.find(
f2 => f2?.level?._id?.toString() === currentFeatured?.value?.attribute?.toString()
);
if (!featuredAttribute) {
const featuredAttributeId = currentFeatured?.value?.attribute;
featuredAttribute = {};
featuredAttribute.level =
attributesMapBatch.get(featuredAttributeId?.toString()) ||
attributesMap.get(featuredAttributeId?.toString());
}
if (!currentFeatured?.value?.source?.model) {
const featuredToPush = {
level: featuredAttribute?.level,
values: featuredAttribute?.values,
isAllowedToEdit: currentFeatured?.isAllowedToEdit,
isAllowedToBulkEdit: currentFeatured?.isAllowedToBulkEdit,
addEntries: currentFeatured?.addEntries,
attributeType: currentFeatured?.attributeType,
localScope: currentFeatured?.localScope
};
// get values from item
featured.push(featuredToPush);
} else {
// get values from profiling-v2 answers
let query = {
model: currentFeatured.value?.source?.model,
centralItem: item._id,
['data.' + featuredAttribute?.level?._id]: { $exists: true }
};
let currentFeaturedFrequency = await getFeaturedFrequency(currentFeatured?.value?.source);
if (currentFeaturedFrequency === 'ADHOC') {
query['isAdhoc'] = true;
currentFeaturedFrequency = [];
} else if (currentFeaturedFrequency?.length)
query['frequency'] = { $in: currentFeaturedFrequency.map(f => f._id) };
let values = await answerDAO.find(query, 'data frequency submitted', null, '-createdAt');
if (values?.length) {
if (currentFeaturedFrequency?.length) {
values = currentFeaturedFrequency
.map(
f =>
values.find(a => a.frequency.toString() === f._id.toString())?.data[
featuredAttribute.level._id
]
)
.filter(v => v?.length)
.flat();
} else {
values = values
.map(a => a?.data[featuredAttribute.level._id])
.filter(v => v?.length)
.flat();
}
if (featuredAttribute?.level?.type === 'Values') {
values = values?.map(val =>
featuredAttribute.level.values.find(v => v?._id?.toString() === val?.toString())
);
}
if (featuredAttribute?.level?.type === 'Entity') {
const valuePromises = values.map(value => itemDAO.findById(value, true, 'name attributes'));
const resolvedValues = await Promise.all(valuePromises);
values = resolvedValues.map(result => result?.name);
}
if (['Number', 'Date', 'Boolean', 'Text'].includes(featuredAttribute?.level?.type)) {
values = values?.map(val => ({ value: val }));
}
}
for (let index = 0; index < values.length; index++) {
const attribute = values[index];
if (typeof attribute === 'string') {
values[index] = { value: attribute };
}
}
featured.push({
level: featuredAttribute?.level,
values,
frequencies: currentFeaturedFrequency?.map(f => f?.period)
});
}
} else if (currentFeatured.type === 'ATTRIBUTE_RELATION') {
//Get Selected xRef attribute to show
const attributesCurrentFeatured = item.populatedAttributes.find(
attribute => attribute.level._id?.toString() === currentFeatured.value?.linkedAttribute?.toString()
);
// attributesCurrentFeatured is undefined if currentFeatured is a natural attribute
if (attributesCurrentFeatured) {
let valuesOfEntityAttribute = item.attributes
.find(
attribute =>
attribute.attribute.toString() === attributesCurrentFeatured.level._id.toString()
)
.values?.filter(
value => /^[0-9a-fA-F]{24}$/.test(value?.value) && dsScope.includes(value?.value)
);
const currentAttr = attributesData.find(
attribute => attribute._id.toString() === currentFeatured.value.attribute?.toString()
);
const originAttribute = cloneDeep(currentAttr);
originAttribute.name = `${originAttribute?.name} ( ${attributesCurrentFeatured?.level?.name} )`;
const values = [];
if (valuesOfEntityAttribute?.length) {
const itemsIds = valuesOfEntityAttribute
?.map(value => value?.value)
?.filter(value => value && /^[0-9a-fA-F]{24}$/.test(value));
// Batch fetch all item entity attributes
const itemEntityAttributes = await itemDAO.find({ _id: { $in: itemsIds } }, 'name attributes');
const itemEntityAttributesMap = new Map(
itemEntityAttributes.map(item => [item._id.toString(), item])
);
for (const itemId of itemsIds) {
const itemEntityAttribute = itemEntityAttributesMap.get(itemId?.toString());
if (!itemEntityAttribute) continue;
itemEntityAttribute.isRemoved = !dsScope.includes(itemEntityAttribute?._id?.toString());
//Get values of the xRef attribute to show related to the current item
let xRefItemValues = itemEntityAttribute?.attributes?.find(
attribute =>
attribute?.attribute?.toString() === currentFeatured?.value?.attribute?.toString()
)?.values;
if (originAttribute?.type === 'Values') {
xRefItemValues = originAttribute.values.filter(value =>
xRefItemValues?.map(v => v?.name).includes(value?.name)
);
}
if (isQualitrack) {
let shouldReplace = false;
if (originAttribute?.type === 'Values') {
shouldReplace =
!xRefItemValues ||
xRefItemValues.length === 0 ||
xRefItemValues.every(
item =>
!item?.name &&
(item?.value === null ||
item?.value === undefined ||
!item.hasOwnProperty('value'))
);
} else {
shouldReplace =
!xRefItemValues ||
xRefItemValues.length === 0 ||
xRefItemValues.every(
item =>
item?.value === null ||
item?.value === undefined ||
!item.hasOwnProperty('value')
);
}
if (shouldReplace) {
const existingId =
xRefItemValues && xRefItemValues.length > 0 && xRefItemValues[0]?.id
? xRefItemValues[0].id
: itemId;
xRefItemValues = [{ value: '-', id: existingId }];
}
}
values.push(xRefItemValues);
}
}
featured.push({ level: originAttribute, values: values?.flat() });
} else {
//Get the item of the natural relation
const attributesCurrentFeatured = item.relations.find(
relation => relation.level?._id?.toString() === currentFeatured.value?.entity?.toString()
);
const originAttribute = attributesData.find(
attribute => attribute._id.toString() === currentFeatured.value.attribute?.toString()
);
let naturalAttributeValues = [];
if (attributesCurrentFeatured?.items?.length) {
const itemRelations = attributesCurrentFeatured.items;
if (itemRelations?.length) {
naturalAttributeValues = itemRelations.reduce((acc, curr) => {
const currentItemValues =
curr?.attributes?.find(
attribute =>
attribute.attribute.toString() ===
currentFeatured.value.attribute?.toString()
)?.values || [];
return [...acc, ...currentItemValues];
}, []);
if (originAttribute.type === 'Values') {
naturalAttributeValues = originAttribute.values?.filter(value =>
naturalAttributeValues?.map(v => v?.name).includes(value.name)
);
}
}
}
featured.push({ level: originAttribute, values: naturalAttributeValues });
}
} else if (currentFeatured.type === 'LIBRARY') {
//only for qualitrack
let featuredAttribute = cloneDeep(
featuredAttributes?.find(
attribute => attribute?.level?._id?.toString() === currentFeatured?.value?.attribute?.toString()
)
);
if (!featuredAttribute)
featuredAttribute = { level: { _id: currentFeatured?.value?.attribute, library: {} }, values: [] };
else
featuredAttribute.level.library =
librariesMap.get(featuredAttribute.level?.library?.toString()) || {};
featured.push({ level: featuredAttribute.level, values: featuredAttribute.values });
}
}
delete item.attributes;
delete item.populatedAttributes;
items[index] = { ...item, featured };
}
return items;
};Editor is loading...
Leave a Comment