import { override } from '@microsoft/decorators' ; import { BaseApplicationCustomizer , PlaceholderContent , PlaceholderName } from '@microsoft/sp-application-base' ; import { IHubSiteData , IHubSiteDataResponse } from './IHubSiteData' ; import { SPHttpClientResponse , SPHttpClient } from '@microsoft/sp-http' ; import { IAlert , IAlertItem , AlertType } from './IAlert' ; import * as React from 'react' ; import * as ReactDom from 'react-dom' ; import { IAlertNotificationsProps , AlertNotifications } from './components' ; /**
 * If your command set uses the ClientSideComponentProperties JSON input,
 * it will be deserialized into the BaseExtension.properties object.
 * You can define an interface to describe it.
 */ export interface IHubOrSiteAlertsApplicationCustomizerProperties { } /** A Custom Action which can be run during execution of a Client Side Application */ export default class HubOrSiteAlertsApplicationCustomizer extends BaseApplicationCustomizer < IHubOrSiteAlertsApplicationCustomizerProperties > { private static _topPlaceholder ? : PlaceholderContent ; /**
     * Constant used to exit the chain of promises when the current site
     * is not connected to a hub site and is not a hub site itself.
     */ private static readonly NO_HUBSITE_DATA : string = 'NO_HUBSITE_DATA' ; @ override public onInit ( ) { this . context . application . navigatedEvent . add ( this , this . _render ) ; return Promise . resolve ( ) ; } private _handleDispose ( ) { console . log ( '[HubOrSiteAlertsApplicationCustomizer._onDispose] Disposed custom top placeholder.' ) ; } /**
     * Retrieves information about the hub site to which the current site is connected.
     * If the current site is a hub site itself, returns information about the current
     * hub site.
     * If the is not connected to a hub sites, returns null;
     */ private _getConnectedHubSiteData ( ) { return new Promise < IHubSiteData > ( ( resolve , reject ) : void => { const headers = new Headers ( ) ; headers . append ( 'accept' , 'application/json;odata.metadata=none' ) ; this . context . spHttpClient . get ( `${ this . context . pageContext . web . absoluteUrl }/_api/web/hubsitedata` , SPHttpClient . configurations . v1 , { headers : headers } ) . then ( ( res ) : Promise < IHubSiteDataResponse > => { return res . json ( ) ; } ) . then ( ( res ) : void => { if ( res [ '@odata.null' ] === true ) { resolve ( undefined ) ; return ; } try { const hubSiteData = JSON . parse ( res . value ) ; resolve ( hubSiteData ) ; } catch ( e ) { reject ( e ) ; } } ) . catch ( ( error ) : void => { reject ( error ) ; } ) ; } ) ; } param hubSiteUrl private _loadUpcomingAlerts ( hubSiteUrl ) { return new Promise < IAlert [ ] > ( ( resolve , reject ) : void => { const headers = new Headers ( ) ; headers . append ( 'accept' , 'application/json;odata.metadata=none' ) ; const nowString = new Date ( ) . toISOString ( ) ; this . context . spHttpClient . get ( hubSiteUrl + '/_api/web/lists/getByTitle(\'Alerts\')/items?' + '$filter=PnPAlertStartDateTime le datetime\'' + nowString + '\' ' + 'and PnPAlertEndDateTime ge datetime\'' + nowString + '\' ' + '&$select=PnPAlertType,PnPAlertMessage,PnPAlertMoreInformation&$orderby=PnPAlertEndDateTime' , SPHttpClient . configurations . v1 , { headers : headers } ) . then ( ( res ) : Promise < { value : IAlertItem [ ] ; } > => { return res . json ( ) ; } ) . then ( ( res ) : void => { const upcomingAlerts = res . value . map ( alert => { return { type : AlertType [ alert . PnPAlertType ] , message : alert . PnPAlertMessage , moreInformationUrl : alert . PnPAlertMoreInformation ? alert . PnPAlertMoreInformation . Url : undefined } ; } ) ; resolve ( upcomingAlerts ) ; } ) . catch ( ( error ) : void => { reject ( error ) ; } ) ; } ) ; } private _render ( ) { if ( ! HubOrSiteAlertsApplicationCustomizer . _topPlaceholder ) { HubOrSiteAlertsApplicationCustomizer . _topPlaceholder = this . context . placeholderProvider . tryCreateContent ( PlaceholderName . Top , { onDispose : this . _handleDispose } ) ; } if ( ! HubOrSiteAlertsApplicationCustomizer . _topPlaceholder ) { return ; } this . _getConnectedHubSiteData ( ) . then ( ( connectedHubSiteData ) : Promise < IAlert [ ] > => { if ( ! connectedHubSiteData || connectedHubSiteData === undefined ) { return Promise . reject ( HubOrSiteAlertsApplicationCustomizer . NO_HUBSITE_DATA ) ; } return this . _loadUpcomingAlerts ( connectedHubSiteData . url ) ; } ) . then ( ( upcomingAlerts ) : void => { if ( upcomingAlerts . length === 0 ) { console . log ( 'No upcoming alerts found' ) ; return ; } const element = React . createElement ( AlertNotifications , { alerts : upcomingAlerts } ) ; ReactDom . render ( element , HubOrSiteAlertsApplicationCustomizer . _topPlaceholder . domElement ) ; } ) . catch ( ( error ) : void => { if ( error === HubOrSiteAlertsApplicationCustomizer . NO_HUBSITE_DATA ) { console . log ( `Current site is not connected to a hub site and is not a hub site itself.
            Skipping loading alerts` ) ; } else { console . error ( error ) ; } } ) ; } }