import { ICrmDataProvider } from './ICrmDataProvider' ; import { ISPField } from '../data/ISPField' ; import { ISPView } from '../data/ISPView' ; import { ISPUser } from '../data/ISPUser' ; import { ISharePointItem } from '../data/ISharePointItem' ; import { IPerson } from '../data/IPerson' ; import { IOrganization } from '../data/IOrganization' ; import { IOrganizationSet } from './IOrganizationSet' ; import OrganizationSet from './OrganizationSet' ; import { DataProviderErrorCodes } from './DataError' ; import { ITag } from '../data/ITag' ; import { ITagSet } from './ITagSet' ; import { BaseCrmDataProvider } from './BaseCrmDataProvider' ; import { IEvent } from '../utilities/Events' ; import { sp } from '../pnp-preset' ; import { IWebPartContext } from '@microsoft/sp-webpart-base' ; import { IItemAddResult , IItemUpdateResult , IItems } from '@pnp/sp/items' ; import { IListInfo } from '@pnp/sp/lists' ; import { IFieldInfo } from '@pnp/sp/fields' ; export default class SharePointCrmDataProvider extends BaseCrmDataProvider implements ICrmDataProvider { private _meUserLoginName : string ; private _personFieldListSelect = "$select=Id,Title,FirstName,Company,OrganizationId" ; private _organizationFieldListSelect = "$select=Id,Title" ; public get meUserLoginName ( ) : string { return this . _meUserLoginName ; } public set meUserLoginName ( newValue ) { this . _meUserLoginName = newValue ; } constructor ( context ) { super ( ) ; sp . setup ( context ) ; sp . configure ( { headers : [ [ 'X-ClientTag' , 'SPCommunityCrmWebPart' ] ] } ) ; this . _idCounter = 0 ; } public updateAll ( ) { return new Promise < boolean > ( ( resolve ) => { resolve ( true ) ; } ) ; } private _addPersonItem ( person ) { return sp . web . lists . getByTitle ( 'Contacts' ) . items . add ( person , this . _selectedPersonList . ListItemEntityTypeFullName ) ; } private _getUsers ( filter ) { return sp . web . siteUserInfoList . items . filter ( filter ) . get ( ) ; } private _getPersonItems ( filter ? , orderBy ? , orderAsc ? , top ? ) { let personItems = sp . web . lists . getByTitle ( 'Contacts' ) . items . select ( 'Id' , 'Title' , 'FirstName' , 'Company' , 'OrganizationId' ) ; if ( filter ) { personItems = personItems . filter ( filter ) ; } if ( orderBy ) { personItems = personItems . orderBy ( orderBy , orderAsc ) ; } if ( top ) { personItems = personItems . top ( top ) ; } return personItems . get ( ) ; } private _fixupItem ( item ) { for ( var key in item ) { if ( key . length >= 9 && key . substring ( key . length - 8 , key . length ) == "StringId" ) { if ( item [ key . substring ( 0 , key . length - 8 ) + "Id" ] != null ) { item [ key ] = item [ key . substring ( 0 , key . length - 8 ) + "Id" ] . toString ( ) ; } else { item [ key ] = null ; } } } } private _updatePersonItem ( item ) { return sp . web . lists . getByTitle ( 'Contacts' ) . items . getById ( item . Id ) . update ( item , '*' , this . _selectedPersonList . ListItemEntityTypeFullName ) ; } public addPersonItem ( newPerson ) { return new Promise < IPerson [ ] > ( ( resolve , reject ) : void => { this . _addPersonItem ( newPerson ) . then ( ( ) : Promise < IPerson [ ] > => { return this . _getPersonItems ( undefined , 'Created' , false , 1 ) ; } ) . then ( ( people ) : void => { this . _onPersonAdded . dispatch ( this , newPerson ) ; resolve ( people ) ; } ) ; } ) ; } public notifyPersonChanged ( person ) { this . _onPersonChanged . dispatch ( this , person ) ; } public readUsersByIds ( ids ) { var query = "" ; for ( var id of ids ) { if ( query . length > 0 ) { query += " or " ; } query += "Id eq " + id ; } return this . _getUsers ( query ) ; } public readUsersByUserName ( userName ) { return this . _getUsers ( `substringof('${ userName }', Name)` ) ; } public readUsersBySearch ( search ) { return this . _getUsers ( "substringof('" + search + "', Title)" ) ; } public readPersonItemsBySearch ( search ) { return this . _getPersonItems ( "substringof('" + search + "', Full_x0020_Name)" ) ; } public readPersonItems ( ) { return this . _getPersonItems ( null ) ; } public readPersonItemsByOrganizationId ( organizationId ) { return this . _getPersonItems ( "OrganizationId eq " + organizationId ) ; } public readPersonItemsByIds ( ids ) { var searchQuery = "" ; for ( var id of ids ) { if ( searchQuery . length > 0 ) { searchQuery += " or " ; } searchQuery += "Id eq " + id . toString ( ) ; } return this . _getPersonItems ( searchQuery ) ; } public get onPersonAdded ( ) : IEvent < ICrmDataProvider , IPerson > { return this . _onPersonAdded . asEvent ( ) ; } public get onPersonChanged ( ) : IEvent < ICrmDataProvider , IPerson > { return this . _onPersonChanged . asEvent ( ) ; } public get onPersonRemoved ( ) : IEvent < ICrmDataProvider , IPerson > { return this . _onPersonRemoved . asEvent ( ) ; } public updatePersonItem ( itemUpdated ) { return new Promise < IPerson [ ] > ( ( resolve , reject ) : void => { this . _updatePersonItem ( itemUpdated ) . then ( ( ) : Promise < IPerson [ ] > => { return this . _getPersonItems ( undefined , 'Modified' , false , 1 ) ; } ) . then ( ( people ) : void => { resolve ( people ) ; } ) ; } ) ; } public deletePersonItem ( itemDeleted ) { return this . readPersonItems ( ) ; } public get onOrganizationAdded ( ) : IEvent < ICrmDataProvider , IOrganization > { return this . _onOrganizationAdded . asEvent ( ) ; } public get onOrganizationChanged ( ) : IEvent < ICrmDataProvider , IOrganization > { return this . _onOrganizationChanged . asEvent ( ) ; } public get onOrganizationRemoved ( ) : IEvent < ICrmDataProvider , IOrganization > { return this . _onOrganizationRemoved . asEvent ( ) ; } public get onTagAdded ( ) : IEvent < ICrmDataProvider , ITag > { return this . _onTagAdded . asEvent ( ) ; } public get onTagChanged ( ) : IEvent < ICrmDataProvider , ITag > { return this . _onTagChanged . asEvent ( ) ; } public get onTagRemoved ( ) : IEvent < ICrmDataProvider , ITag > { return this . _onTagRemoved . asEvent ( ) ; } private _addTagItem ( tag ) { return sp . web . lists . getByTitle ( 'Tags' ) . items . add ( tag , this . selectedTagList . ListItemEntityTypeFullName ) ; } public init ( ) { return this . _loadListData ( ) ; } private _loadListData ( ) { const orgListDataPromise = sp . web . lists . getByTitle ( 'Organizations' ) . select ( 'Id' ) . get ( ) . then ( ( list ) : void => { this . _selectedOrganizationList . Id = list . Id ; } , _ => { this . pushError ( "The Organization list was not found." , DataProviderErrorCodes . OrganizationListDoesNotExist ) ; } ) ; const tagsListDataPromise = sp . web . lists . getByTitle ( 'Tags' ) . select ( 'Id' ) . get ( ) . then ( ( list ) : void => { this . _selectedTagList . Id = list . Id ; } ) ; const meUserListDataPromise = sp . web . siteUserInfoList . items . filter ( `substringof('${ this . meUserLoginName }', Name)` ) . get ( ) . then ( items => { if ( items . length > 0 ) { this . meUser = items [ 0 ] ; } } ) ; const orgListFieldDataPromise = sp . web . lists . getByTitle ( 'Organizations' ) . fields . filter ( "Hidden eq false and FieldTypeKind ne 12 and InternalName ne 'AppEditor' and InternalName ne 'AppAuthor'" ) . select ( 'ID' , 'InternalName' , 'Title' , 'FieldTypeKind' , 'Choices' , 'RichText' , 'AllowMultipleValues' , 'MaxLength' , 'LookupList' ) . get ( ) . then ( ( fields ) : void => { this . _organizationFieldListSelect = "?$select=" ; for ( let listField of fields ) { this . _organizationFieldListSelect += listField . InternalName + ", " ; } this . _organizationFieldListSelect = this . _organizationFieldListSelect . substring ( 0 , this . _organizationFieldListSelect . length - 2 ) ; this . _selectedOrganizationList . Fields = ( fields as any ) as ISPField [ ] ; } ) ; const personListFieldDataPromise = sp . web . lists . getByTitle ( 'Contacts' ) . fields . filter ( "Hidden eq false and FieldTypeKind ne 12 and InternalName ne 'AppEditor' and InternalName ne 'AppAuthor'" ) . select ( 'ID' , 'InternalName' , 'Title' , 'FieldTypeKind' , 'Choices' , 'RichText' , 'AllowMultipleValues' , 'MaxLength' , 'LookupList' ) . get ( ) . then ( ( fields ) : void => { this . _personFieldListSelect = "?$select=" ; for ( let listField of fields ) { this . _personFieldListSelect += listField . InternalName + ", " ; } this . _personFieldListSelect = this . _personFieldListSelect . substring ( 0 , this . _personFieldListSelect . length - 2 ) ; this . _selectedPersonList . Fields = ( fields as any ) as ISPField [ ] ; } ) ; const promises = [ orgListDataPromise , tagsListDataPromise , orgListFieldDataPromise , meUserListDataPromise , personListFieldDataPromise ] ; return Promise . all ( promises ) . then ( ( ) : void => { this . validate ( ) ; } ) ; } private _getOrganizationItems ( query , orderBy , orderAsc ? ) { let organizationItems = sp . web . lists . getByTitle ( 'Organizations' ) . items . select ( 'Id' , 'Title' ) ; if ( query ) { organizationItems = organizationItems . filter ( query ) ; } if ( orderBy ) { organizationItems = organizationItems . orderBy ( orderBy , orderAsc ) ; } return organizationItems . get ( ) . then ( ( organizations ) => { let orgSet = this . _ensureOrganizationSet ( query + "|" + orderBy ) ; this . notifyOrganizationsChanged ( organizations , orgSet ) ; return orgSet ; } ) . catch ( _ => { this . pushError ( "Couldn't retrieve lists for the app." , DataProviderErrorCodes . Unknown ) ; return null ; } ) ; } private _updateOrganizationItem ( item ) { return sp . web . lists . getByTitle ( 'Organizations' ) . items . getById ( item . Id ) . update ( item , '*' , this . _selectedOrganizationList . ListItemEntityTypeFullName ) ; } public addOrganizationItem ( newOrganization ) { this . _fixupItem ( newOrganization ) ; return new Promise < IOrganizationSet > ( ( resolve , reject ) : void => { this . _addOrganizationItem ( newOrganization ) . then ( ( ) : Promise < IOrganizationSet > => { return this . _getOrganizationItems ( null , 'Created' , false ) ; } ) . then ( ( organizationSet ) : void => { resolve ( organizationSet ) ; } , ( err ) : void => { reject ( err ) ; } ) ; } ) ; } public notifyOrganizationChanged ( person ) { this . _onOrganizationChanged . dispatch ( this , person ) ; } public readOrganizationItemsByView ( view ) { var query = "" ; if ( view . query != null ) { query = view . query . getOdataQuery ( this . selectedOrganizationList ) ; } return this . _getOrganizationItems ( query , null ) ; } public readOrganizationItemsByPriority ( priority ) { if ( priority > 20 ) { return this . _getOrganizationItems ( "Organizational_x0020_Priority gt " + priority + " or Organizational_x0020_Priority eq null" , null ) ; } else { return this . _getOrganizationItems ( "Organizational_x0020_Priority eq " + priority , null ) ; } } public readOrganizationItemsBySearch ( search , tagItemIds ) { var tagItemQuery = "" ; var searchQuery = "" ; if ( tagItemIds != null ) { for ( var tagItemId of tagItemIds ) { tagItemQuery += " or Tags eq " + tagItemId ; } } if ( search . length >= 3 ) { searchQuery = "substringof('" + search + "', Title)" ; } if ( tagItemQuery . length > 0 && searchQuery . length == 0 ) { tagItemQuery = tagItemQuery . substring ( 4 , tagItemQuery . length ) ; } return this . _getOrganizationItems ( searchQuery + tagItemQuery , null ) ; } public readOrganizationItems ( ) { return this . _getOrganizationItems ( null , null ) ; } public readOrganizationItemsByIds ( ids ) { var searchQuery = "" ; for ( var id of ids ) { if ( searchQuery . length > 0 ) { searchQuery += " or " ; } searchQuery += "Id eq " + id . toString ( ) ; } return this . _getOrganizationItems ( searchQuery , null ) ; } public readRecentOrganizationItems ( ) { return this . _getOrganizationItems ( null , "Modified" , false ) ; } public readMyOrganizationItems ( ) { return this . readOrganizationItems ( ) ; } public updateOrganizationItem ( itemUpdated ) { return new Promise < IOrganizationSet > ( ( resolve , reject ) : void => { this . _updateOrganizationItem ( itemUpdated ) . then ( ( ) : Promise < IOrganizationSet > => { return this . _getOrganizationItems ( null , "Modified" , false ) ; } ) . then ( ( organizationSet ) : void => { resolve ( organizationSet ) ; } , ( err ) : void => { reject ( err ) ; } ) ; } ) ; } public deleteOrganizationItem ( itemDeleted ) { return this . readOrganizationItems ( ) ; } private _getTagItems ( query , orderBy , orderAsc ? ) { return sp . web . lists . getByTitle ( 'Tags' ) . items . filter ( query ) . orderBy ( orderBy , orderAsc ) . select ( 'Id' , 'Title' , 'Description' ) . get ( ) . then ( ( tags ) => { let tagSet = this . _ensureTagSet ( query + "|" + orderBy ) ; this . notifyTagsChanged ( tags , tagSet ) ; return tagSet ; } ) ; } private _updateTagItem ( item ) { return sp . web . lists . getByTitle ( 'Organizations' ) . items . getById ( item . Id ) . update ( item , this . _selectedTagList . ListItemEntityTypeFullName ) ; } private _addOrganizationItem ( organization ) { return sp . web . lists . getByTitle ( 'Organizations' ) . items . add ( organization , this . selectedOrganizationList . ListItemEntityTypeFullName ) ; } public addTagItem ( newTag ) { return new Promise < ITagSet > ( ( resolve , reject ) : void => { this . _addTagItem ( newTag ) . then ( ( ) : Promise < ITagSet > => { return this . _getTagItems ( null , "Created" , false ) ; } ) . then ( ( tagSet ) : void => { resolve ( tagSet ) ; } , ( err ) : void => { reject ( err ) ; } ) ; } ) ; } public notifyTagChanged ( person ) { this . _onTagChanged . dispatch ( this , person ) ; } public readTagItemsBySearch ( search ) { return this . _getTagItems ( "substringof('" + search + "', Title)" , null ) ; } public readTagItems ( ) { return this . _getTagItems ( null , null ) ; } public readTagItemsByIds ( ids ) { var searchQuery = "" ; for ( var id of ids ) { if ( searchQuery . length > 0 ) { searchQuery += " or " ; } searchQuery += "Id eq " + id . toString ( ) ; } return this . _getTagItems ( searchQuery , null ) ; } public readRecentTagItems ( ) { return this . _getTagItems ( null , "Modified" , false ) ; } public readMyTagItems ( ) { return this . readTagItems ( ) ; } public updateTagItem ( itemUpdated ) { return new Promise < ITagSet > ( ( resolve , reject ) : void => { this . _updateTagItem ( itemUpdated ) . then ( ( ) : Promise < ITagSet > => { return this . _getTagItems ( null , "Modified" , false ) ; } ) . then ( ( tagSet ) : void => { resolve ( tagSet ) ; } , ( err ) : void => { reject ( err ) ; } ) ; } ) ; } public deleteTagItem ( itemDeleted ) { return this . readTagItems ( ) ; } }