/*! * SAPUI5 * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ import { ComparisonOperator } from "./ComparisonOperator"; import { ComplexCondition } from "./ComplexCondition"; import { DataSource } from "./DataSource"; import { Filter } from "./Filter"; import { LogicalOperator } from "./LogicalOperator"; import { SearchResultSetItem } from "./SearchResultSetItem"; import { SearchResultSetItemAttribute } from "./SearchResultSetItemAttribute"; import { SearchResultSetItemAttributeBase } from "./SearchResultSetItemAttributeBase"; import { SearchResultSetItemAttributeGroup } from "./SearchResultSetItemAttributeGroup"; import { SearchResultSetItemAttributeGroupMembership } from "./SearchResultSetItemAttributeGroupMembership"; import { SimpleCondition } from "./SimpleCondition"; import { Sina } from "./Sina"; import { Value } from "./types"; import { HierarchyDisplayType } from "./HierarchyDisplayType"; import { AttributeMetadata } from "./AttributeMetadata"; import { Condition } from "./Condition"; import { AttributeType } from "./AttributeType"; import { AttributeGroupMetadata } from "./AttributeGroupMetadata"; import { AttributeMetadataBase } from "./AttributeMetadataBase"; export function combineFilterConditionsByAnd(sina: Sina, conditions: Array): Condition | null { if (!conditions || conditions.length === 0) { return null; } // filter out invalid conditions (undefined/null or complex conditions with no nested conditions) const validConditions = conditions.filter((condition) => { if (!condition) { return false; } if ( condition instanceof ComplexCondition && (!condition.conditions || condition.conditions.length === 0) ) { return false; } return true; }); if (validConditions.length === 0) { return null; } return sina.createComplexCondition({ operator: LogicalOperator.And, conditions: validConditions as Array, }); } export function convertOperator2Wildcards(value: string, operator: ComparisonOperator): string { if (operator === ComparisonOperator.Eq) { return value; } const result = []; const values = value.split(" "); for (let i = 0; i < values.length; i++) { let trimedValue = values[i].trim(); if (trimedValue.length === 0) { continue; } switch (operator) { case ComparisonOperator.Co: trimedValue = "*" + trimedValue + "*"; break; case ComparisonOperator.Bw: case ComparisonOperator.ValueHelp: trimedValue = trimedValue + "*"; break; case ComparisonOperator.Ew: trimedValue = "*" + trimedValue; break; default: break; } result.push(trimedValue); } return result.join(" "); } export function getNavigationHierarchyDataSources( sina: Sina, hierarchyAttrId: string, hierarchyName: string, dataSource: DataSource ): Array { const navigationDataSources = []; if (hierarchyAttrId?.length && sina) { const boDataSources: Array = sina.getBusinessObjectDataSources(); boDataSources.forEach((boDataSource) => { if (boDataSource.getHierarchyDataSource() === dataSource) { navigationDataSources.push(boDataSource); } else if (boDataSource.hierarchyName === hierarchyAttrId) { // avoid self reference return; } else { boDataSource.attributesMetadata.forEach((attribute) => { if ( ((attribute as AttributeMetadata).hierarchyName === hierarchyName && attribute.id === hierarchyAttrId && (attribute as AttributeMetadata).hierarchyDisplayType === HierarchyDisplayType.HierarchyResultView) || (attribute as AttributeMetadata).hierarchyDisplayType === HierarchyDisplayType.StaticHierarchyFacet ) { navigationDataSources.push(boDataSource); } }); } }); } return navigationDataSources; } // Prepare title as value label in filter condition export function assembleTitle(result: SearchResultSetItem): string { const titleValueArray = []; result.titleAttributes.forEach((titleAttr: SearchResultSetItemAttributeBase) => { if (titleAttr instanceof SearchResultSetItemAttributeGroup && Array.isArray(titleAttr.attributes)) { titleAttr.attributes.forEach((subAttributeGroup: SearchResultSetItemAttributeGroupMembership) => { if ( subAttributeGroup.attribute && subAttributeGroup.attribute instanceof SearchResultSetItemAttribute && subAttributeGroup.attribute.value?.startsWith("sap-icon://") !== true ) { titleValueArray.push(subAttributeGroup.attribute.valueFormatted); } }); } else if (titleAttr instanceof SearchResultSetItemAttribute) { if (titleAttr.value.startsWith("sap-icon://") !== true) { titleValueArray.push(titleAttr.valueFormatted); } } }); return titleValueArray.filter((item) => typeof item === "string" && item.trim() !== "").join(" "); } // Assemble down navigation to related descendants as bottom navigation toolbar link export function assembleHierarchyDecendantsNavigations( result: SearchResultSetItem, attrName: string, attrValue: Value, attrValueLabel: string, navigationDataSources: Array ): void { const datasetCondition = new SimpleCondition({ attribute: attrName, operator: ComparisonOperator.DescendantOf, value: attrValue, valueLabel: attrValueLabel, }); const wrapComplexConditionDS = new ComplexCondition({ operator: LogicalOperator.And, conditions: [datasetCondition], }); const rootConditionDS = new ComplexCondition({ operator: LogicalOperator.And, conditions: [wrapComplexConditionDS], }); navigationDataSources.forEach((navigationDataSource) => { const filterDS = new Filter({ dataSource: navigationDataSource, searchTerm: "", //navigation mode, ignore content in search input box rootCondition: rootConditionDS, sina: result.sina, }); result.navigationTargets.push( result.sina.createSearchNavigationTarget(filterDS, navigationDataSource.labelPlural) ); }); } export function stringifyValue(value: unknown): string { if (typeof value === "string") { return value; } if (typeof value === "number" || typeof value === "boolean") { return String(value); } if (value === null || value === undefined) { return ""; } if (typeof value === "object") { if (typeof value.toString === "function") { return value.toString(); } else { return JSON.stringify(value); } } return "" + value; } export function extractDisplayedSingleAttributeIds(attribute: AttributeMetadataBase): string[] { if (attribute?.type !== AttributeType.Group) { // single attribute return attribute.id ? [attribute.id] : []; } // group attribute const groupAttribute = attribute as AttributeGroupMetadata; const results = new Set(); // 1. get displayed single or group child attribute ids if (!groupAttribute?.displayAttributes || groupAttribute.displayAttributes.length === 0) { return []; } const displayedIdsOrNames = new Set(groupAttribute.displayAttributes); // 2. get displayed single or group child attribute metadatas const displayedAttributes = groupAttribute.attributes.filter( // sina groupAttribute.displayAttributes may contain either attribute id or nameInGroup, so we need to check both (child) => (typeof child.attribute.id === "string" && displayedIdsOrNames.has(child.attribute.id)) || (typeof child.nameInGroup === "string" && displayedIdsOrNames.has(child.nameInGroup)) ); if (displayedAttributes.length === 0) { return []; } // 3. get displayed ONLY single child attribute ids displayedAttributes.forEach((child) => { extractDisplayedSingleAttributeIds(child.attribute).forEach((id) => results.add(id)); }); return Array.from(results); }