@@ -2,13 +2,20 @@ import { ISPService, ILibsOptions, LibsOrderBy, IFieldsOptions, FieldsOrderBy }
22import { ISPField , ISPList , ISPLists , IUploadImageResult } from "../common/SPEntities" ;
33import { BaseComponentContext } from '@microsoft/sp-component-base' ;
44import { SPHttpClient , ISPHttpClientOptions } from "@microsoft/sp-http" ;
5- import { urlCombine } from "../common/utilities" ;
5+ import { SPHelper , urlCombine } from "../common/utilities" ;
66import filter from 'lodash/filter' ;
77import find from 'lodash/find' ;
88
9+ interface ICachedListItems {
10+ items : any [ ] ;
11+ expiration : number ;
12+ }
13+
914export default class SPService implements ISPService {
1015
1116 private _webAbsoluteUrl : string ;
17+ private _cachedListItems : Map < string , ICachedListItems > = new Map < string , ICachedListItems > ( ) ;
18+
1219
1320 constructor ( private _context : BaseComponentContext , webAbsoluteUrl ?: string ) {
1421 this . _webAbsoluteUrl = webAbsoluteUrl ? webAbsoluteUrl : this . _context . pageContext . web . absoluteUrl ;
@@ -146,13 +153,24 @@ export default class SPService implements ISPService {
146153 /**
147154 * Get List Items
148155 */
149- public async getListItems ( filterText : string , listId : string , internalColumnName : string , field : ISPField | undefined , keyInternalColumnName ?: string , webUrl ?: string , filterString ?: string , substringSearch : boolean = false , orderBy ?: string ) : Promise < any [ ] > {
156+ public async getListItems (
157+ filterText : string ,
158+ listId : string ,
159+ internalColumnName : string ,
160+ field : ISPField | undefined ,
161+ keyInternalColumnName ?: string ,
162+ webUrl ?: string ,
163+ filterString ?: string ,
164+ substringSearch : boolean = false ,
165+ orderBy ?: string ,
166+ cacheInterval : number = 1 ) : Promise < any [ ] > {
150167 let returnItems : any [ ] ;
151168 const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ;
152169 let apiUrl = '' ;
153170 let isPost = false ;
171+ let processItems : ( ( items : any [ ] ) => any [ ] ) | undefined ;
154172
155- if ( field && field . TypeAsString === 'Calculated' ) { // for calculated fields we need to use CAML query
173+ if ( field && field . TypeAsString === 'Calculated' && SPHelper . isTextFieldType ( field . ResultType ) ) { // for calculated fields we need to use CAML query
156174 let orderByStr = '' ;
157175
158176 if ( orderBy ) {
@@ -169,19 +187,40 @@ export default class SPService implements ISPService {
169187 apiUrl = `${ webAbsoluteUrl } /_api/web/lists('${ listId } ')/GetItems(query=@v1)?$select=${ keyInternalColumnName || 'Id' } ,${ internalColumnName } &@v1=${ JSON . stringify ( { ViewXml : camlQuery } ) } ` ;
170188 isPost = true ;
171189 }
172- else {
190+ else if ( SPHelper . isTextFieldType ( field . TypeAsString ) ) {
173191 const filterStr = substringSearch ? // JJ - 20200613 - find by substring as an option
174192 `${ filterText ? `substringof('${ encodeURIComponent ( filterText . replace ( "'" , "''" ) ) } ',${ internalColumnName } )` : '' } ${ filterString ? ( filterText ? ' and ' : '' ) + filterString : '' } `
175193 : `${ filterText ? `startswith(${ internalColumnName } ,'${ encodeURIComponent ( filterText . replace ( "'" , "''" ) ) } ')` : '' } ${ filterString ? ( filterText ? ' and ' : '' ) + filterString : '' } ` ; //string = filterList ? `and ${filterList}` : '';
176194 apiUrl = `${ webAbsoluteUrl } /_api/web/lists('${ listId } ')/items?$select=${ keyInternalColumnName || 'Id' } ,${ internalColumnName } &$filter=${ filterStr } &$orderby=${ orderBy } ` ;
177195 }
196+ else { // we need to get FieldValuesAsText and cache them
197+ const mapKey = `${ webAbsoluteUrl } ##${ listId } ##${ internalColumnName } ##${ keyInternalColumnName || 'Id' } ` ;
198+ const cachedItems = this . _cachedListItems . get ( mapKey ) ;
199+
200+ if ( cachedItems && cachedItems . expiration < Date . now ( ) ) {
201+ return this . _filterListItemsFieldValuesAsText ( cachedItems . items , internalColumnName , filterText , substringSearch ) ;
202+ }
203+
204+ apiUrl = `${ webAbsoluteUrl } /_api/web/lists('${ listId } ')/items?$select=${ keyInternalColumnName || 'Id' } ,${ internalColumnName } ,FieldValuesAsText/${ internalColumnName } &$expand=FieldValuesAsText&$orderby=${ orderBy } ${ filterString ? '&$filter=' + filterString : '' } ` ;
205+ isPost = false ;
206+
207+ processItems = ( items : any [ ] ) => {
208+
209+ this . _cachedListItems . set ( mapKey , {
210+ items,
211+ expiration : Date . now ( ) + cacheInterval * 60 * 1000
212+ } ) ;
213+
214+ return this . _filterListItemsFieldValuesAsText ( items , internalColumnName , filterText , substringSearch ) ;
215+ } ;
216+ }
178217
179218 try {
180219 const data = isPost ? await this . _context . spHttpClient . post ( apiUrl , SPHttpClient . configurations . v1 , { } ) : await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ;
181220 if ( data . ok ) {
182221 const results = await data . json ( ) ;
183222 if ( results && results . value && results . value . length > 0 ) {
184- return results . value ;
223+ return processItems ? processItems ( results . value ) : results . value ;
185224 }
186225 }
187226
@@ -191,8 +230,6 @@ export default class SPService implements ISPService {
191230 }
192231 }
193232
194-
195-
196233 /**
197234* Gets list items for list item picker
198235* @param filterText
@@ -430,16 +467,16 @@ export default class SPService implements ISPService {
430467 return ;
431468 }
432469
433- public async getLookupValue ( listId : string , listItemID : number , fieldName : string , webUrl ?: string ) : Promise < any [ ] > {
470+ public async getLookupValue ( listId : string , listItemID : number , fieldName : string , lookupFieldName : string | undefined , webUrl ?: string ) : Promise < any [ ] > {
434471 try {
435472 const webAbsoluteUrl = ! webUrl ? this . _context . pageContext . web . absoluteUrl : webUrl ;
436- let apiUrl = `${ webAbsoluteUrl } /_api/web/lists(@listId)/items(${ listItemID } )/?@listId=guid'${ encodeURIComponent ( listId ) } '&$select=${ fieldName } /ID,${ fieldName } /Title&$expand=${ fieldName } ` ;
473+ let apiUrl = `${ webAbsoluteUrl } /_api/web/lists(@listId)/items(${ listItemID } )/?@listId=guid'${ encodeURIComponent ( listId ) } '&$select=${ fieldName } /ID,${ fieldName } /${ lookupFieldName || ' Title' } &$expand=${ fieldName } ` ;
437474
438475 const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ;
439476 if ( data . ok ) {
440477 const result = await data . json ( ) ;
441478 if ( result && result [ fieldName ] ) {
442- return [ { key : result [ fieldName ] . ID , name : result [ fieldName ] . Title } ] ;
479+ return [ { key : result [ fieldName ] . ID , name : result [ fieldName ] [ lookupFieldName || ' Title' ] } ] ;
443480 }
444481 }
445482
@@ -450,18 +487,18 @@ export default class SPService implements ISPService {
450487 }
451488 }
452489
453- public async getLookupValues ( listId : string , listItemID : number , fieldName : string , webUrl ?: string ) : Promise < any [ ] > {
490+ public async getLookupValues ( listId : string , listItemID : number , fieldName : string , lookupFieldName : string | undefined , webUrl ?: string ) : Promise < any [ ] > {
454491 try {
455492 const webAbsoluteUrl = ! webUrl ? this . _context . pageContext . web . absoluteUrl : webUrl ;
456- let apiUrl = `${ webAbsoluteUrl } /_api/web/lists(@listId)/items(${ listItemID } )?@listId=guid'${ encodeURIComponent ( listId ) } '&$select=${ fieldName } /ID,${ fieldName } /Title&$expand=${ fieldName } ` ;
493+ let apiUrl = `${ webAbsoluteUrl } /_api/web/lists(@listId)/items(${ listItemID } )?@listId=guid'${ encodeURIComponent ( listId ) } '&$select=${ fieldName } /ID,${ fieldName } /${ lookupFieldName || ' Title' } &$expand=${ fieldName } ` ;
457494
458495 const data = await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ;
459496 if ( data . ok ) {
460497 const result = await data . json ( ) ;
461498 if ( result && result [ fieldName ] ) {
462499 let lookups = [ ] ;
463500 result [ fieldName ] . forEach ( element => {
464- lookups . push ( { key : element . ID , name : element . Title } ) ;
501+ lookups . push ( { key : element . ID , name : element [ lookupFieldName || ' Title' ] } ) ;
465502 } ) ;
466503 return lookups ;
467504 }
@@ -600,4 +637,22 @@ export default class SPService implements ISPService {
600637
601638 return result ;
602639 }
640+
641+ private _filterListItemsFieldValuesAsText ( items : any [ ] , internalColumnName : string , filterText : string | undefined , substringSearch : boolean ) : any [ ] {
642+ const lowercasedFilterText = filterText . toLowerCase ( ) ;
643+
644+ return items . filter ( i => {
645+ let fieldValue = i . FieldValuesAsText [ internalColumnName ] ;
646+ if ( ! fieldValue ) {
647+ return false ;
648+ }
649+ fieldValue = fieldValue . toLowerCase ( ) ;
650+
651+ if ( ! filterText ) {
652+ return true ;
653+ }
654+
655+ return substringSearch ? fieldValue . indexOf ( lowercasedFilterText ) > - 1 : fieldValue . startsWith ( lowercasedFilterText ) ;
656+ } ) ;
657+ }
603658}
0 commit comments