import * as React from 'react' ; import * as ReactDOM from 'react-dom' ; import { Button , ButtonType } from 'office-ui-fabric-react' ; import { Log } from '@microsoft/sp-core-library' ; import Announcement from './Announcement' ; import { IAnnouncement } from '../IAnnouncement' ; import { IAnnouncementItem } from '../IAnnouncementItem' ; import { SPHttpClient , SPHttpClientResponse } from '@microsoft/sp-http' ; const STORAGE_KEY = 'AnnouncementsApplicationCustomizer' ; const LOG_SOURCE = 'AnnouncementsApplicationCustomizer_Announcements' ; export interface IAnnouncementsState { isLoading : boolean ; allAnnouncements : IAnnouncement [ ] ; acknowledgedAnnouncements : number [ ] ; } export interface IAnnouncementsProps { siteUrl : string ; listName : string ; spHttpClient : SPHttpClient ; } export default class Announcements extends React . Component < IAnnouncementsProps , IAnnouncementsState > { constructor ( props ) { super ( props ) ; this . state = { isLoading : true , allAnnouncements : [ ] , acknowledgedAnnouncements : [ ] } ; } protected componentDidMount ( ) { this . setState ( { isLoading : true , allAnnouncements : [ ] , acknowledgedAnnouncements : [ ] } ) ; Promise . all ( [ this . getAnnouncements ( ) , this . getAcknowledgedAnnouncements ( ) ] ) . then ( ( results ) : void => { this . setState ( { isLoading : false , allAnnouncements : results [ 0 ] , acknowledgedAnnouncements : results [ 1 ] } ) ; } ) . catch ( ( error ) : void => { Log . error ( LOG_SOURCE , new Error ( `Error loading announcements: ${ error }` ) ) ; this . setState ( { isLoading : false , allAnnouncements : [ ] , acknowledgedAnnouncements : [ ] } ) ; } ) ; } public render ( ) { if ( this . state . isLoading ) { return null ; } const announcementElements = this . state . allAnnouncements . map ( ( announcement ) : JSX . Element => { if ( this . state . acknowledgedAnnouncements . indexOf ( announcement . id ) < 0 ) { return < Announcement { ... announcement } acknowledge = { this . acknowledgeAnnouncement . bind ( this , announcement ) } / > ; } else { return null ; } } ) ; return < div > { announcementElements } < /div>; } private getAnnouncements ( ) { return new Promise < IAnnouncement [ ] > ( ( resolve , reject ) : void => { this . props . spHttpClient . get ( `${ this . props . siteUrl }/_api/web/lists/getByTitle('${ this . props . listName }')/items?$select=ID,Title,Announcement,Urgent` , SPHttpClient . configurations . v1 , { headers : { 'Accept' : 'application/json;odata.metadata=none' } } ) . then ( ( response ) : Promise < { value : IAnnouncementItem [ ] ; } > => { return response . json ( ) ; } ) . then ( ( announcements ) : void => { resolve ( announcements . value . map ( ( item ) : IAnnouncement => { return { id : item . ID , title : item . Title , announcement : item . Announcement , urgent : item . Urgent } ; } ) ) ; } ) . catch ( ( error ) : void => { reject ( error ) ; } ) ; } ) ; } private getAcknowledgedAnnouncements ( ) { return new Promise < number [ ] > ( ( resolve , reject ) : void => { if ( window . localStorage ) { const items = window . localStorage . getItem ( STORAGE_KEY ) ; if ( items ) { resolve ( JSON . parse ( items ) ) ; } else { resolve ( [ ] ) ; } } } ) ; } private acknowledgeAnnouncement ( announcement ) { if ( ! window . localStorage ) { return ; } let items = [ ] ; const itemsString = window . localStorage . getItem ( STORAGE_KEY ) ; if ( itemsString ) { items = JSON . parse ( itemsString ) ; } items . push ( announcement . id ) ; window . localStorage . setItem ( STORAGE_KEY , JSON . stringify ( items ) ) ; this . setState ( ( prevState , props ) : IAnnouncementsState => { prevState . acknowledgedAnnouncements = items ; return prevState ; } ) ; } }