UNPKG

@mikezimm/fps-core-v7

Version:

Library of reusable core interfaces, types and constants migrated from fps-library-v2

610 lines 32.7 kB
import { ItemHasUniquePerms } from "../../AnyContent/IsA/IFPSItemIsA"; import { addItemIsA } from "./addItemIsA"; // import { addOtherIsAMeta } from "./addOtherIsAMeta"; import { EmptyFPSItemSearch } from "../../AnyContent/IFPSItemSearch"; import { DefaultOverflowTab } from '../../../atoms/easy-pages/interfaces/epTypes'; import { retrieveFPSUser } from '../../../../banner/FPSWebPartClass/functions/showTricks'; // import { addSearchFileData } from "./addSearchFile"; export function createMinFPSItemTime(item, field) { var _a; // 2024-07-15: I think this being outside of the function was causing the error: // Reason being, time stamp Today was generated on first load, likely before analytics was saved. // In that case the Analytics time could be after 'Today' causing a negative few miliseconds // https://github.com/mikezimm/drilldown7/issues/431 const Today = new Date(); const TodayMS = Today.getTime(); const itemFieldValue = (_a = item[field]) !== null && _a !== void 0 ? _a : ''; // 2024-12-04: Added this because PivotTiles was returning Zulu time. const itemFieldDate = new Date(itemFieldValue); // 2024/09-07: Added ] as '' to pass typescript errors for now const ms = Date.parse(itemFieldValue); const valid = Number.isNaN(ms) ? false : true; const Stamp = { valid: valid, ms: valid === true ? ms : 0, now: Today, // 2024/09-07: Added ] as '' to pass typescript errors for now theTime: item[field], local: valid === true && itemFieldDate ? itemFieldDate.toLocaleString() : '', dayYYYYMMDD: valid === true && itemFieldValue ? `${itemFieldValue.substring(0, 10)}` : `Z`, age: valid === true ? (TodayMS - ms) / (1000 * 60 * 60 * 24) : -79, }; // https://github.com/mikezimm/drilldown7/issues/431 if (['Created', 'Modified', 'FirstPublishedDate'].indexOf(field) > -1 && Stamp.age && Stamp.age < 0) Stamp.age = .00001; return Stamp; } export function createMinFPSItemUser(item, field, FPSUser) { const fieldValue = item[field]; const Stamp = { valid: false, Id: -79, ID: -79, Title: '', Name: '', Email: '', Mine: null, }; if (fieldValue) { if (fieldValue.Title) { Stamp.Title = fieldValue.Title, Stamp.valid = true; } else if (fieldValue.title) { Stamp.Title = fieldValue.title, Stamp.valid = true; } if (fieldValue.Email) { Stamp.Email = fieldValue.Email, Stamp.valid = true; } // Added this after realizing item.Author property is actually EMail cased // https://github.com/fps-solutions/FPS-Photo-Form/issues/56 else if (fieldValue.EMail) { Stamp.Email = fieldValue.EMail, Stamp.valid = true; } else if (fieldValue.email) { Stamp.Email = fieldValue.email, Stamp.valid = true; } if (fieldValue.Name) { Stamp.Name = fieldValue.Name, Stamp.valid = true; } else if (fieldValue.name) { Stamp.Name = fieldValue.name, Stamp.valid = true; } else if (fieldValue.LoginName) { Stamp.Name = fieldValue.LoginName, Stamp.valid = true; } const { name, email } = FPSUser; if (Stamp.Name && name && Stamp.Name.toLocaleLowerCase() === name.toLocaleLowerCase()) { Stamp.Mine = true; } else if (Stamp.Email && email && Stamp.Email.toLocaleLowerCase() === email.toLocaleLowerCase()) { Stamp.Mine = true; } else if ((Stamp.Name && name) || (Stamp.Email && email)) { // Explicitly set to false because there is a property but clearly do not match // If there is nothing to directly compare to, leave as null which could be used downstream Stamp.Mine = false; } if (fieldValue.Id) { Stamp.Id = fieldValue.Id, Stamp.valid = true; } else if (fieldValue.id) { Stamp.Id = fieldValue.id, Stamp.valid = true; } else if (fieldValue.ID) { Stamp.Id = fieldValue.ID, Stamp.valid = true; } if (Stamp.Id > -1) Stamp.ID = Stamp.Id; // [ `${field}/Title`, `${field}/Name`, ].map( prop => { // const splits: string[] = prop.split('/'); // if ( item[ splits[0] ] && item[ splits[0] ][ splits[1] ] ) item[ prop ] = item[ splits[0] ][ splits[1] ]; // }); } return Stamp; } /** * 2023-07-06 - REFACTOR - * @param item * @returns */ export function addDateTimeInfoSearch(item, FPSUser) { if (!item.FPSItem) item.FPSItem = { IsA: { allIsAKeys: [], allIsAKeysStr: '' }, // 2024-09-07: Added Search and File to pass the updated IFPSItem requirements Search: EmptyFPSItemSearch, File: undefined, }; if (!item.FPSItem.Search) item.FPSItem.Search = EmptyFPSItemSearch; const Stamp = {}; //https://stackoverflow.com/a/15191245 /** * If item is based on search results (like subs, lists, libraries, hubs ) it will have LastItemUserModifiedDate * Then use the LastItemUserModifiedDate and do not try to add a person's name */ if (!item.Modified) { if (item.LastItemModifiedDate) { item.Modified = item.LastItemModifiedDate; } else if (item.LastItemUserModifiedDate) { item.Modified = item.LastItemUserModifiedDate; } } if (item.Created) { Stamp.created = createMinFPSItemTime(item, 'Created'); item.createdAge = Stamp.created.age; // Added for AgeSlider search using getFilteredV1 } if (item.Modified) { Stamp.modified = createMinFPSItemTime(item, 'Modified'); item.modifiedAge = Stamp.modified.age; // Added for AgeSlider search using getFilteredV1 } if (item.FirstPublishedDate) { Stamp.published = createMinFPSItemTime(item, 'FirstPublishedDate'); item.publishedAge = Stamp.published.age; // Added for AgeSlider search using getFilteredV1 } // [ 'Author/Title', 'Author/Name', 'Editor/Title', 'Editor/Name', ].map( prop => { // const splits: string[] = prop.split('/'); // if ( item[ splits[0] ] && item[ splits[0] ][ splits[1] ] ) item[ prop ] = item[ splits[0] ][ splits[1] ]; // }); Stamp.author = createMinFPSItemUser(item, 'Author', FPSUser); Stamp.editor = createMinFPSItemUser(item, 'Editor', FPSUser); /** * If item is based on search results (like subs, lists, libraries, hubs ) it will have LastItemUserModifiedDate * Then use the LastItemUserModifiedDate and do not try to add a person's name */ if (Stamp.author && Stamp.created) Stamp.createdNote = `${Stamp.author.Title} - ${item.Created ? item.Created.substring(0, 10) : ''}`; if (Stamp.editor && Stamp.modified) Stamp.modifiedNote = `${Stamp.editor.Title} - ${item.Modified ? item.Modified.substring(0, 10) : ''}`; item.FPSItem.Stamp = Stamp; return item; } /** * 2024-11-30: Added this due to PivotTiles not seeing folder name but 'UNK' in the Title/Link * * @param item * @returns */ function standardizeFileProps(item) { // Bring File props to top for max usability if (item.File && typeof item.File === 'object') { if (!item.FileLeafRef && item.File.FileLeafRef) item.FileLeafRef = item.File.FileLeafRef; if (!item.FileRef && item.File.FileRef) item.FileRef = item.File.FileRef; if (!item.Title && item.File.FileLeafRef) item.Title = item.File.FileLeafRef; if (!item.File.ServerRelativeUrl && item.FileRef) item.File.ServerRelativeUrl = item.FileRef; if (!item.ServerRelativeUrl && item.File.ServerRelativeUrl) item.ServerRelativeUrl = item.File.ServerRelativeUrl; if (!item.ServerRelativeUrl) { if (item.FileRef) { item[`File/ServerRelativeUrl`] = item.FileRef; item.File.ServerRelativeUrl = item.FileRef; item.ServerRelativeUrl = item.FileRef; } } if (!item.FileLeafRef && item[`File/ServerRelativeUrl`]) item.FileLeafRef = item[`File/ServerRelativeUrl`].substring(item[`File/ServerRelativeUrl`].lastIndexOf('/') + 1); if (!item.File.Name) item.File.Name = item.FileLeafRef; } else if (!item.File && (item.FileRef || item.FileLeafRef)) { item.File = {}; if (item.FileRef) { item.File.FileRef = item.FileRef; } if (item.FileLeafRef) { item.File.FileLeafRef = item.FileLeafRef; item.File.Name = item.FileLeafRef; } if (!item.ServerRelativeUrl && item.FileRef) item.ServerRelativeUrl = item.FileRef; if (item.ServerRelativeUrl) item.File.ServerRelativeUrl = item.ServerRelativeUrl; } if (item.FileSystemObjectType === 1 || item.File) { if (item.FileLeafRef && !item[`File/Name`]) item[`File/Name`] = item.FileLeafRef; if (item.FileRef && !item[`File/ServerRelativeUrl`]) item[`File/ServerRelativeUrl`] = item.FileRef; if (!item.Title && item[`File/Name`]) item.Title = item[`File/Name`]; } if (item.FileSystemObjectType === 1 && !item[`File_x0020_Type`]) item[`File_x0020_Type`] = 'folder'; return item; } /** * AS OF 2025-07-13: Does NOT search HTML strings as readable text but straight html. * Added Drilldown's getVisibleTextFromHtml file but have not added full functionality back via ISourceProps to impliment it yet. * @param items * @param sourceProps * @param search * @returns */ export function addSearchMeta1(items, sourceProps, search) { //searchNest will be an array of prop key arrays... so [ 'Author/Title' ] => [ ["Author","Title"] ] const searchNest = []; const FPSUser = retrieveFPSUser(); // https://github.com/mikezimm/pivottiles7/issues/395 if (sourceProps && sourceProps.searchProps) sourceProps.searchProps.map(prop => { if (prop.indexOf('.') > -1 || prop.indexOf('/') > -1) { searchNest.push(prop.trim().replace(' ', '').split(/[./]/gm)); } else { searchNest.push([prop.trim().replace(' ', '')]); } }); items.map((item) => { let searchTitle = ''; let searchDesc = ''; const searchHref = ''; if (!item.FPSItem) item.FPSItem = { IsA: { allIsAKeys: [], allIsAKeysStr: '' }, File: { valid: false, fileDisplayName: '' }, Search: JSON.parse(JSON.stringify(EmptyFPSItemSearch)), }; item = standardizeFileProps(item); item = addDateTimeInfoSearch(item, FPSUser); // This was only from ALVFinMan... should be removed if (item.ReportingSections) { item.Reporting = item.ReportingSections; } const meta = []; //This is for display purposes so user can see what property the search criteria is found in const searchText = searchNest.map((propArray, idx) => { if (propArray.length === 1) { item[sourceProps.searchProps[idx]] = item[propArray[0]]; //Add flattened value - item["Author/Title"]= item.Author.Title if (Array.isArray(item[propArray[0]])) { return `${sourceProps.searchProps[idx]}=${item[propArray[0]].join(';')}`; } else { return `${sourceProps.searchProps[idx]}=${item[propArray[0]]}`; } } else if (propArray.length === 2) { //Add flatened value for people/expanded columns let hasError = false; try { if (Array.isArray(item[propArray[0]])) { // eslint-disable-next-line @typescript-eslint/no-explicit-any item[sourceProps.searchProps[idx]] = item[propArray[0]].map((itemX) => { return itemX[propArray[1]]; }); //Add flattened value - item["Author/Title"]= [ item.Author[0].Title, item.Author[1].Title] } else { if (item[propArray[0]]) { item[sourceProps.searchProps[idx]] = item[propArray[0]][propArray[1]]; //Add flattened value - item["Author/Title"]= item.Author.Title } else { // Need to add this in if the value was not found. Like the column had no value and was undefined or null... aka Acronyms Standards lookup item[sourceProps.searchProps[idx]] = 'UNK'; hasError = true; } } /** * This section was specific to ALVFM columns */ //Manually copy ReportingSections/Title over to Reporting/Title // if ( sourceProps.searchProps[ idx ] === 'ReportingSections/Title' ) { item[ 'Reporting/Title'] = item[ sourceProps.searchProps[ idx ] ]; } } catch (e) { // alert('Error doing search props'); const lastPart = item[propArray[0]] ? item[propArray[0]][propArray[1]] : 'UNK'; item[sourceProps.searchProps[idx]] = lastPart; console.log('Search Error: ~ `77', item, sourceProps.searchProps, idx, item[propArray[0]], lastPart); hasError = true; } if (hasError === true) { return `${sourceProps.searchProps[idx]}=UNK`; } else { //This first loop never gets triggered with multi-select lookups because the array is really item [ propArray[0] ] if (Array.isArray(item[propArray[0]][propArray[1]])) { let result = `${sourceProps.searchProps[idx]}=${item[propArray[0]][propArray[1]].join(';')}`; // This is specific to ALVFM if (sourceProps.searchProps[idx] === 'ReportingSections/Title') { result += ` || Reporting/Title=${item[propArray[0]][propArray[1]].join(';')}`; } return result; } else if (Array.isArray(item[propArray[0]])) { //As in Controller2/Title /** * NEED TO ADD LOOP HERE TO CHECK FOR MULTI-SELECT Lookups like ReportingSections/Titles. * They don't get caught in the above one because the logic does not work that way */ if (item[sourceProps.searchProps[idx]]) { const result = `${sourceProps.searchProps[idx]}=${item[sourceProps.searchProps[idx]].join(';')}`; return result; } } else { let result = `${sourceProps.searchProps[idx]}=${item[propArray[0]][propArray[1]]}`; // This is specific to ALVFM if (sourceProps.searchProps[idx] === 'ReportingSections/Title') { result += ` || Reporting/Title=${item[propArray[0]][propArray[1]]}`; } return result; } } } }).join(' || '); //Get rid of any empty strings searchText.split(' || ').map(text => { if (text) { meta.push(text); } }); //searchTextLC is used for actual search function - removes Column Titles from searchable text const searchTextLC = sourceProps && sourceProps.searchProps ? sourceProps.searchProps.map(prop => { if (Array.isArray(item[prop])) { return `${item[prop].join(';')}`; } else { return `${item[prop]}`; } }).join(' || ') : ''; item.FPSItem.Search.searchText = searchText; item.FPSItem.Search.searchTextLC = searchTextLC.toLocaleLowerCase(); item.FPSItem.Search.meta = [...meta,]; item = addStandardSearchArrays(item, sourceProps, search); // //update item's left search string arrays // if ( search && search.left && search.left.Search ) { // search.left.Search.map( ( keyWord: string, idx: number ) => { // const keyWordLC = search.left.SearchLC[ idx ]; // if ( item.FPSItem.SearchLC.indexOf( keyWordLC ) > - 1 ) { // item.FPSItem.Search.leftSearch.push( keyWord ); // item.FPSItem.Search.leftSearchLC.push( keyWordLC ); // } // }); // } // //update item's top search string arrays // if ( search && search.top && search.top.Search ) { // search.top.Search.map( ( keyWord: string, idx: number ) => { // const keyWordLC = search.top.SearchLC[ idx ]; // if ( item.FPSItem.Search.searchTextLC.indexOf( keyWordLC ) > - 1 ) { // item.FPSItem.Search.topSearch.push( keyWord ); // item.FPSItem.Search.topSearchLC.push( keyWordLC ); // } // }); // } //update item's top search string arrays // if ( search && search.type && search.type.Search ) { // search.type.Search.map( ( keyWord: string, idx: number ) => { // const keyWordLC = search.type.SearchLC[ idx ]; // if ( item.FPSItem.Search.searchTextLC.indexOf( keyWordLC ) > - 1 ) { // item.typeSearch.push( keyWord ); // item.typeSearchLC.push( keyWordLC ); // } // }); // } if (item.HasUniqueRoleAssignments === true) { item = addItemIsA(item, ItemHasUniquePerms); } // item = addOtherIsAMeta( item ); item.FPSItem.Search.searchTitle = `${searchTitle}`; item.FPSItem.Search.searchDesc = `${searchDesc}`; item.FPSItem.Search.searchHref = `${searchHref}`; // item.FPSItem.Search.meta = [...meta, ...item.FPSItem.Search.leftSearch, ...item.FPSItem.Search.topSearch ]; // Check if it's a file: // if ( item.File || item.FileSizeDisplay || item.FileLeafRef || item.FileRef || item.File_x0020_Type || item.FirstPublishedDate ) { // // Item is a file // item = addItemIsA( item, ItemIsAFile ); // } // item.FPSItem.File.fileDisplayName = ''; //Basically the file name but without extension // //https://github.com/mikezimm/Compliance/issues/121 // if ( item.FileSizeDisplay ) item.FPSItem.File.fileSizeNumber = parseInt( item.FileSizeDisplay ); // let searchType = item.FPSItem.Search.type; // const extIdx = item.FileRef ? item.FileRef.lastIndexOf('.') : -1; // if ( item['File_x0020_Type'] ) { // eslint-disable-line dot-notation // searchType = item['File_x0020_Type'] ; // eslint-disable-line dot-notation // searchTitle = item['FileLeafRef'] ? item['FileLeafRef'] : 'No Filename to show'; // eslint-disable-line dot-notation // item.FPSItem.File.fileDisplayName = item['FileLeafRef'].replace(`.${searchType}`,''); // eslint-disable-line dot-notation // searchDesc = ''; // item = addItemIsA( item, ItemIsAFile ); // // https://github.com/mikezimm/fps-library-v2/issues/51 - DO NOT do this loop if it's a folder with a . in it :) // } else if ( item.FileSystemObjectType !== 1 && extIdx > -1 ) { // searchType = item.FileRef.substring( extIdx + 1 ); // if ( searchType === 'aspx' ) { // searchType = 'page'; // searchTitle = item.Title; // item.FPSItem.File.fileDisplayName = item['FileLeafRef'].replace(`.aspx`,''); // eslint-disable-line dot-notation // searchDesc = item.Description; // /** // * OData__OriginalSourceUrl is a hidden column in SharePoint Online that is used to store the original URL of a document that was uploaded to SharePoint. // * This column is used by the SharePoint Online search engine to crawl and index documents. // * It is not recommended to modify or delete this column as it can cause issues with search results and other SharePoint Online features¹. // I hope this helps! Let me know if you have any other questions. // Source: Conversation with Bing, 7/6/2023 // (1) Use OData query operations in SharePoint REST requests. https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/use-odata-query-operations-in-sharepoint-rest-requests. // (2) OData Source for SharePoint Online - social.msdn.microsoft.com. https://social.msdn.microsoft.com/Forums/en-US/58807617-90aa-48e3-a06f-9582b683d8de/odata-source-for-sharepoint-online?forum=sharepointadmin. // (3) Working with SharePoint Online through OData v4 Endpoint - KingswaySoft. http://www.kingswaysoft.com/blog/2021/06/29/Working-with-SharePoint-Online-through-OData-v4-Endpoint. // (4) Using OData sources with Business Connectivity Services in SharePoint .... https://learn.microsoft.com/en-us/sharepoint/dev/general-development/using-odata-sources-with-business-connectivity-services-in-sharepoint. // */ // if ( item.OData__OriginalSourceUrl !== null ) { // item = addItemIsA( item, ItemIsANewsLink ); // } else if ( item.PromotedState === 1 || item.PromotedState === 2 ) { // item = addItemIsA( item, ItemIsANewsPost ); // } else { // item = addItemIsA( item, ItemIsAPage ); // } // } // // Handle folder objects // } else if ( !searchType && item.FileSystemObjectType === 1 ) { // const thisContentType = item[`ContentType/Name`] ? item[`ContentType/Name`] : 'Unknown'; // if ( thisContentType.indexOf( `Document Set` ) > -1 ) { // searchType = 'docset'; // item[`File_x0020_Type`] = 'docset'; // searchTitle = item.FileLeafRef ? item.FileLeafRef : ''; // searchDesc = item.Description ? item.Description : ''; // item = addItemIsA( item, ItemIsADocSet ); // } else { // searchType = 'folder'; // item[`File_x0020_Type`] = 'folder'; // searchTitle = item.FileLeafRef ? item.FileLeafRef : ''; //webRelativeLink // const webLink = `${sourceProps.webUrl}${sourceProps.webRelativeLink ? sourceProps.webRelativeLink : ''}`; // const fileRelativeLink = item.FileRef.indexOf( webLink ) === 0 ? // item.FileRef.substring( webLink.length ) : item.FileRef; // searchDesc = item.Description ? item.Description : fileRelativeLink.substring( 0, fileRelativeLink.lastIndexOf( item.FileLeafRef ) -1 ); // item = addItemIsA( item, ItemIsFolderContent ); // } // } else { // searchType = sourceProps.defType; // searchTitle = item.Title; // searchDesc = 'Other Type Search Desc'; // } // // If folder, add folderTree array // if ( item.FileSystemObjectType === 0 || item.FileSystemObjectType === 1 ) { // const libUrl: string = `${sourceProps.webUrl}${sourceProps.webRelativeLink ? sourceProps.webRelativeLink : ''}` // const folderString: string = item.FileRef && libUrl ? item.FileRef.replace( libUrl, '' ).replace(`/${item.FileLeafRef}`,'') : ''; // const folderTree: string[] = folderString ? folderString.indexOf('/') === 0 ? folderString.substring(1).split('/') : folderString.split('/') : []; // item.FPSItem.File.folderString = folderString; // item.FPSItem.File.folderTree = folderTree; // } // item.FPSItem.Search.searchTitle = `${searchTitle}`; // item.FPSItem.Search.searchDesc = `${searchDesc}`; // item.FPSItem.Search.searchHref = `${searchHref}`; /** * This section was specific to ALVFM columns */ // if ( sourceProps.key === 'manual' || sourceProps.key === 'help' || sourceProps.key === 'news' ) { // item.FPSItem.Search.searchTitle = item.Title; // } item.FPSItem.Search.format = sourceProps.key; // if ( item.Tab && item.LinkColumn ) { // console.log('DataFetch.ts ~ 493'); // } /** * This section was specific to ALVFM columns */ // if ( !searchDesc && item.SearchWords ) { searchDesc = item.SearchWords; } // if ( !searchHref && item.LinkColumn ) { // searchHref = item.LinkColumn.Url; // if ( !searchDesc && item.SearchWords ) { searchDesc = item.LinkColumn.Description; } // } // //Just add this prop to everything for ease of use. // if ( item.ReportingForms ) { // if ( Array.isArray( item.ReportingForms) === true ) { // item.ReportingFormsStr = item.ReportingForms.map( ( form: any ) => { return form.Title ; } ).join('; '); // } else { item.ReportingFormsStr = item.ReportingForms; } // } else { // item.ReportingForms = []; // item.ReportingFormsStr = ''; // } // if ( searchType === 'account' ) { // searchTitle = ''; // searchDesc = [ searchType, item.ReportingForms.Title, item.SubCategory, item.Name1, item.Description ] .join ('<>'); // if ( item.Description && ( item.Description.indexOf('&quot;') > -1 || item.Description.indexOf('</') > -1 ) ) { item.descIsHTML = true ; } // searchHref = ''; // } /** * This could be added as secondary function after adding custom search code to catch any loose ends. */ //This if was added for the Standards Wiki Library where the title column is actually Title0 // if ( !searchTitle && item.Title0 ) { searchTitle = item.Title0 ; } // if ( !searchTitle && item.FileLeafRef ) { searchTitle = item.FileLeafRef.substr(0, item.FileLeafRef.lastIndexOf('.') ) ; } //Added for Std #139 which does not have a Title value. // if ( !searchDesc ) { searchDesc = '' ; } // if ( !searchHref ) { // if ( item.ServerRedirectedEmbedUri ) { searchHref = item.ServerRedirectedEmbedUri ; } // else if ( item.FileRef ) { searchHref = item.FileRef ; } // else if ( item[ 'File/ServerRelativeUrl' ] ) { searchHref = item[ 'File/ServerRelativeUrl' ] ; } // } // let searchTypeIdx = SearchTypes.keys.indexOf( searchType ) ; // if ( searchTypeIdx === -1 ) { // console.log('Invalid searchTypeIdx not found:', searchType, SearchTypes.keys ); // } // const adjustIdx = SearchTypes.objs[ searchTypeIdx ].adjust ? SearchTypes.objs[ searchTypeIdx ].adjust : 0; // searchTypeIdx = searchTypeIdx + adjustIdx; // if ( searchType === 'entity' ) { // // console.log('found Entity:', searchType, searchTypeIdx, item ); // } // searchTypeIdx = searchTypeIdx > -1 ? searchTypeIdx : SearchTypes.keys.length -1 ; // item.FPSItem.Search.searchTitle = `${searchTitle}`; // item.FPSItem.Search.searchDesc = `${searchDesc}`; // item.FPSItem.Search.searchHref = `${searchHref}`; /** * 2025-01-20: Added this for https://github.com/mikezimm/pivottiles7/issues/439 * addSearchMeta2 was consoling warnings when there was no Search.type so I'm adding the default if it was not added */ if (!item.FPSItem.Search.type && sourceProps.defType) item.FPSItem.Search.type = sourceProps.defType; }); return items; } /** * addStandardSearchArrays: * * This was derived from ALVFM DataFetch which added keyword arrays found in item search directly to the item. * This makes searching faster when using buttons because it is just looking for a specific word match in an array... not searching entire string. * * @param item * @param sourceProps - These are specific search criteria based on each specific source * @param search - These are general search criteria used in a multi-source search page like in ALVFM * @returns */ export function addStandardSearchArrays(item, sourceProps, search) { //update item's top search string arrays if (search && search.top && search.top.Search) item = buildItemSearchArray(item, 'top', search.top.Search, search.top.SearchLC, sourceProps.OverflowTab); if (search && search.left && search.left.Search) item = buildItemSearchArray(item, 'left', search.left.Search, search.left.SearchLC, sourceProps.OverflowTab); if (search && search.type && search.type.Search) item = buildItemSearchArray(item, 'type', search.type.Search, search.type.SearchLC, sourceProps.OverflowTab); if (sourceProps.meta0 && sourceProps.meta0.length > 0) item = buildItemSearchArray(item, 'meta0', sourceProps.meta0, [], sourceProps.OverflowTab); if (sourceProps.meta1 && sourceProps.meta1.length > 0) item = buildItemSearchArray(item, 'meta1', sourceProps.meta1, [], sourceProps.OverflowTab); if (sourceProps.meta2 && sourceProps.meta2.length > 0) item = buildItemSearchArray(item, 'meta2', sourceProps.meta2, [], sourceProps.OverflowTab); if (sourceProps.meta3 && sourceProps.meta3.length > 0) item = buildItemSearchArray(item, 'meta3', sourceProps.meta3, [], sourceProps.OverflowTab); if (sourceProps.metaX && sourceProps.metaX.length > 0) item = buildItemSearchArray(item, 'metaX', sourceProps.metaX, [], sourceProps.OverflowTab); return item; } /** * buildItemSearchArray * * This is called by addStandardSearchArrays and makes it more reuslable and scalable to add this type of data to items. * * @param item * @param key * @param keyWords * @param keyWordsLC * @returns */ export function buildItemSearchArray(item, key, keyWords, keyWordsLC, OverflowTab = DefaultOverflowTab) { if (!key) return item; if (!item[key]) item[key] = []; if (!item.FPSItem.Search.meta) item.FPSItem.Search.meta = []; // Based on testing if ( ![] ) and it does not exist yet, it will return true and then create it. if (!item[`${key}LC`]) item[`${key}LC`] = []; // 2023-02-16: Added for cases where you use something like meta1 if (!item[`${key}Search`]) item[`${key}Search`] = []; if (!item[`${key}SearchLC`]) item[`${key}SearchLC`] = []; keyWords.map((keyWord, idx) => { // 2023-02-16: Added for when keyWordsLC === 0... then you can't get an index so just use keyWord const keyWordLC = keyWordsLC && keyWordsLC.length > 0 && keyWordsLC.length >= idx ? keyWordsLC[idx] : keyWord.toLocaleLowerCase(); if (item.FPSItem.Search.searchTextLC.indexOf(keyWordLC) > -1) { item[`${key}Search`].push(keyWord); item[`${key}SearchLC`].push(keyWordLC); // Finally add normal case keyword to meta array for use downstream - aka highlighted text with casing for readability item.FPSItem.Search.meta.push(keyWord); } }); // 2023-02-16: Added for cases where you use something like meta1 if (item[`${key}Search`].length === 0) { item[`${key}Search`].push(OverflowTab); item[`${key}SearchLC`].push(OverflowTab.toLocaleLowerCase()); } return item; } //# sourceMappingURL=addSearchMeta1.js.map