@@ -6,9 +6,16 @@ import { urlCombine } from "../common/utilities";
6
6
import filter from 'lodash/filter' ;
7
7
import find from 'lodash/find' ;
8
8
9
+ interface ICachedListItems {
10
+ items : any [ ] ;
11
+ expiration : number ;
12
+ }
13
+
9
14
export default class SPService implements ISPService {
10
15
11
16
private _webAbsoluteUrl : string ;
17
+ private _cachedListItems : Map < string , ICachedListItems > = new Map < string , ICachedListItems > ( ) ;
18
+
12
19
13
20
constructor ( private _context : BaseComponentContext , webAbsoluteUrl ?: string ) {
14
21
this . _webAbsoluteUrl = webAbsoluteUrl ? webAbsoluteUrl : this . _context . pageContext . web . absoluteUrl ;
@@ -146,13 +153,24 @@ export default class SPService implements ISPService {
146
153
/**
147
154
* Get List Items
148
155
*/
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 [ ] > {
150
167
let returnItems : any [ ] ;
151
168
const webAbsoluteUrl = ! webUrl ? this . _webAbsoluteUrl : webUrl ;
152
169
let apiUrl = '' ;
153
170
let isPost = false ;
171
+ let processItems : ( ( items : any [ ] ) => any [ ] ) | undefined ;
154
172
155
- if ( field && field . TypeAsString === 'Calculated' ) { // for calculated fields we need to use CAML query
173
+ if ( field && field . TypeAsString === 'Calculated' && this . _isTextFieldType ( field . ResultType ) ) { // for calculated fields we need to use CAML query
156
174
let orderByStr = '' ;
157
175
158
176
if ( orderBy ) {
@@ -169,19 +187,40 @@ export default class SPService implements ISPService {
169
187
apiUrl = `${ webAbsoluteUrl } /_api/web/lists('${ listId } ')/GetItems(query=@v1)?$select=${ keyInternalColumnName || 'Id' } ,${ internalColumnName } &@v1=${ JSON . stringify ( { ViewXml : camlQuery } ) } ` ;
170
188
isPost = true ;
171
189
}
172
- else {
190
+ else if ( this . _isTextFieldType ( field . TypeAsString ) ) {
173
191
const filterStr = substringSearch ? // JJ - 20200613 - find by substring as an option
174
192
`${ filterText ? `substringof('${ encodeURIComponent ( filterText . replace ( "'" , "''" ) ) } ',${ internalColumnName } )` : '' } ${ filterString ? ( filterText ? ' and ' : '' ) + filterString : '' } `
175
193
: `${ filterText ? `startswith(${ internalColumnName } ,'${ encodeURIComponent ( filterText . replace ( "'" , "''" ) ) } ')` : '' } ${ filterString ? ( filterText ? ' and ' : '' ) + filterString : '' } ` ; //string = filterList ? `and ${filterList}` : '';
176
194
apiUrl = `${ webAbsoluteUrl } /_api/web/lists('${ listId } ')/items?$select=${ keyInternalColumnName || 'Id' } ,${ internalColumnName } &$filter=${ filterStr } &$orderby=${ orderBy } ` ;
177
195
}
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 } ')/GetItems?$select=${ keyInternalColumnName || 'Id' } ,FieldValuesAsText/${ internalColumnName } &$expand=FieldValuesAsText&$orderby=${ orderBy } ${ filterString ? '&$filter=' + filterString : '' } ` ;
205
+ isPost = true ;
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
+ }
178
217
179
218
try {
180
219
const data = isPost ? await this . _context . spHttpClient . post ( apiUrl , SPHttpClient . configurations . v1 , { } ) : await this . _context . spHttpClient . get ( apiUrl , SPHttpClient . configurations . v1 ) ;
181
220
if ( data . ok ) {
182
221
const results = await data . json ( ) ;
183
222
if ( results && results . value && results . value . length > 0 ) {
184
- return results . value ;
223
+ return processItems ? processItems ( results . value ) : results . value ;
185
224
}
186
225
}
187
226
@@ -191,8 +230,6 @@ export default class SPService implements ISPService {
191
230
}
192
231
}
193
232
194
-
195
-
196
233
/**
197
234
* Gets list items for list item picker
198
235
* @param filterText
@@ -600,4 +637,30 @@ export default class SPService implements ISPService {
600
637
601
638
return result ;
602
639
}
640
+
641
+ private _isTextFieldType ( fieldType ?: string ) : boolean {
642
+ if ( ! fieldType ) {
643
+ return true ;
644
+ }
645
+ const lowercasedFieldType = fieldType . toLowerCase ( ) ;
646
+ return lowercasedFieldType === 'text' || lowercasedFieldType === 'note' ;
647
+ }
648
+
649
+ private _filterListItemsFieldValuesAsText ( items : any [ ] , internalColumnName : string , filterText : string | undefined , substringSearch : boolean ) : any [ ] {
650
+ const lowercasedFilterText = filterText . toLowerCase ( ) ;
651
+
652
+ return items . filter ( i => {
653
+ let fieldValue = i . FieldValuesAsText [ internalColumnName ] ;
654
+ if ( ! fieldValue ) {
655
+ return false ;
656
+ }
657
+ fieldValue = fieldValue . toLowerCase ( ) ;
658
+
659
+ if ( ! filterText ) {
660
+ return true ;
661
+ }
662
+
663
+ return substringSearch ? fieldValue . indexOf ( lowercasedFilterText ) > - 1 : fieldValue . startsWith ( lowercasedFilterText ) ;
664
+ } ) ;
665
+ }
603
666
}
0 commit comments