{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/components/staffDirectorySearch/Search.tsx","webpack:///./src/components/staffDirectorySearch/data/DataService.ts","webpack:///./src/components/staffDirectorySearch/Errors.tsx","webpack:///./src/components/staffDirectorySearch/SearchResults.tsx","webpack:///./src/components/staffDirectorySearch/BlankSearchResults.tsx","webpack:///./src/components/staffDirectorySearch/NoSearchResults.tsx","webpack:///./src/components/staffDirectorySearch/StaffBasic.tsx","webpack:///./src/components/staffDirectorySearch/Name.tsx","webpack:///./src/components/staffDirectorySearch/Photo.tsx","webpack:///./src/components/staffDirectorySearch/QuickLinks.tsx","webpack:///./src/components/staffDirectorySearch/StaffExtended.tsx","webpack:///./src/components/staffDirectorySearch/BioAndMessage.tsx","webpack:///./src/components/staffDirectorySearch/ContactInfo.tsx","webpack:///./src/components/staffDirectorySearch/GroupsList.tsx","webpack:///./src/components/staffDirectorySearch/SecondaryInfo.tsx","webpack:///./src/components/staffDirectorySearch/SocialMediaLinks.tsx","webpack:///./src/components/staffDirectorySearch/SocialMediaLink.tsx","webpack:///./src/components/staffDirectorySearch/SearchSettings.tsx","webpack:///./src/components/staffDirectorySearch/GroupsDropdown.tsx","webpack:///./src/components/staffDirectorySearch/ResetButton.tsx","webpack:///./src/components/staffDirectorySearch/SearchButton.tsx","webpack:///./src/components/staffDirectorySearch/SearchTerm.tsx","webpack:///./src/components/staffDirectorySearch/classes/Group.ts","webpack:///./src/components/staffDirectorySearch/classes/StaffBasic.ts","webpack:///./src/components/staffDirectorySearch/classes/StaffExtended.ts","webpack:///./src/components/common/paginator/paginatorComponent.tsx","webpack:///./src/components/staffDirectorySearch/demoPage/staffDirectorySearchPage.tsx","webpack:///./src/components/staffDirectorySearch/classes/ObjectVerifier.ts","webpack:///./src/components/staffDirectorySearch/Utilities.ts","webpack:///./src/components/staffDirectorySearch/IStaffDirectorySearch.ts","webpack:///./src/components/staffDirectorySearch/LargeLoadingSpinner.tsx","webpack:///./src/components/staffDirectorySearch/Email.tsx","webpack:///./src/components/staffDirectorySearch/classes/Localization.ts","webpack:///./src/components/EnviroConfig.ts","webpack:///./src/components/staffDirectorySearch/classes/Settings.ts"],"names":["i","chunkIds","length","deferredModules","j","deferredModule","enumerable","get","getter","value","key","bind","module","Object","prototype","hasOwnProperty","call","object","property","jsonpArray","webpackJsonpCallback","Search","props","savedStaffBasicPages","maxNumberPageLinks","resultsPerPage","maxGroupLengthDisplayedInWideScreen","maxGroupLengthDisplayedInNarrowScreen","dataService","setInitialState","bindCallbackFunctionsToThisComponent","this","loadSettings","handleResize","e","selectedGroupID","parseInt","target","setState","searchTerm","setPage","loadSearchResults","nativeEvent","preventDefault","userID","state","staffMembersExtended","groupIDs","settings","groups","g","push","groupID","loadUserExtended","flipExpandedState","pageNumber","loadingText","localization","loading","className","errors","errorMessage","settingsLoaded","portletInstanceId","portletInstanceID","searchByJobTitle","maxTextLengthDisplayedForGroup","onSelectGroup","onChangeSearchTerm","onClickSearchButton","onClickResetButton","onKeyDownCancelSubmit","staffMembersBasic","totalNumberOfResults","pagerSettings","searchResultsLoaded","onClickMore","onChangePage","currentPageNumber","numberOfPageLinks","then","response","undefined","d","error","settingsVerification","displayResponseVerificationErrors","displayResponseErrors","addError","methodName","message","Array","savedPage","expanded","getSelectedGroupIDs","sortOrder","firstRecord","lastRecord","search","searchResultsVerification","results","pageOfStaffMembersBasic","groupIds","userExtended","staffExtendedVerification","result","verificationResult","details","map","staffMemberBasic","filter","s","toString","numPageLinks","maxLength","that","maxNumPageLinks","window","on","each","width","addClass","setMaxGroupsLengthDisplayed","removeClass","availWidthForPageLinks","Math","floor","pageLinkWidth","round","min","max","setNumberPageLinks","resize","DataService","searchParams","body","JSON","stringify","callFetch","userId","url","headers","Headers","append","baseURL","staffDirServiceURL","fetch","method","credentials","ok","json","statusText","Errors","console","log","SearchResults","textCurrentlyDisplayingPageText","currentlyDisplayingPage","textDisplayPageText","displayPage","textDisplayPreviousPageOfResults","displayPreviousPageOfResults","textDisplayPreviousSetOfPageLinks","displayPreviousSetOfPageLinks","textDisplayNextPageOfResults","displayNextPageOfResults","textDisplayNextSetOfPageLinks","displayNextSetOfPageLinks","textNoNextPageOfResults","noNextPageOfResults","textNoNextSetOfPageLinks","noNextSetOfPageLinks","textNoPreviousPageOfResults","noPreviousPageOfResults","textNoPreviousSetOfPageLinks","noPreviousSetOfPageLinks","textOf","of","textOfResultsText","ofResults","textNoResultsFoundText","noResultsFound","textLoading","numberOfBlankResults","role","staff","staffBasic","staffExtended","noSearchResultsText","totalNumberOfRecords","recordsPerPage","text_currentlyDisplayingPage","text_displayPage","text_displayPreviousPageOfResults","text_displayPreviousSetOfPageLinks","text_displayNextPageOfResults","text_displayNextSetOfPageLinks","text_noNextPageOfResults","text_noNextSetOfPageLinks","text_noPreviousPageOfResults","text_noPreviousSetOfPageLinks","text_of","text_ofResultsText","BlankSearchResults","rows","title","NoSearchResults","StaffBasic","btnText","btnAriaText","btnClassName","liClassName","more","moreAria","less","lessAria","firstName","lastName","staffMember","imageURL","onlyShowFirstInitial","jobTitle","website","email","useExternalEmailApp","phone","emailPrivacy","mailUrl","href","onClick","Name","name","Photo","photoClass","backgroundImageStyle","backgroundImage","initials","style","QuickLinks","showWebsite","showPhone","showEmail","showQuickButtons","phoneLink","ariaPhoneLink","telephonePersonAt","replace","titleText","websiteText","small","StaffExtended","blog","socialMediaLinks","room","grades","subjects","officeHours","biography","personalMessage","BioAndMessage","showBioOrMessage","dangerouslySetInnerHTML","__html","ContactInfo","showBlog","showContactInfo","medium","mywebsite","myblog","GroupsList","groupNames","groupName","sort","a","b","groupItems","SecondaryInfo","showSecondaryInfo","roomText","subjectsTaughtText","subjectsTaught","gradesTaughtText","gradesTaught","officeHoursText","SocialMediaLinks","smLink","SocialMediaLink","link","toLowerCase","SearchSettings","placeholder","placeholderAria","searchTermPlaceHolder","searchTermPlaceHolderAria","searchTermPlaceHolder_NameOnly","searchTermPlaceHolderAria_NameOnly","searchText","resetText","maxTextLengthDisplayed","GroupsDropdown","text","allGroupsName","all","selectedGroupName","reduce","substr","onChange","id","group","ResetButton","SearchButton","type","SearchTerm","onKeyDown","Group","verifyGroup","thing","parentObjectChain","v","checkHasProperty","checkIsInteger","checkIsString","verifyStaffBasicArray","isArray","index","checkIsObject","staffBasicVerificationResult","verifyStaffBasic","combineVerificationResults","stringProperties","prop","removeParentObject","verifyStaffExtended","checkIsArray","propName","addParentObject","PaginatorComponent","numberOfPages","currentPageSet","numberOfPageSets","firstPageLinkDisplayed","lastPageLinkDisplayed","firstRecordDisplayed","lastRecordDisplayed","showPager","showPagerEvenIfOnlyOnlyOnePageOfResults","setPageDisplayed","setRecordsPerPage","displayPreviousPage","displayPreviousPageSet","displayNextPage","displayNextPageSet","killEvent","ceil","leftArrow","getLeftArrow","leftEllipsis","getLeftEllipsis","pageLinks","getPageLinks","blankLinks","getBlankLinks","rightEllipsis","getRightEllipsis","rightArrow","getRightArrow","pagerOptions","includeRecordsPerPageDropdown","pagerOptionNumbers","recordsPerPageOptions","forEach","p","text_perPage","pageLink","blankLink","ariaLabel","anchorClassName","ariaCurrent","numLinksDisplayed","attributes","onChangeRecordsPerPage","components","document","getElementsByClassName","Component","elem","nodeValue","ObjectVerifier","propertyName","isNaN","Number","obj","otherResult","detail","pop","join","formatName","lastNamePosition","lastIndexOf","firstNamePosition","adjustedFirstName","nullCheck","item","speakPhoneAsNumbers","output","EmailStyle","LargeLoadingSpinner","OpenModalDialog","height","feature","open","Email","emailText","alt","emailPopupURL","linkhref","emailAria","handleLinkClick","Localization","verifyLocalizer","exampleLocalization","EnviroConfig","toBoolean","x","useProductionConfig","newsroomServiceURL","createAlertServiceURL","portletLibraryServiceURL","iconpickerServiceURL","newsroomApiBaseUrl","quicklinkportletServiceURL","searchServiceURL","calendarServiceURL","unifiedPublishingBaseURL","unifiedPublishingAlertServiceURL","bannerServiceURL","socialMediaManagementURL","emailPopupPath","modernSocialMediaAlertsInTestMode","ngrokURL","process","env","NGROK_URL","Settings","verifySettings","checkIsBoolean","groupVerificationResult","localizationVerificationResult"],"mappings":"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","file":"staffDirectorySearch.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t15: 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"../Common/JavaScript/resourcelibrary/reactportlets/\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([1716,0]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","import $ from \"jquery\";\r\nimport \"whatwg-fetch\"; // Polyfill for Fetch for IE.\r\n\r\nimport * as React from \"react\";\r\n\r\nimport \"../../../node_modules/font-awesome/scss/font-awesome.scss\"; // Font-Awesome SASS CSS sheet.\r\nimport \"../common/styles/common.css\";\r\nimport \"./styles/staffDirSearch.css\";\r\n\r\nimport { IInterfaceCheckResult, IPagerSettings, ISettings, IStaffBasic, IStaffExtended } from \"./IStaffDirectorySearch\";\r\n\r\nimport { DataService } from \"./data/DataService\";\r\n\r\nimport { Errors } from \"./Errors\";\r\nimport { LargeLoadingSpinner } from \"./LargeLoadingSpinner\";\r\nimport { SearchResults } from \"./SearchResults\";\r\nimport { SearchSettings } from \"./SearchSettings\";\r\n\r\nimport { Localization } from \"./classes/Localization\";\r\nimport { Settings, verifySettings } from \"./classes/Settings\";\r\nimport { StaffBasic, verifyStaffBasicArray } from \"./classes/StaffBasic\";\r\nimport { StaffExtended, verifyStaffExtended } from \"./classes/StaffExtended\";\r\n\r\nexport interface ISearchProps extends React.Props<Search> {\r\n  portletInstanceID: number;\r\n}\r\n\r\nexport interface ISearchState {\r\n  settingsLoaded: boolean;\r\n  searchResultsLoaded: boolean;\r\n  settings: ISettings;\r\n  selectedGroupID: number;\r\n  searchTerm: string;\r\n  maxTextLengthDisplayedForGroup: number;\r\n  staffMembersBasic: IStaffBasic[];\r\n  staffMembersExtended: { [userID: number]: IStaffExtended };\r\n  totalNumberOfResults: number;\r\n  errors: string[];\r\n  pagerSettings: IPagerSettings;\r\n}\r\n\r\nexport default class Search extends React.Component<ISearchProps, ISearchState> {\r\n\r\n  private dataService: DataService;\r\n  private savedStaffBasicPages: { [pageNumber: number]: IStaffBasic[] } = {};\r\n  private maxNumberPageLinks = 5;\r\n  private resultsPerPage = 10;\r\n  private maxGroupLengthDisplayedInWideScreen = 20;\r\n  private maxGroupLengthDisplayedInNarrowScreen = 8;\r\n\r\n  public constructor(props: ISearchProps) {\r\n    super(props);\r\n\r\n    this.dataService = new DataService();\r\n    this.setInitialState();\r\n    this.bindCallbackFunctionsToThisComponent();\r\n  }\r\n\r\n  public componentDidMount() {\r\n    this.loadSettings();\r\n    this.handleResize();\r\n  }\r\n\r\n  // Callback methods:\r\n\r\n  public onSelectGroup(e): void {\r\n    const selectedGroupID = parseInt(e.target.value, 10);\r\n    this.setState({ selectedGroupID });\r\n  }\r\n\r\n  public onChangeSearchTerm(e): void {\r\n    const searchTerm = e.target.value;\r\n    this.setState({ searchTerm });\r\n  }\r\n\r\n  public onClickSearchButton(e): void {\r\n    this.savedStaffBasicPages = {}; // Clear saved search results.\r\n    this.setPage(1);\r\n    this.loadSearchResults();\r\n  }\r\n\r\n  public onClickResetButton(e): void {\r\n    e.nativeEvent.preventDefault();\r\n    this.savedStaffBasicPages = {};\r\n    const selectedGroupID = 0;\r\n    const searchTerm = \"\";\r\n    this.setPage(1);\r\n    this.setState({ selectedGroupID, searchTerm }, this.loadSearchResults);\r\n  }\r\n\r\n  public onClickMore(e: any, userID: number): void {\r\n    e.nativeEvent.preventDefault();\r\n    if (!this.state.staffMembersExtended[userID]) {\r\n      const groupIDs: number[] = [];\r\n      for (const g of this.state.settings.groups) {\r\n        groupIDs.push(g.groupID);\r\n      }\r\n      this.loadUserExtended(userID, groupIDs);\r\n    }\r\n    this.flipExpandedState(userID);\r\n  }\r\n\r\n  public onChangePage(pageNumber: number): void {\r\n    this.setPage(pageNumber);\r\n    this.loadSearchResults();\r\n  }\r\n\r\n  public onKeyDownCancelSubmit(e): void {\r\n    // We don't our form to submit when user hits Enter in the search term textbox.\r\n    if (e.key === \"Enter\") {\r\n      e.nativeEvent.preventDefault();\r\n      this.savedStaffBasicPages = {}; // Clear saved search results.\r\n      this.setPage(1);\r\n      this.loadSearchResults();\r\n    }\r\n  }\r\n\r\n  public render() {\r\n    let loadingText = \"Loading...\"; // Hard-code to English before internationalised text has been loaded.\r\n    if (this.state.settings.localization && this.state.settings.localization.loading) {\r\n      loadingText = this.state.settings.localization.loading;\r\n    }\r\n\r\n    return (\r\n\r\n      <div className=\"PO-wrapper PO-staffDirectory\">\r\n\r\n        <Errors errors={this.state.errors} errorMessage={this.state.settings.localization.errorMessage} />\r\n\r\n        {(!this.state.settingsLoaded) &&\r\n          <LargeLoadingSpinner loadingText={loadingText} />\r\n        }\r\n\r\n        {this.state.settingsLoaded &&\r\n          <div>\r\n            <SearchSettings\r\n              portletInstanceId={this.props.portletInstanceID}\r\n              localization={this.state.settings.localization}\r\n              selectedGroupID={this.state.selectedGroupID}\r\n              groups={this.state.settings.groups}\r\n              searchTerm={this.state.searchTerm}\r\n              searchByJobTitle={this.state.settings.searchByJobTitle}\r\n              maxTextLengthDisplayedForGroup = {this.state.maxTextLengthDisplayedForGroup}\r\n              onSelectGroup={this.onSelectGroup}\r\n              onChangeSearchTerm={this.onChangeSearchTerm}\r\n              onClickSearchButton={this.onClickSearchButton}\r\n              onClickResetButton={this.onClickResetButton}\r\n              onKeyDownCancelSubmit={this.onKeyDownCancelSubmit}\r\n            />\r\n\r\n            <SearchResults\r\n              portletInstanceId={this.props.portletInstanceID}\r\n              settings={this.state.settings}\r\n              staffMembersBasic={this.state.staffMembersBasic}\r\n              staffMembersExtended={this.state.staffMembersExtended}\r\n              totalNumberOfResults={this.state.totalNumberOfResults}\r\n              pagerSettings={this.state.pagerSettings}\r\n              searchResultsLoaded={this.state.searchResultsLoaded}\r\n              onClickMore={this.onClickMore}\r\n              onChangePage={this.onChangePage}\r\n            />\r\n          </div>\r\n        }\r\n      </div>\r\n\r\n    );\r\n  }\r\n\r\n  private bindCallbackFunctionsToThisComponent() {\r\n    // Event callback 'this' bindings:\r\n    this.onSelectGroup = this.onSelectGroup.bind(this);\r\n    this.onChangeSearchTerm = this.onChangeSearchTerm.bind(this);\r\n    this.onClickSearchButton = this.onClickSearchButton.bind(this);\r\n    this.onClickResetButton = this.onClickResetButton.bind(this);\r\n    this.onClickMore = this.onClickMore.bind(this);\r\n    this.onChangePage = this.onChangePage.bind(this);\r\n    this.onKeyDownCancelSubmit = this.onKeyDownCancelSubmit.bind(this);\r\n  }\r\n\r\n  private setInitialState() {\r\n    const settings: ISettings = new Settings(this.props.portletInstanceID);\r\n    const staffBasic: IStaffBasic[] = [];\r\n    const staffExtended: { [userID: number]: IStaffExtended } = {};\r\n    const pagerSettings: IPagerSettings = { currentPageNumber: 1, numberOfPageLinks: this.maxNumberPageLinks, resultsPerPage: this.resultsPerPage };\r\n\r\n    const settingsLoaded = false;\r\n    const searchResultsLoaded = false;\r\n    const selectedGroupID: number = 0;\r\n    const searchTerm = \"\";\r\n    const errors = [];\r\n    const totalNumberOfResults = 0;\r\n    const isLoadingSearchResults = true;\r\n    const maxTextLengthDisplayedForGroup = this.maxGroupLengthDisplayedInWideScreen;\r\n\r\n    this.state = {\r\n      settings,\r\n      staffMembersBasic: staffBasic,\r\n      staffMembersExtended: staffExtended,\r\n      pagerSettings,\r\n      totalNumberOfResults,\r\n      settingsLoaded,\r\n      searchResultsLoaded,\r\n      selectedGroupID,\r\n      searchTerm,\r\n      maxTextLengthDisplayedForGroup,\r\n      errors,\r\n    };\r\n  }\r\n\r\n  // API calls:\r\n\r\n  private loadSettings(): void {\r\n    const methodName = \"Settings\";\r\n\r\n    try {\r\n      this.dataService.settings(this.props.portletInstanceID).then((response) => {\r\n        this.setState({ settingsLoaded: true });\r\n\r\n        if (response.d !== undefined) {\r\n          response = response.d; // .NET service wraps response in a 'd' property.\r\n        }\r\n\r\n        if (response.error === \"\") {\r\n          // Response returned without error. Next, verify response is valid.\r\n          const settingsVerification = verifySettings(response);\r\n          if (settingsVerification.error === false) {\r\n            const settings: ISettings = response;\r\n            this.setState({ settings });\r\n\r\n            this.loadSearchResults();\r\n          } else {\r\n            this.displayResponseVerificationErrors(settingsVerification, methodName);\r\n          }\r\n        } else {\r\n          this.displayResponseErrors(response, methodName);\r\n        }\r\n\r\n      });\r\n    } catch (error) {\r\n      this.addError(methodName + \": Unhandled error: \" + error.message);\r\n    }\r\n  }\r\n\r\n  private loadSearchResults(): void {\r\n    const methodName = \"Search\";\r\n\r\n    const pageNumber: number = this.state.pagerSettings.currentPageNumber;\r\n\r\n    // Clear any errors.\r\n    const errors = new Array<string>();\r\n    this.setState({ errors });\r\n\r\n    // Check if this page of results are already saved in client memory; if so, use that data.\r\n    if (this.savedStaffBasicPages[pageNumber] !== undefined) {\r\n      const savedPage = this.savedStaffBasicPages[pageNumber];\r\n      for (const s of savedPage) { s.expanded = false; }\r\n      this.setState({ staffMembersBasic: savedPage });\r\n      this.setState({ searchResultsLoaded: true });\r\n    } else {\r\n      // Haven't requested this page of results yet; ask the API for the page.\r\n      try {\r\n        this.setState({ searchResultsLoaded: false });\r\n\r\n        const portletInstanceId: number = this.props.portletInstanceID;\r\n        const groupIDs: number[] = this.getSelectedGroupIDs();\r\n        const searchTerm: string = this.state.searchTerm;\r\n        const sortOrder: string = this.state.settings.sortOrder;\r\n        const searchByJobTitle: boolean = this.state.settings.searchByJobTitle;\r\n\r\n        const firstRecord: number = ((this.state.pagerSettings.currentPageNumber - 1) * this.state.pagerSettings.resultsPerPage);\r\n        const lastRecord: number = firstRecord + (this.state.pagerSettings.resultsPerPage - 1);\r\n\r\n        this.dataService.search(portletInstanceId, groupIDs, sortOrder, searchTerm, firstRecord, lastRecord, searchByJobTitle).then((response) => {\r\n          this.setState({ searchResultsLoaded: true });\r\n\r\n          if (response.d !== undefined) {\r\n            response = response.d; // .NET service wraps response in a 'd' property.\r\n          }\r\n\r\n          if (response.error === \"\") {\r\n            // Response returned without error. Next, verify response is valid.\r\n            const searchResultsVerification = verifyStaffBasicArray(response.results);\r\n            if (searchResultsVerification.error === false) {\r\n\r\n              // Get returned page of staff members from reponse.\r\n              const pageOfStaffMembersBasic: IStaffBasic[] = response.results;\r\n              for (const smb of pageOfStaffMembersBasic) { smb.expanded = false; } // Add an Expanded=\"false\" property to each staff member; toggled when \"More...\" clicked.\r\n\r\n              // Add page of staff members to local memory.\r\n              this.savedStaffBasicPages[pageNumber] = pageOfStaffMembersBasic;\r\n\r\n              // Set total number of results.\r\n              const totalNumberOfResults = response.totalNumberOfResults;\r\n\r\n              // Update state.\r\n              this.setState({ staffMembersBasic: pageOfStaffMembersBasic, totalNumberOfResults });\r\n            } else {\r\n              this.displayResponseVerificationErrors(searchResultsVerification, methodName);\r\n            }\r\n          } else {\r\n            this.displayResponseErrors(response, methodName);\r\n          }\r\n\r\n        });\r\n      } catch (error) {\r\n        this.addError(methodName + \": Unhandled error: \" + error.message);\r\n      }\r\n    }\r\n  }\r\n\r\n  private loadUserExtended(userID: number, groupIds: number[]): void {\r\n    const methodName = \"UserExtended\";\r\n    const portletInstanceId: number = this.props.portletInstanceID;\r\n\r\n    // Clear any errors.\r\n    const errors = new Array<string>();\r\n    this.setState({ errors });\r\n\r\n    try {\r\n      this.dataService.userExtended(portletInstanceId, userID, groupIds).then((response) => {\r\n\r\n        if (response.d !== undefined) {\r\n          response = response.d; // .NET service wraps response in a 'd' property.\r\n        }\r\n\r\n        if (response.error === \"\") {\r\n          // Response returned without error. Next, verify response is valid.\r\n          const staffExtendedVerification = verifyStaffExtended(response.result, userID);\r\n          if (staffExtendedVerification.error === false) {\r\n            const staffMembersExtended = this.state.staffMembersExtended;\r\n            staffMembersExtended[userID] = response.result;\r\n            this.setState({ staffMembersExtended });\r\n          } else {\r\n            this.displayResponseVerificationErrors(staffExtendedVerification, methodName);\r\n          }\r\n        } else {\r\n          this.displayResponseErrors(response, methodName);\r\n        }\r\n      });\r\n    } catch (error) {\r\n      this.addError(methodName + \": Unhandled error: \" + error.message);\r\n    }\r\n  }\r\n\r\n  private displayResponseErrors(response: any, methodName: string): void {\r\n    // Error occurred in response, or error property is missing.\r\n    if (response.hasOwnProperty(\"error\")) {\r\n      this.addError(methodName + \": Error in response: \" + response.error);\r\n    } else {\r\n      this.addError(methodName + \": Response is missing the expected 'error' property.\");\r\n    }\r\n  }\r\n\r\n  private displayResponseVerificationErrors(verificationResult: IInterfaceCheckResult, methodName: string): void {\r\n    for (const error of verificationResult.details) {\r\n      this.addError(methodName + \": \" + error);\r\n    }\r\n  }\r\n\r\n  private getSelectedGroupIDs(): number[] {\r\n    let groupIDs: number[] = [];\r\n    if (this.state.selectedGroupID === 0) {\r\n      groupIDs = this.state.settings.groups.map((g) => g.groupID);\r\n    } else {\r\n      groupIDs = [this.state.selectedGroupID];\r\n    }\r\n    return groupIDs;\r\n  }\r\n\r\n  private addError(error: string) {\r\n    const errors = this.state.errors;\r\n    errors.push(error);\r\n    this.setState({ errors });\r\n  }\r\n\r\n  // Utility methods:\r\n\r\n  private flipExpandedState(userID: number): void {\r\n    const staffMembersBasic = this.state.staffMembersBasic;\r\n    const staffMemberBasic = this.state.staffMembersBasic.filter((s) => s.userID.toString() === userID.toString())[0];\r\n    staffMemberBasic.expanded = !(staffMemberBasic.expanded);\r\n    this.setState({ staffMembersBasic });\r\n  }\r\n\r\n  private setPage(pageNumber: number) {\r\n    const pagerSettings = this.state.pagerSettings;\r\n    pagerSettings.currentPageNumber = pageNumber;\r\n    this.setState({ pagerSettings });\r\n  }\r\n\r\n  private setNumberPageLinks(numPageLinks: number) {\r\n    const pagerSettings = this.state.pagerSettings;\r\n    pagerSettings.numberOfPageLinks = numPageLinks;\r\n    this.setState({ pagerSettings });\r\n  }\r\n\r\n  private setMaxGroupsLengthDisplayed(maxLength: number) {\r\n    this.setState({ maxTextLengthDisplayedForGroup: maxLength });\r\n  }\r\n\r\n  private handleResize() {\r\n\r\n    // Using JQuery for this... not ideal.\r\n\r\n    /* tslint:disable */\r\n\r\n    const that = this;\r\n    const minNumPageLinks = 1;\r\n    const maxNumPageLinks = this.maxNumberPageLinks;\r\n    const maxGroupLengthDisplayedInWideScreen = this.maxGroupLengthDisplayedInWideScreen;\r\n    const maxGroupLengthDisplayedInNarrowScreen = this.maxGroupLengthDisplayedInNarrowScreen;\r\n\r\n    $(window).on(\"resize\", () => {\r\n\r\n      // Adjust staff directory width.\r\n      $('.PO-wrapper').each(function () {\r\n        const portletWidth = $(this).width();\r\n\r\n        if (portletWidth < 525) {\r\n          $(this).addClass('PO-mobileView');\r\n          that.setMaxGroupsLengthDisplayed(maxGroupLengthDisplayedInNarrowScreen);\r\n        }\r\n        else {\r\n          $(this).removeClass('PO-mobileView');\r\n         that.setMaxGroupsLengthDisplayed(maxGroupLengthDisplayedInWideScreen);\r\n        }\r\n\r\n      });\r\n\r\n      // Adjust number of links displayed in paginator, depending on width.\r\n      $('.PO-paging').each(function () {\r\n        const pagerWidth = $(this).width();\r\n        let availWidthForPageLinks = pagerWidth;\r\n\r\n        availWidthForPageLinks = Math.floor(availWidthForPageLinks - (33.34 + 32 + 32 + 34.34)); // Take off the width used by the < ... ... > controls.\r\n        availWidthForPageLinks = availWidthForPageLinks - 20; // Take off the 10px padding on each side.\r\n\r\n        let pageLinkWidth = 28; // 1 digit page link width.\r\n        const currentPageNumber = that.state.pagerSettings.currentPageNumber;\r\n        if( currentPageNumber > 9) { // 2 digit page link width.\r\n          pageLinkWidth = 36;\r\n        }\r\n        if( currentPageNumber > 99) { // 3 digit page link width.\r\n          pageLinkWidth = 44;\r\n        }\r\n\r\n        let numPageLinks = Math.round(availWidthForPageLinks / pageLinkWidth);\r\n        numPageLinks = Math.min(numPageLinks, maxNumPageLinks);\r\n        numPageLinks = Math.max(numPageLinks, minNumPageLinks);\r\n\r\n        that.setNumberPageLinks(numPageLinks);\r\n\r\n        // console.log(\"pagerWidth: \" + pagerWidth + \", availWidthForPageLinks: \" + availWidthForPageLinks + \", numPageLinks = \" + numPageLinks);\r\n      });\r\n\r\n    }).resize();\r\n\r\n    /* tslint:enable */\r\n  }\r\n\r\n}\r\n","import { EnviroConfig } from \"../../EnviroConfig\";\r\n\r\nimport { IAPI, ISettings, IStaffBasic, IStaffExtended } from \"../IStaffDirectorySearch\";\r\n\r\nimport { Group } from \"../classes/Group\";\r\nimport { Settings } from \"../classes/Settings\";\r\nimport { SocialMediaLink } from \"../classes/SocialMediaLink\";\r\nimport { StaffBasic } from \"../classes/StaffBasic\";\r\nimport { StaffExtended } from \"../classes/StaffExtended\";\r\n\r\nexport class DataService {\r\n\r\n  public settings(portletInstanceId: number): any {\r\n    const url = \"Settings\";\r\n\r\n    const searchParams = { portletInstanceId };\r\n    const body = JSON.stringify(searchParams);\r\n\r\n    return this.callFetch(url, body);\r\n  }\r\n\r\n  public search(portletInstanceId: number, groupIds: number[], sortOrder: string, searchTerm: string, firstRecord: number, lastRecord: number, searchByJobTitle: boolean): any {\r\n    const url = \"Search\";\r\n\r\n    const searchParams = { firstRecord, groupIds, lastRecord, portletInstanceId, searchTerm, sortOrder, searchByJobTitle };\r\n    const body = JSON.stringify(searchParams);\r\n\r\n    return this.callFetch(url, body);\r\n  }\r\n\r\n  public userExtended(portletInstanceId: number, userId: number, groupIds: number[]): any {\r\n    const url = \"userExtended\";\r\n\r\n    const searchParams = { portletInstanceId, userId: userId.toString(), groupIds };\r\n    const body = JSON.stringify(searchParams);\r\n\r\n    return this.callFetch(url, body);\r\n  }\r\n\r\n  private callFetch(url: string, body: string): Promise<Response> {\r\n\r\n    const headers = new Headers();\r\n    headers.append(\"Accept\", \"application/json, text/javascript, */*; q=0.01\");\r\n    headers.append(\"Content-Type\", \"application/json; charset=UTF-8\");\r\n\r\n    const config = new EnviroConfig();\r\n    const baseURL =  config.staffDirServiceURL;\r\n\r\n    return fetch(baseURL + url, { method: \"POST\", headers, body, credentials: \"same-origin\" }).then((response) => {\r\n      let result: any = {};\r\n      if (response.ok) {\r\n        result = response.json();\r\n      } else {\r\n        result.error = url + \": \" + response.statusText;\r\n      }\r\n      return result;\r\n    }).catch((error) => {\r\n      const result: any = {};\r\n      result.error = error;\r\n      return url + \": \" + result;\r\n    });\r\n  }\r\n\r\n}\r\n","import * as React from \"react\";\r\n\r\nexport interface IErrorsProps {\r\n  errors: string[];\r\n  errorMessage: string;\r\n}\r\n\r\nexport const Errors = (props: IErrorsProps) => {\r\n\r\n  props.errors.map((error, i) => {\r\n    console.log(error); // tslint:disable-line\r\n  });\r\n\r\n  return (\r\n    <div>\r\n      {props.errors.length > 0 &&\r\n        <div className=\"PO-contentArea\">\r\n          <ul className=\"DIR-userList\">\r\n            <li className=\"DIR-item DIR-noResults DIR-error\">\r\n              <div className=\"DIR-card\">\r\n                <div className=\"DIR-cardInfo\">\r\n                  <p>{props.errorMessage}</p>\r\n                </div>\r\n              </div>\r\n            </li>\r\n          </ul>\r\n        </div>\r\n      }\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { IPagerSettings, ISettings, IStaffBasic, IStaffExtended } from \"./IStaffDirectorySearch\";\r\n\r\nimport PaginatorComponent from \"../common/paginator/paginatorComponent\";\r\nimport { BlankSearchResults } from \"./BlankSearchResults\";\r\nimport { NoSearchResults } from \"./NoSearchResults\";\r\nimport { StaffBasic } from \"./StaffBasic\";\r\n\r\nexport interface ISearchResultsProps {\r\n  portletInstanceId: number;\r\n  settings: ISettings;\r\n  staffMembersBasic: IStaffBasic[];\r\n  staffMembersExtended: { [userID: number]: IStaffExtended };\r\n  totalNumberOfResults: number;\r\n  pagerSettings: IPagerSettings;\r\n  searchResultsLoaded: boolean;\r\n  onClickMore: (event: any, userID: number) => any;\r\n  onChangePage: (pageNumber: number) => any;\r\n}\r\n\r\nexport const SearchResults = (props: ISearchResultsProps) => {\r\n\r\n  const textCurrentlyDisplayingPageText = props.settings.localization.currentlyDisplayingPage;\r\n  const textDisplayPageText = props.settings.localization.displayPage;\r\n  const textDisplayPreviousPageOfResults = props.settings.localization.displayPreviousPageOfResults;\r\n  const textDisplayPreviousSetOfPageLinks = props.settings.localization.displayPreviousSetOfPageLinks;\r\n  const textDisplayNextPageOfResults = props.settings.localization.displayNextPageOfResults;\r\n  const textDisplayNextSetOfPageLinks = props.settings.localization.displayNextSetOfPageLinks;\r\n  const textNoNextPageOfResults = props.settings.localization.noNextPageOfResults;\r\n  const textNoNextSetOfPageLinks = props.settings.localization.noNextSetOfPageLinks;\r\n  const textNoPreviousPageOfResults = props.settings.localization.noPreviousPageOfResults;\r\n  const textNoPreviousSetOfPageLinks = props.settings.localization.noPreviousSetOfPageLinks;\r\n  const textOf = props.settings.localization.of;\r\n  const textOfResultsText = props.settings.localization.ofResults;\r\n  const textNoResultsFoundText = props.settings.localization.noResultsFound;\r\n  const textLoading = props.settings.localization.loading;\r\n\r\n  function getStaffMemberExtended(userID: number): IStaffExtended {\r\n    if (props.staffMembersExtended) {\r\n      if (props.staffMembersExtended[userID]) {\r\n        return props.staffMembersExtended[userID];\r\n      } else {\r\n        return null;\r\n      }\r\n    } else {\r\n      return null;\r\n    }\r\n  }\r\n\r\n  return (\r\n\r\n    <div>\r\n\r\n      {!props.searchResultsLoaded &&\r\n        <BlankSearchResults numberOfBlankResults={props.pagerSettings.resultsPerPage} loadingText={textLoading} />\r\n      }\r\n\r\n      {props.searchResultsLoaded && props.totalNumberOfResults >= 1 &&\r\n        <div className=\"PO-contentArea\">\r\n          <ul className=\"DIR-userList\" role=\"presentation\">\r\n            {props.staffMembersBasic.map((staff, i) => {\r\n              return (\r\n                <StaffBasic\r\n                  settings={props.settings}\r\n                  staffBasic={staff}\r\n                  staffExtended={getStaffMemberExtended(staff.userID)}\r\n                  localization={props.settings.localization}\r\n                  key={staff.userID}\r\n                  onClickMore={props.onClickMore}\r\n                />);\r\n            })}\r\n          </ul>\r\n        </div>\r\n      }\r\n\r\n      {props.searchResultsLoaded && props.totalNumberOfResults < 1 &&\r\n        <NoSearchResults noSearchResultsText={textNoResultsFoundText} />\r\n      }\r\n\r\n      < PaginatorComponent\r\n        totalNumberOfRecords={props.totalNumberOfResults}\r\n        recordsPerPage={props.pagerSettings.resultsPerPage}\r\n        numberOfPageLinks={props.pagerSettings.numberOfPageLinks}\r\n        currentPageNumber={props.pagerSettings.currentPageNumber}\r\n\r\n        text_currentlyDisplayingPage={textCurrentlyDisplayingPageText}\r\n        text_displayPage={textDisplayPageText}\r\n        text_displayPreviousPageOfResults={textDisplayPreviousPageOfResults}\r\n        text_displayPreviousSetOfPageLinks={textDisplayPreviousSetOfPageLinks}\r\n        text_displayNextPageOfResults={textDisplayNextPageOfResults}\r\n        text_displayNextSetOfPageLinks={textDisplayNextSetOfPageLinks}\r\n\r\n        text_noNextPageOfResults={textNoNextPageOfResults}\r\n        text_noNextSetOfPageLinks={textNoNextSetOfPageLinks}\r\n        text_noPreviousPageOfResults={textNoPreviousPageOfResults}\r\n        text_noPreviousSetOfPageLinks={textNoPreviousSetOfPageLinks}\r\n\r\n        text_of={textOf}\r\n        text_ofResultsText={textOfResultsText}\r\n\r\n        onChangePage={props.onChangePage}\r\n      />\r\n\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nexport interface IBlankSearchResultsProps {\r\n  numberOfBlankResults: number;\r\n  loadingText: string;\r\n}\r\n\r\nexport const BlankSearchResults = (props: IBlankSearchResultsProps) => {\r\n\r\n  const rows: JSX.Element[] = [];\r\n  for (let i = 0; i < props.numberOfBlankResults; i++) {\r\n    rows.push(\r\n      <li className=\"DIR-item DIR-loadItem\" key={i} title={props.loadingText}>\r\n        <div className=\"DIR-card\">\r\n          <div className=\"DIR-photo DIR-noPhoto\" aria-hidden=\"true\">\r\n            <em></em>\r\n          </div>\r\n          <div className=\"DIR-cardInfo\">\r\n            <ul>\r\n              <li className=\"DIR-name\"></li>\r\n              <li className=\"DIR-title\"></li>\r\n              <li className=\"DIR-quickLinks\">\r\n                <div className=\"DIR-quickButtons\">\r\n                  <ul>\r\n                    <li><a></a></li>\r\n                    <li><a></a></li>\r\n                    <li><a></a></li>\r\n                  </ul>\r\n                </div>\r\n              </li>\r\n            </ul>\r\n          </div>\r\n        </div>\r\n      </li>,\r\n    );\r\n  }\r\n\r\n  return (\r\n    <ul className=\"DIR-userList\">\r\n      {rows}\r\n    </ul>\r\n  );\r\n\r\n};\r\n","import * as React from \"react\";\r\n\r\nexport interface INoSearchResultsProps {\r\n  noSearchResultsText: string;\r\n}\r\n\r\nexport const NoSearchResults = (props: INoSearchResultsProps) => {\r\n  return (\r\n    <div className=\"PO-contentArea\">\r\n      <ul className=\"DIR-userList\" role=\"presentation\">\r\n        <li className=\"DIR-item DIR-noResults\" role=\"presentation\">\r\n          <div className=\"DIR-card\">\r\n            <div className=\"DIR-cardInfo\">\r\n              <ul role=\"presentation\">\r\n                <li className=\"DIR-name\" role=\"presentation\">{props.noSearchResultsText}</li>\r\n              </ul>\r\n            </div>\r\n          </div>\r\n        </li>\r\n      </ul>\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { ISettings, IStaffBasic, IStaffExtended } from \"./IStaffDirectorySearch\";\r\n\r\nimport { Name } from \"./Name\";\r\nimport { Photo } from \"./Photo\";\r\nimport { QuickLinks } from \"./QuickLinks\";\r\nimport { StaffExtended } from \"./StaffExtended\";\r\n\r\nexport interface IStaffBasicProps {\r\n  settings: ISettings;\r\n  staffBasic: IStaffBasic;\r\n  staffExtended: IStaffExtended;\r\n  localization: {};\r\n  onClickMore: (event: any, userId: number) => any;\r\n}\r\n\r\nexport const StaffBasic = (props: IStaffBasicProps) => {\r\n\r\n  let btnText = \"\";\r\n  let btnAriaText = \"\";\r\n  let btnClassName = \"DIR-openSlideout\";\r\n  let liClassName = \"DIR-item\";\r\n\r\n  const more = props.settings.localization.more;\r\n  const moreAria = props.settings.localization.moreAria;\r\n  const less = props.settings.localization.less;\r\n  const lessAria = props.settings.localization.lessAria;\r\n\r\n  if (props.staffBasic.expanded === false) {\r\n    btnText = more;\r\n    btnAriaText = moreAria + \" \" + props.staffBasic.firstName + \" \" + props.staffBasic.lastName;\r\n  } else {\r\n    btnText = less;\r\n    btnAriaText = lessAria + \" \" + props.staffBasic.firstName + \" \" + props.staffBasic.lastName;\r\n    btnClassName += \" DIR-active\";\r\n    liClassName += \" active\";\r\n  }\r\n\r\n  return (\r\n\r\n    <li className={liClassName} role=\"presentation\">\r\n      <div className=\"DIR-card\" aria-label={props.settings.localization.staffMember} role=\"group\">\r\n\r\n        <Photo imageURL={props.staffBasic.imageURL} firstName={props.staffBasic.firstName} lastName={props.staffBasic.lastName} />\r\n\r\n        <div className=\"DIR-cardInfo\">\r\n          <ul role=\"presentation\">\r\n\r\n            <Name firstName={props.staffBasic.firstName} lastName={props.staffBasic.lastName} sortOrder={props.settings.sortOrder} onlyShowFirstInitial={props.settings.onlyShowFirstInitial} />\r\n\r\n            <li className=\"DIR-title\" role=\"presentation\">{props.staffBasic.jobTitle}</li>\r\n\r\n            <li className=\"DIR-quickLinks\" role=\"presentation\">\r\n\r\n              <QuickLinks\r\n                website={props.staffBasic.website}\r\n                email={props.staffBasic.email}\r\n                useExternalEmailApp={props.settings.useExternalEmailApp}\r\n                phone={props.staffBasic.phone}\r\n                emailPrivacy={props.settings.emailPrivacy}\r\n                firstName={props.staffBasic.firstName}\r\n                mailUrl={props.staffBasic.mailUrl}\r\n                lastName={props.staffBasic.lastName}\r\n                userID={props.staffBasic.userID}\r\n                sortOrder={props.settings.sortOrder}\r\n                onlyShowFirstInitial={props.settings.onlyShowFirstInitial}\r\n                localization={props.settings.localization}\r\n              />\r\n\r\n            </li>\r\n\r\n          </ul>\r\n        </div>\r\n\r\n        <div className=\"DIR-more\">\r\n          <a className={btnClassName} href=\"#\" data-user-id={props.staffBasic.userID} onClick={(e) => props.onClickMore(e, props.staffBasic.userID)} aria-label={btnAriaText}>{btnText}</a>\r\n        </div>\r\n\r\n      </div>\r\n\r\n      <StaffExtended settings={props.settings} staffBasic={props.staffBasic} staffExtended={props.staffExtended} />\r\n\r\n    </li>\r\n\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { formatName } from \"./Utilities\";\r\n\r\nexport interface INameProps {\r\n  firstName: string;\r\n  lastName: string;\r\n  sortOrder: string;\r\n  onlyShowFirstInitial: boolean;\r\n}\r\n\r\nexport const Name = (props: INameProps) => {\r\n  const name = formatName(props.firstName, props.lastName, props.sortOrder, props.onlyShowFirstInitial);\r\n  return <li className=\"DIR-name\" role=\"presentation\">{name}</li>;\r\n};\r\n","import * as React from \"react\";\r\n\r\nexport interface IPhotoProps {\r\n  imageURL: string;\r\n  firstName: string;\r\n  lastName: string;\r\n}\r\n\r\nexport const Photo = (props: IPhotoProps) => {\r\n\r\n  let photoClass: string = \"DIR-photo\";\r\n  if (!props.imageURL || props.imageURL === \"\") {\r\n    photoClass += \" DIR-noPhoto\";\r\n  }\r\n\r\n  const backgroundImageStyle = { backgroundImage: \"url(\" + props.imageURL + \")\" };\r\n\r\n  let initials: string = \"\";\r\n\r\n  if (props.firstName.length > 0) {\r\n    initials += props.firstName[0];\r\n  }\r\n\r\n  if (props.lastName.length > 0) {\r\n    initials += props.lastName[0];\r\n  }\r\n\r\n  return (\r\n    <div className={photoClass} aria-hidden=\"true\">\r\n      <span style={backgroundImageStyle}></span>\r\n      <em>{initials}</em>\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { EmailStyle } from \"./IStaffDirectorySearch\";\r\n\r\nimport { Localization} from \"./classes/Localization\";\r\nimport { Email } from \"./Email\";\r\nimport { speakPhoneAsNumbers } from \"./Utilities\";\r\n\r\nexport interface IQuickLinksProps {\r\n  email: string;\r\n  emailPrivacy: boolean;\r\n  useExternalEmailApp: boolean;\r\n  website: string;\r\n  phone: string;\r\n  firstName: string;\r\n  mailUrl: string;\r\n  lastName: string;\r\n  userID: number;\r\n  sortOrder: string;\r\n  onlyShowFirstInitial: boolean;\r\n  localization: Localization;\r\n}\r\n\r\nexport const QuickLinks = (props: IQuickLinksProps) => {\r\n\r\n  const showWebsite: boolean = props.website !== \"\";\r\n  const showPhone: boolean = props.phone !== \"\";\r\n  const showEmail: boolean = props.email !== \"\";\r\n\r\n  const showQuickButtons: boolean = showWebsite || showPhone || showEmail;\r\n\r\n  const phoneLink = \"tel:\" + props.phone;\r\n  const ariaPhoneLink = props.localization.telephonePersonAt\r\n    .replace(\"{firstname}\", props.firstName)\r\n    .replace(\"{lastname}\", props.lastName)\r\n    .replace(\"{number}\", speakPhoneAsNumbers(props.phone));\r\n  const titleText = \"Go to \" + props.firstName + \" \" + props.lastName + \" Webpage\";\r\n\r\n  const websiteText = props.localization.website;\r\n\r\n  return (\r\n    <div>\r\n      {\r\n        showQuickButtons &&\r\n        <div className=\"DIR-quickButtons\">\r\n          <ul role=\"presentation\">\r\n            {showWebsite &&\r\n              <li role=\"presentation\"><a href={props.website} target=\"_blank\" title={titleText}><em className=\"fa fa-globe\" aria-hidden=\"true\"></em><span className=\"offScreen\">{websiteText + \" \" + props.website}</span></a></li>\r\n            }\r\n\r\n            <Email\r\n              style={EmailStyle.small}\r\n              email={props.email}\r\n              emailPrivacy={props.emailPrivacy}\r\n              useExternalEmailApp={props.useExternalEmailApp}\r\n              firstName={props.firstName}\r\n              mailUrl={props.mailUrl}\r\n              lastName={props.lastName}\r\n              userID={props.userID}\r\n              sortOrder={props.sortOrder}\r\n              onlyShowFirstInitial={props.onlyShowFirstInitial}\r\n              localization={props.localization}\r\n            />\r\n\r\n            {showPhone &&\r\n              <li role=\"presentation\">\r\n                <a href={phoneLink} aria-label={ariaPhoneLink}>\r\n                  <em className=\"fa fa-phone DIR-infoOption\" aria-hidden=\"true\"></em>\r\n                  <span>{props.phone}</span>\r\n                </a>\r\n              </li>\r\n            }\r\n          </ul>\r\n        </div>\r\n      }\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { ISettings, IStaffBasic, IStaffExtended } from \"./IStaffDirectorySearch\";\r\n\r\nimport { BioAndMessage } from \"./BioAndMessage\";\r\nimport { ContactInfo } from \"./ContactInfo\";\r\nimport { GroupsList } from \"./GroupsList\";\r\nimport { LargeLoadingSpinner } from \"./LargeLoadingSpinner\";\r\nimport { SecondaryInfo } from \"./SecondaryInfo\";\r\nimport { SocialMediaLinks } from \"./SocialMediaLinks\";\r\n\r\nexport interface IStaffExtendedProps {\r\n  settings: ISettings;\r\n  staffBasic: IStaffBasic;\r\n  staffExtended: IStaffExtended;\r\n}\r\n\r\nexport const StaffExtended = (props: IStaffExtendedProps) => {\r\n\r\n  const loadingText = props.settings.localization.loading;\r\n\r\n  return (\r\n\r\n    <div>\r\n\r\n      {props.staffExtended === null && props.staffBasic.expanded &&\r\n        <LargeLoadingSpinner loadingText={loadingText} />\r\n      }\r\n\r\n      {props.staffExtended != null && props.staffBasic.expanded &&\r\n        <div className=\"DIR-slideOut DIR-active\">\r\n\r\n          <ContactInfo\r\n            phone={props.staffBasic.phone}\r\n            email={props.staffBasic.email}\r\n            emailPrivacy={props.settings.emailPrivacy}\r\n            useExternalEmailApp={props.settings.useExternalEmailApp}\r\n            website={props.staffBasic.website}\r\n            blog={props.staffExtended.blog}\r\n            firstName={props.staffBasic.firstName}\r\n            mailUrl={props.staffBasic.mailUrl}\r\n            lastName={props.staffBasic.lastName}\r\n            userID={props.staffBasic.userID}\r\n            sortOrder={props.settings.sortOrder}\r\n            onlyShowFirstInitial={props.settings.onlyShowFirstInitial}\r\n            localization={props.settings.localization}\r\n          />\r\n\r\n          <SocialMediaLinks socialMediaLinks={props.staffExtended.socialMediaLinks} />\r\n\r\n          <GroupsList groups={props.settings.groups} groupIDs={props.staffExtended.groupIDs} />\r\n\r\n          <SecondaryInfo\r\n            room={props.staffExtended.room}\r\n            grades={props.staffExtended.grades}\r\n            subjects={props.staffExtended.subjects}\r\n            officeHours={props.staffExtended.officeHours}\r\n            localization={props.settings.localization}\r\n          />\r\n\r\n          <BioAndMessage\r\n            biography={props.staffExtended.biography}\r\n            personalMessage={props.staffExtended.personalMessage}\r\n            localization={props.settings.localization}\r\n          />\r\n\r\n        </div>\r\n      }\r\n    </div>\r\n\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { Localization } from \"./classes/Localization\";\r\n\r\nexport interface IBioAndMessageProps {\r\n  biography: string;\r\n  personalMessage: string;\r\n  localization: Localization;\r\n}\r\n\r\nexport const BioAndMessage = (props: IBioAndMessageProps) => {\r\n\r\n  const showBioOrMessage: boolean = props.biography !== \"\" || props.personalMessage !== \"\";\r\n\r\n  return (\r\n    <div>\r\n      {showBioOrMessage &&\r\n        <div className=\"DIR-message\">\r\n          {props.biography !== \"\" &&\r\n            <div className=\"DIR-biography\">\r\n              <div className=\"DIR-mTitle\">{props.localization.biography}</div>\r\n              <div className=\"DIR-mContent\">\r\n                <p>{props.biography}</p>\r\n              </div>\r\n            </div>\r\n          }\r\n          {props.personalMessage !== \"\" &&\r\n            <div className=\"DIR-personalMessage\">\r\n              <div className=\"DIR-mTitle\">{props.localization.personalMessage}</div>\r\n              <div className=\"DIR-mContent\" >\r\n                <p dangerouslySetInnerHTML={{ __html: props.personalMessage }}></p>\r\n              </div>\r\n            </div>\r\n          }\r\n        </div>\r\n      }\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { EmailStyle } from \"./IStaffDirectorySearch\";\r\n\r\nimport { Localization } from \"./classes/Localization\";\r\nimport { Email } from \"./Email\";\r\nimport { speakPhoneAsNumbers } from \"./Utilities\";\r\n\r\nexport interface IContactInfoProps {\r\n  phone: string;\r\n  website: string;\r\n  email: string;\r\n  emailPrivacy: boolean;\r\n  useExternalEmailApp: boolean;\r\n  blog: string;\r\n  firstName: string;\r\n  mailUrl: string;\r\n  lastName: string;\r\n  userID: number;\r\n  sortOrder: string;\r\n  onlyShowFirstInitial: boolean;\r\n  localization: Localization;\r\n}\r\n\r\nexport const ContactInfo = (props: IContactInfoProps) => {\r\n\r\n  const showPhone: boolean = props.phone !== \"\";\r\n  const showEmail: boolean = props.email !== \"\";\r\n  const showWebsite: boolean = props.website !== \"\";\r\n  const showBlog: boolean = props.blog !== \"\";\r\n  const showContactInfo: boolean = showPhone || showEmail || showWebsite || showBlog;\r\n\r\n  const phoneLink = \"tel:\" + props.phone;\r\n  const ariaPhoneLink = props.localization.telephonePersonAt\r\n    .replace(\"{firstname}\", props.firstName)\r\n    .replace(\"{lastname}\", props.lastName)\r\n    .replace(\"{number}\", speakPhoneAsNumbers(props.phone));\r\n\r\n  return (\r\n    <div>\r\n      {showContactInfo &&\r\n        <div className=\"DIR-contactInfo\">\r\n          <ul role=\"presentation\">\r\n            {showPhone &&\r\n              <li role=\"presentation\"><a className=\"DIR-contactButton\" href={phoneLink} aria-label={ariaPhoneLink}><em className=\"fa fa-phone\" aria-hidden=\"true\"></em>{props.phone}</a></li>\r\n            }\r\n            {showEmail &&\r\n              <Email\r\n                style={EmailStyle.medium}\r\n                email={props.email}\r\n                emailPrivacy={props.emailPrivacy}\r\n                useExternalEmailApp={props.useExternalEmailApp}\r\n                firstName={props.firstName}\r\n                mailUrl={props.mailUrl}\r\n                lastName={props.lastName}\r\n                userID={props.userID}\r\n                sortOrder={props.sortOrder}\r\n                onlyShowFirstInitial={props.onlyShowFirstInitial}\r\n                localization={props.localization}\r\n              />\r\n            }\r\n            {showWebsite &&\r\n              <li role=\"presentation\"><a className=\"DIR-contactButton\" href={props.website} target=\"_blank\" title={props.website} aria-label={props.localization.mywebsite + \" \" + props.website}><em className=\"fa fa-globe\" aria-hidden=\"true\"></em>{props.localization.mywebsite}</a></li>\r\n            }\r\n            {showBlog &&\r\n              <li role=\"presentation\"><a className=\"DIR-contactButton\" href={props.blog} target=\"_blank\" title={props.blog} aria-label={props.localization.myblog + \" \" + props.blog}><em className=\"fa fa-comments\" aria-hidden=\"true\"></em>{props.localization.myblog}</a></li>\r\n            }\r\n          </ul>\r\n        </div>\r\n      }\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { IGroup } from \"./IStaffDirectorySearch\";\r\n\r\nexport interface IGroupsListProps {\r\n  groupIDs: number[];\r\n  groups: IGroup[];\r\n}\r\n\r\nexport const GroupsList = (props: IGroupsListProps) => {\r\n\r\n  const groupNames: string[] = [];\r\n\r\n  // Match the group IDs for the user against the list of groups that we display in the Groups dropdown. Only include those.\r\n  for (const groupID of props.groupIDs) {\r\n    if (props.groups.filter((g) => g.groupID === groupID)[0] !== undefined) {\r\n      const groupName = props.groups.filter((g) => g.groupID === groupID)[0].name;\r\n      groupNames.push(groupName);\r\n    }\r\n  }\r\n\r\n  // Sort the names.\r\n  groupNames.sort((a, b) => {\r\n    if (a < b) { return -1; }\r\n    if (a > b) { return 1; }\r\n    return 0;\r\n  });\r\n\r\n  // Build the list items.\r\n  const groupItems: JSX.Element[] = [];\r\n  let i: number = 0;\r\n  for (const groupName of groupNames) {\r\n    groupItems.push(<li key={i}>{groupName}</li>);\r\n    i++;\r\n  }\r\n\r\n  return (\r\n    <div>\r\n      {groupNames.length > 0 &&\r\n        <div className=\"DIR-groups\">\r\n          <ul role=\"presentation\">\r\n            <li className=\"DIR-groupsTitle\" role=\"presentation\">Groups:&nbsp;</li>\r\n            {groupItems}\r\n          </ul>\r\n        </div>\r\n      }\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { Localization } from \"./classes/Localization\";\r\n\r\nexport interface ISecondaryInfoProps {\r\n  room: string;\r\n  subjects: string;\r\n  grades: string;\r\n  officeHours: string;\r\n  localization: Localization;\r\n}\r\n\r\nexport const SecondaryInfo = (props: ISecondaryInfoProps) => {\r\n\r\n  const showSecondaryInfo: boolean = props.room !== \"\" || props.subjects !== \"\" || props.grades !== \"\" || props.officeHours !== \"\";\r\n\r\n  const roomText = props.localization.room;\r\n  const subjectsTaughtText = props.localization.subjectsTaught;\r\n  const gradesTaughtText = props.localization.gradesTaught;\r\n  const officeHoursText = props.localization.officeHours;\r\n\r\n  return (\r\n    <div>\r\n      {showSecondaryInfo &&\r\n        <div className=\"DIR-secondaryInfo\">\r\n          <ul role=\"presentation\">\r\n            {props.room !== \"\" &&\r\n              <li role=\"presentation\"><span>{roomText}:</span> {props.room}</li>\r\n            }\r\n            {props.subjects !== \"\" &&\r\n              <li role=\"presentation\"><span>{subjectsTaughtText}:</span> {props.subjects}</li>\r\n            }\r\n            {props.grades !== \"\" &&\r\n              <li role=\"presentation\"><span>{gradesTaughtText}:</span> {props.grades}</li>\r\n            }\r\n            {props.officeHours !== \"\" &&\r\n              <li role=\"presentation\"><span>{officeHoursText}:</span> {props.officeHours}</li>\r\n            }\r\n          </ul>\r\n        </div>\r\n      }</div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { ISocialMediaLink } from \"./IStaffDirectorySearch\";\r\nimport { SocialMediaLink } from \"./SocialMediaLink\";\r\n\r\nexport interface ISocialMediaLinksProps {\r\n  socialMediaLinks: ISocialMediaLink[];\r\n}\r\n\r\nexport const SocialMediaLinks = (props: ISocialMediaLinksProps) => {\r\n  return (\r\n    <div>\r\n      {props.socialMediaLinks.length > 0 &&\r\n        <div className=\"DIR-media\">\r\n          <ul role=\"presentation\">\r\n            {props.socialMediaLinks.map((smLink, i) => {\r\n              return <SocialMediaLink name={smLink.name} website={smLink.website} key={i} />;\r\n            })}\r\n          </ul>\r\n        </div>\r\n      }\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nexport interface ISocialMediaLinkProps {\r\n  name: string;\r\n  website: string;\r\n}\r\n\r\nexport const SocialMediaLink = (props: ISocialMediaLinkProps) => {\r\n\r\n  let link: any = null;\r\n\r\n  switch (props.name.toLowerCase()) {\r\n    case \"facebook\":\r\n      link = <li role=\"presentation\"><a className=\"DIR-mediaButton\" href={props.website} target=\"_blank\"><span className=\"DIR-facebook\"><em className=\"fa fa-facebook\" aria-hidden=\"true\"><span className=\"DIR-mText\">Facebook</span></em></span>Facebook</a></li>;\r\n      break;\r\n    case \"twitter\":\r\n      link = <li role=\"presentation\"><a className=\"DIR-mediaButton\" href={props.website} target=\"_blank\"><span className=\"DIR-twitter\"><em className=\"fa fa-twitter\" aria-hidden=\"true\"><span className=\"DIR-mText\">Twitter</span></em></span>Twitter</a></li>;\r\n      break;\r\n    case \"youtube\":\r\n      link = <li role=\"presentation\"><a className=\"DIR-mediaButton\" href={props.website} target=\"_blank\"><span className=\"DIR-youtube\"><em className=\"fa fa-youtube-play\" aria-hidden=\"true\"><span className=\"DIR-mText\">YouTube</span></em></span>YouTube</a></li>;\r\n      break;\r\n    case \"linkedin\":\r\n      link = <li role=\"presentation\"><a className=\"DIR-mediaButton\" href={props.website} target=\"_blank\"><span className=\"DIR-linkedin\"><em className=\"fa fa-linkedin\" aria-hidden=\"true\"><span className=\"DIR-mText\">LinkedIn</span></em></span>LinkedIn</a></li>;\r\n      break;\r\n    case \"google+\":\r\n      link = <li role=\"presentation\"><a className=\"DIR-mediaButton\" href={props.website} target=\"_blank\"><span className=\"DIR-googleplus\"><em className=\"fa fa-google-plus\" aria-hidden=\"true\"><span className=\"DIR-mText\">Google+</span></em></span>Google+</a></li>;\r\n      break;\r\n    default:\r\n      link = <li role=\"presentation\"><a className=\"DIR-mediaButton\" href={props.website} target=\"_blank\"><span className=\"DIR-default\"><em className=\"fa fa-external-link\" aria-hidden=\"true\"><span className=\"DIR-mText\">{props.name}</span></em></span>{props.name}</a></li>;\r\n      break;\r\n  }\r\n\r\n  return (\r\n    link\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { IGroup } from \"./IStaffDirectorySearch\";\r\n\r\nimport { GroupsDropdown } from \"./GroupsDropdown\";\r\nimport { ResetButton } from \"./ResetButton\";\r\nimport { SearchButton } from \"./SearchButton\";\r\nimport { SearchTerm } from \"./SearchTerm\";\r\nimport { nullCheck } from \"./Utilities\";\r\n\r\nimport { Localization } from \"./classes/Localization\";\r\n\r\nexport interface ISearchSettingsProps {\r\n  portletInstanceId: number;\r\n  localization: Localization;\r\n  selectedGroupID: number;\r\n  groups: IGroup[];\r\n  searchTerm: string;\r\n  searchByJobTitle: boolean;\r\n  maxTextLengthDisplayedForGroup: number;\r\n  onSelectGroup: (event: any) => any;\r\n  onChangeSearchTerm: (event: any) => any;\r\n  onClickSearchButton: (event: any) => any;\r\n  onClickResetButton: (event: any) => any;\r\n  onKeyDownCancelSubmit: (event: any) => any;\r\n}\r\n\r\nexport const SearchSettings = (props: ISearchSettingsProps) => {\r\n\r\n  let placeholder = \"\";\r\n  let placeholderAria = \"\";\r\n  if (props.searchByJobTitle === true) {\r\n    placeholder = props.localization.searchTermPlaceHolder;\r\n    placeholderAria = props.localization.searchTermPlaceHolderAria;\r\n  } else {\r\n    placeholder = props.localization.searchTermPlaceHolder_NameOnly;\r\n    placeholderAria = props.localization.searchTermPlaceHolderAria_NameOnly;\r\n  }\r\n\r\n  const searchText = props.localization.searchText;\r\n  const resetText = props.localization.resetText;\r\n\r\n  return (\r\n    <div>\r\n      {props.groups.length > 0 &&\r\n        <div className=\"PO-controlsTop\">\r\n\r\n          <div className=\"PO-search\">\r\n\r\n            {props.groups.length > 1 &&\r\n              <GroupsDropdown selectedGroupID={props.selectedGroupID} groups={props.groups} onSelectGroup={props.onSelectGroup} localization={props.localization} maxTextLengthDisplayed={props.maxTextLengthDisplayedForGroup} />\r\n            }\r\n\r\n            <div className=\"nav-fill\">\r\n\r\n              <SearchTerm placeholder={placeholder} placeholderAria={placeholderAria} searchTerm={props.searchTerm} onChangeSearchTerm={props.onChangeSearchTerm} onKeyDownCancelSubmit={props.onKeyDownCancelSubmit} />\r\n\r\n              <SearchButton searchText={searchText} onClickSearchButton={props.onClickSearchButton} />\r\n\r\n              <ResetButton resetText={resetText} onClickResetButton={props.onClickResetButton} />\r\n\r\n            </div>\r\n          </div>\r\n        </div>\r\n      }\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { Localization } from \"./classes/Localization\";\r\nimport { IGroup } from \"./IStaffDirectorySearch\";\r\n\r\nexport interface IGroupsDropdownProps {\r\n  selectedGroupID: number;\r\n  groups: IGroup[];\r\n  localization: Localization;\r\n  maxTextLengthDisplayed: number;\r\n  onSelectGroup: (event: any) => any;\r\n}\r\n\r\nexport const GroupsDropdown = (props: IGroupsDropdownProps) => {\r\n\r\n  const allGroupsName = props.localization.all;\r\n\r\n  // Truncate function.\r\n  const truncate = (text: string, length: number): string => {\r\n    if (text.length >= length) {\r\n      return text.substr(0, length + 1) + \"...\";\r\n    }\r\n    return text;\r\n  };\r\n\r\n  let selectedGroupName = allGroupsName;\r\n  if (props.selectedGroupID > 0) {\r\n    selectedGroupName = truncate(props.groups.reduce((a, b) => b.groupID === props.selectedGroupID ? a + b.name : a, \"\"), props.maxTextLengthDisplayed);\r\n  }\r\n\r\n  return (\r\n    <div className=\"DIR-sGroups\">\r\n      <div className=\"DIR-sGroup\">\r\n\r\n        <select className=\"DIR-sGroupSelect\" value={props.selectedGroupID} onChange={props.onSelectGroup} id=\"selGroupId\" aria-label=\"Dropdown for staff directory group selection\">\r\n          <option value=\"0\" key={0} data-text=\"{allGroupsName}\">{allGroupsName}</option>\r\n          {props.groups.map((group, i) => {\r\n            return <option value={group.groupID} key={i} data-text={group.name}>{group.name}</option>;\r\n          })}\r\n        </select>\r\n\r\n        <div className=\"DIR-sGroupFName\">\r\n          <span className=\"DIR-sGFN\">{selectedGroupName}</span>\r\n          <em className=\"fa fa-chevron-down dead\" aria-hidden=\"true\"></em>\r\n        </div>\r\n\r\n      </div>\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nexport interface IResetProps {\r\n  resetText: string;\r\n  onClickResetButton: (event: any) => any;\r\n}\r\n\r\nexport const ResetButton = (props: IResetProps) => {\r\n  return (\r\n    <div className=\"DIR-sCancel\">\r\n      <span><a href=\"#\" onClick={(e) => props.onClickResetButton(e)} title={props.resetText}><em className=\"fa fa-times\" aria-hidden=\"true\"></em></a></span>\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nexport interface ISearchButtonProps {\r\n  searchText: string;\r\n  onClickSearchButton: (event: any) => any;\r\n}\r\n\r\nexport const SearchButton = (props: ISearchButtonProps) => {\r\n  return (\r\n    <div className=\"DIR-sSubmit\">\r\n      <input type=\"button\" className=\"DIR-sGhostSubmit\" onClick={props.onClickSearchButton} aria-label={props.searchText} />\r\n      <span className=\"DIR-sSubmitText\">{props.searchText}</span>\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nexport interface ISearchTermProps {\r\n  placeholder: string;\r\n  placeholderAria: string;\r\n  searchTerm: string;\r\n  onChangeSearchTerm: (event: any) => any;\r\n  onKeyDownCancelSubmit: (event: any) => any;\r\n}\r\n\r\nexport const SearchTerm = (props: ISearchTermProps) => {\r\n  return (\r\n    <div className=\"DIR-sTextInput\">\r\n      <input type=\"text\" maxLength={100} placeholder={props.placeholder} value={props.searchTerm} onChange={props.onChangeSearchTerm} aria-label={props.placeholderAria} onKeyDown={props.onKeyDownCancelSubmit} />\r\n    </div>\r\n  );\r\n};\r\n","import { IGroup, IInterfaceCheckResult, ISettings  } from \"../IStaffDirectorySearch\";\r\n\r\nimport { ObjectVerifier } from \"./ObjectVerifier\";\r\n\r\nexport class Group implements IGroup {\r\n  public groupID: number = 0;\r\n  public name: string = \"\";\r\n\r\n  constructor(groupID: number, name: string) {\r\n    this.groupID = groupID;\r\n    this.name = name;\r\n  }\r\n\r\n}\r\n\r\nexport function verifyGroup(thing: any, parentObjectChain: string[] = []): IInterfaceCheckResult {\r\n  const result: IInterfaceCheckResult = { error: false, details: [] };\r\n\r\n  // Verify that the object has all the fields required by an IGroup.\r\n\r\n  parentObjectChain.push(\"Group\");\r\n  const v = new ObjectVerifier(thing, parentObjectChain);\r\n\r\n  if (v.checkHasProperty(\"groupID\")) {\r\n    v.checkIsInteger(\"groupID\");\r\n  }\r\n\r\n  if (v.checkHasProperty(\"name\")) {\r\n    v.checkIsString(\"name\");\r\n  }\r\n\r\n  if (v.details.length > 0) {\r\n    result.error = v.error;\r\n    result.details = v.details;\r\n  }\r\n\r\n  return result;\r\n}\r\n","import { IInterfaceCheckResult, IStaffBasic, IStaffExtended } from \"../IStaffDirectorySearch\";\r\n\r\nimport { ObjectVerifier } from \"./ObjectVerifier\";\r\n\r\nexport class StaffBasic implements IStaffBasic {\r\n  public userID: number = 0;\r\n  public firstName: string = \"\";\r\n  public lastName: string = \"\";\r\n  public imageURL: string = \"\";\r\n  public mailUrl: string = \"\";\r\n  public jobTitle: string = \"\";\r\n  public website: string = \"\";\r\n  public email: string = \"\";\r\n  public phone: string = \"\";\r\n  public expanded: boolean = false;\r\n\r\n  constructor(userID: number, firstName: string, lastName: string) {\r\n    this.userID = userID;\r\n    this.firstName = firstName;\r\n    this.lastName = lastName;\r\n  }\r\n}\r\n\r\nexport function verifyStaffBasicArray(thing: any, parentObjectChain: string[] = []): IInterfaceCheckResult {\r\n  // Verify that the object has all the properties expected on the StaffBasic response.\r\n\r\n  const result: IInterfaceCheckResult = { error: false, details: [] };\r\n\r\n  parentObjectChain.push(\"StaffBasicArray\");\r\n  const v = new ObjectVerifier(thing, parentObjectChain);\r\n\r\n  if (Array.isArray(thing)) {\r\n    let index = 0;\r\n    for (const staffBasic of thing) {\r\n      if (v.checkIsObject(staffBasic)) {\r\n        const staffBasicVerificationResult = verifyStaffBasic(staffBasic, v.parentObjectChain, index);\r\n        v.combineVerificationResults(staffBasicVerificationResult);\r\n      }\r\n      index++;\r\n    }\r\n\r\n  } else {\r\n    v.addError(\"StaffBasicArray: Is not an Array\");\r\n  }\r\n\r\n  if (v.details.length > 0) {\r\n    result.error = v.error;\r\n    result.details = v.details;\r\n  }\r\n\r\n  return result;\r\n}\r\n\r\nexport function verifyStaffBasic(thing: any, parentObjectChain: string[] = [], index: number): IInterfaceCheckResult {\r\n  // Verify that the object has all the properties expected on the StaffBasic response.\r\n\r\n  const result: IInterfaceCheckResult = { error: false, details: [] };\r\n\r\n  parentObjectChain.push(\"StaffBasic \" + index.toString());\r\n  const v = new ObjectVerifier(thing, parentObjectChain);\r\n\r\n  if (v.checkHasProperty(\"userID\")) {\r\n    v.checkIsInteger(\"userID\");\r\n  }\r\n\r\n  const stringProperties = [\"firstName\", \"lastName\", \"imageURL\", \"mailUrl\", \"jobTitle\", \"website\", \"email\", \"phone\"];\r\n  for (const prop of stringProperties) {\r\n    if (v.checkHasProperty(prop)) {\r\n      v.checkIsString(prop);\r\n    }\r\n  }\r\n\r\n  v.removeParentObject();\r\n\r\n  if (v.details.length > 0) {\r\n    result.error = v.error;\r\n    result.details = v.details;\r\n  }\r\n\r\n  return result;\r\n}\r\n","import { IInterfaceCheckResult, ISocialMediaLink, IStaffExtended } from \"../IStaffDirectorySearch\";\r\n\r\nimport { ObjectVerifier } from \"./ObjectVerifier\";\r\n\r\nexport class StaffExtended implements IStaffExtended {\r\n  public userID = 0;\r\n  public groupIDs: number[] = [];\r\n  public blog: string = \"\";\r\n  public room: string = \"\";\r\n  public grades: string = \"\";\r\n  public subjects: string = \"\";\r\n  public officeHours: string = \"\";\r\n  public biography: string = \"\";\r\n  public personalMessage: string = \"\";\r\n  public socialMediaLinks: ISocialMediaLink[] = [];\r\n\r\n  constructor(userID: number) {\r\n    this.userID = userID;\r\n  }\r\n}\r\n\r\nexport function verifyStaffExtended(thing: any, userID: number, parentObjectChain: string[] = []): IInterfaceCheckResult {\r\n  // Verify that the object has all the properties expected on the StaffExtended response.\r\n\r\n  const result: IInterfaceCheckResult = { error: false, details: [] };\r\n\r\n  parentObjectChain.push(\"StaffExtended \" + userID.toString());\r\n  const v = new ObjectVerifier(thing, parentObjectChain);\r\n\r\n  if (v.checkHasProperty(\"userID\")) {\r\n    v.checkIsInteger(\"userID\");\r\n  }\r\n\r\n  if (v.checkHasProperty(\"groupIDs\")) {\r\n    if (v.checkIsArray(\"groupIDs\")) {\r\n      const propName = \"groupIDs\";\r\n      v.addParentObject(\"GroupIDs\");\r\n      for (const groupName of thing[propName]) {\r\n        if (typeof groupName !== \"number\") { v.addError(\"GroupID is not a string.\"); }\r\n      }\r\n      v.removeParentObject();\r\n    }\r\n  }\r\n\r\n  const stringProperties = [\"blog\", \"room\", \"grades\", \"subjects\", \"officeHours\", \"biography\", \"personalMessage\"];\r\n  for (const prop of stringProperties) {\r\n    if (v.checkHasProperty(prop)) {\r\n      v.checkIsString(prop);\r\n    }\r\n  }\r\n\r\n  v.removeParentObject();\r\n\r\n  if (v.details.length > 0) {\r\n    result.error = v.error;\r\n    result.details = v.details;\r\n  }\r\n\r\n  return result;\r\n}\r\n","import * as React from \"react\";\r\nimport \"./styles/paginator.css\";\r\n\r\nexport interface IPaginatorProps extends React.Props<PaginatorComponent> {\r\n  totalNumberOfRecords: number;\r\n  recordsPerPage: number;\r\n  numberOfPageLinks: number;\r\n  currentPageNumber: number;\r\n  includeRecordsPerPageDropdown?: boolean;\r\n  recordsPerPageOptions?: number[];\r\n  showPagerEvenIfOnlyOnlyOnePageOfResults?: boolean;\r\n\r\n  text_currentlyDisplayingPage: string;\r\n  text_displayPage: string;\r\n  text_displayPreviousPageOfResults: string;\r\n  text_displayPreviousSetOfPageLinks: string;\r\n  text_displayNextPageOfResults: string;\r\n  text_displayNextSetOfPageLinks: string;\r\n  text_noNextPageOfResults: string;\r\n  text_noNextSetOfPageLinks: string;\r\n  text_noPreviousPageOfResults: string;\r\n  text_noPreviousSetOfPageLinks: string;\r\n  text_of: string;\r\n  text_perPage?: string; // Only required if includeRecordsPerPageDropdown is true\r\n  text_ofResultsText: string;\r\n\r\n  onChangePage: (pageNumber: number) => any;\r\n  onChangeRecordsPerPage?: (recordsPerPage: number) => any;\r\n}\r\n\r\nexport default class PaginatorComponent extends React.Component<IPaginatorProps, {}> {\r\n\r\n  private numberOfPages: number = 0;\r\n  private currentPageSet: number = 0;\r\n  private numberOfPageSets: number = 0;\r\n  private firstPageLinkDisplayed: number = 0;\r\n  private lastPageLinkDisplayed: number = 0;\r\n  private firstRecordDisplayed: number = 0;\r\n  private lastRecordDisplayed: number = 0;\r\n\r\n  constructor(props) {\r\n    super(props);\r\n\r\n    // Bind functions:\r\n    this.setPageDisplayed = this.setPageDisplayed.bind(this);\r\n    this.setRecordsPerPage = this.setRecordsPerPage.bind(this);\r\n    this.displayPreviousPage = this.displayPreviousPage.bind(this);\r\n    this.displayPreviousPageSet = this.displayPreviousPageSet.bind(this);\r\n    this.displayNextPage = this.displayNextPage.bind(this);\r\n    this.displayNextPageSet = this.displayNextPageSet.bind(this);\r\n    this.killEvent = this.killEvent.bind(this);\r\n  }\r\n\r\n  public render() {\r\n\r\n    this.numberOfPages = Math.ceil(this.props.totalNumberOfRecords / this.props.recordsPerPage);\r\n    this.numberOfPageSets = Math.ceil(this.numberOfPages / this.props.numberOfPageLinks);\r\n    this.currentPageSet = Math.ceil(this.props.currentPageNumber / this.props.numberOfPageLinks);\r\n    this.firstRecordDisplayed = ((this.props.currentPageNumber - 1) * this.props.recordsPerPage) + 1;\r\n    this.lastRecordDisplayed = Math.min(this.firstRecordDisplayed + (this.props.recordsPerPage - 1), this.props.totalNumberOfRecords);\r\n    this.firstPageLinkDisplayed = ((this.currentPageSet - 1) * this.props.numberOfPageLinks) + 1;\r\n    this.lastPageLinkDisplayed = Math.min((this.currentPageSet * this.props.numberOfPageLinks), this.numberOfPages);\r\n\r\n    const leftArrow: JSX.Element = this.getLeftArrow();\r\n    const leftEllipsis: JSX.Element = this.getLeftEllipsis();\r\n    const pageLinks: JSX.Element[] = this.getPageLinks();\r\n    const blankLinks: JSX.Element[] = this.getBlankLinks();\r\n    const rightEllipsis: JSX.Element = this.getRightEllipsis();\r\n    const rightArrow: JSX.Element = this.getRightArrow();\r\n\r\n    const pagerOptions: any[] = [];\r\n    if (this.props.includeRecordsPerPageDropdown) {\r\n      const pagerOptionNumbers = [...this.props.recordsPerPageOptions];\r\n      pagerOptionNumbers.sort((a, b) => a - b);\r\n\r\n      pagerOptionNumbers.forEach((p) => {\r\n        pagerOptions.push(<option value={p} key={p}>{p} {this.props.text_perPage}</option>);\r\n      });\r\n    }\r\n\r\n    return (\r\n      <div className=\"notranslate\">\r\n        {this.showPager() &&\r\n          <div className=\"PO-paging\">\r\n            <ul className=\"PO-pageButton\">\r\n\r\n              {leftArrow}\r\n              {leftEllipsis}\r\n\r\n              {pageLinks.map((pageLink, i) => pageLink)}\r\n\r\n              {blankLinks.map((blankLink, i) => blankLink)}\r\n\r\n              {rightEllipsis}\r\n              {rightArrow}\r\n\r\n            </ul>\r\n\r\n            <div className=\"PO-pageCount\">{this.firstRecordDisplayed}-{this.lastRecordDisplayed} {this.props.text_of} {this.props.totalNumberOfRecords}</div>\r\n\r\n            {this.props.includeRecordsPerPageDropdown &&\r\n              <div className=\"PO-pageSize\">\r\n                <select className=\"PO-pageSizeDropdown\" value={this.props.recordsPerPage} onChange={this.setRecordsPerPage}>\r\n                  {pagerOptions}\r\n                </select>\r\n              </div>\r\n            }\r\n\r\n          </div>\r\n        }\r\n      </div>\r\n\r\n    );\r\n  }\r\n\r\n  private showPager = (): boolean => {\r\n    if (this.props.showPagerEvenIfOnlyOnlyOnePageOfResults) { return true; }\r\n    if (this.numberOfPages > 1) { return true; }\r\n  }\r\n\r\n  private getLeftArrow(): JSX.Element {\r\n    if (this.props.currentPageNumber > 1) {\r\n      return <li><a href=\"#\" onClick={this.displayPreviousPage} aria-label={this.props.text_displayPreviousPageOfResults}><em className=\"fa fa-arrow-left\"></em></a></li>;\r\n    } else {\r\n      return <li className=\"inactive\"><a href=\"#\" onClick={this.killEvent} aria-label={this.props.text_noPreviousPageOfResults}><em className=\"fa fa-arrow-left\"></em></a></li>;\r\n    }\r\n  }\r\n\r\n  private getLeftEllipsis(): JSX.Element {\r\n    if (this.currentPageSet > 1) {\r\n      return <li><a href=\"#\" onClick={this.displayPreviousPageSet} aria-label={this.props.text_displayPreviousSetOfPageLinks}>...</a></li>;\r\n    } else {\r\n      return null;\r\n    }\r\n  }\r\n\r\n  private getPageLinks(): JSX.Element[] {\r\n    const pageLinks: JSX.Element[] = [];\r\n    let ariaLabel: string = \"\";\r\n    let anchorClassName: string = \"\";\r\n    let ariaCurrent: boolean = false;\r\n    for (let p: number = this.firstPageLinkDisplayed; p <= this.lastPageLinkDisplayed; p++) {\r\n      ariaLabel = (p === this.props.currentPageNumber) ? this.props.text_currentlyDisplayingPage + \" \" + p + \" \" + this.props.text_ofResultsText : this.props.text_displayPage + \" \" + p + \" \" +\r\n        this.props.text_ofResultsText;\r\n      anchorClassName = \"\";\r\n      ariaCurrent = false;\r\n      if (p.toString() === this.props.currentPageNumber.toString()) {\r\n        anchorClassName = \"selected\";\r\n        ariaCurrent = true;\r\n      }\r\n      pageLinks.push(<li key={p}><a href=\"#\" onClick={this.setPageDisplayed} className={anchorClassName} aria-current={ariaCurrent} aria-label={ariaLabel} data-page-number={p}>{p}</a></li>);\r\n    }\r\n    return pageLinks;\r\n  }\r\n\r\n  private getBlankLinks(): JSX.Element[] {\r\n    // Add blank links at end of series of pages (if required... keeps ellipsis and arrows aligned across all page sets).\r\n    const blankLinks: JSX.Element[] = [];\r\n\r\n    if (this.numberOfPageSets > 1) {\r\n      const numLinksDisplayed = (this.lastPageLinkDisplayed - this.firstPageLinkDisplayed + 1);\r\n      if (numLinksDisplayed < this.props.numberOfPageLinks) {\r\n        for (let p = 0; p < this.props.numberOfPageLinks - numLinksDisplayed; p++) {\r\n          const blankLink = <li aria-hidden=\"true\" key={\"100\" + p}><span aria-hidden=\"true\">&nbsp;&nbsp;</span></li>;\r\n          blankLinks.push(blankLink);\r\n        }\r\n      }\r\n    }\r\n\r\n    return blankLinks;\r\n  }\r\n\r\n  private getRightEllipsis(): JSX.Element {\r\n    if (this.currentPageSet < this.numberOfPageSets) {\r\n      return <li><a href=\"#\" onClick={this.displayNextPageSet} aria-label={this.props.text_displayNextSetOfPageLinks}>...</a></li>;\r\n    } else {\r\n      return null;\r\n    }\r\n  }\r\n\r\n  private getRightArrow(): JSX.Element {\r\n    if (this.props.currentPageNumber < this.numberOfPages) {\r\n      return <li><a href=\"#\" onClick={this.displayNextPage} aria-label={this.props.text_displayNextPageOfResults}><em className=\"fa fa-arrow-right\"></em></a></li>;\r\n    } else {\r\n      return <li className=\"inactive\"><a href=\"#\" onClick={this.killEvent} aria-label={this.props.text_noNextPageOfResults}><em className=\"fa fa-arrow-right\"></em></a></li>;\r\n    }\r\n  }\r\n\r\n  // Event handlers:\r\n\r\n  private setPageDisplayed(e): void {\r\n    e.preventDefault();\r\n    const pageNumber: number = parseInt(e.target.attributes[\"data-page-number\"].value, 10);\r\n    this.props.onChangePage(pageNumber);\r\n  }\r\n\r\n  private setRecordsPerPage(e): void {\r\n    e.preventDefault();\r\n    const recordsPerPage: number = parseInt(e.target.value, 10);\r\n    this.props.onChangeRecordsPerPage(recordsPerPage);\r\n  }\r\n\r\n  private displayPreviousPage(e): void {\r\n    e.preventDefault();\r\n    this.props.onChangePage(this.props.currentPageNumber - 1);\r\n  }\r\n\r\n  private displayPreviousPageSet(e): void {\r\n    e.preventDefault();\r\n    const pageNumber: number = ((this.currentPageSet - 1) * this.props.numberOfPageLinks);\r\n    this.props.onChangePage(pageNumber);\r\n  }\r\n\r\n  private displayNextPage(e): void {\r\n    e.preventDefault();\r\n    this.props.onChangePage(this.props.currentPageNumber + 1);\r\n  }\r\n\r\n  private displayNextPageSet(e): void {\r\n    e.preventDefault();\r\n    const pageNumber: number = ((this.currentPageSet * this.props.numberOfPageLinks) + 1);\r\n    this.props.onChangePage(pageNumber);\r\n  }\r\n\r\n  private killEvent(e): void {\r\n    e.preventDefault();\r\n  }\r\n\r\n}\r\n","import * as React from \"react\";\r\nimport * as ReactDOM from \"react-dom\";\r\n\r\nimport Search from \"../Search\";\r\n\r\n// For hot reloading:\r\ndeclare var module: any;\r\nif (module.hot) {\r\n  module.hot.accept();\r\n}\r\n\r\n// Doing this with plain old JS (not JQuery) to avoid dependency on JQuery.\r\nconst components = document.getElementsByClassName(\"staffDirectoryComponent\");\r\n\r\nfor (let i = 0; i < components.length; i++) { // tslint:disable-line prefer-for-of\r\n\r\n  const elem = components[i];\r\n  const portletInstanceId: number = elem.attributes[\"data-portlet-instance-id\"].nodeValue;\r\n\r\n  const render = (Component) => {\r\n    ReactDOM.render(\r\n      <Component portletInstanceID={portletInstanceId} />,\r\n      elem,\r\n    );\r\n  };\r\n\r\n  render(Search);\r\n}\r\n","import { IInterfaceCheckResult } from \"../IStaffDirectorySearch\";\r\n\r\nexport class ObjectVerifier {\r\n  public error: boolean = false;\r\n  public details: string[] = [];\r\n  public parentObjectChain: string[] = [];\r\n\r\n  private thing: any;\r\n\r\n  constructor(thing: any, parentObjectChain: string[]) {\r\n    this.thing = thing;\r\n    this.parentObjectChain = parentObjectChain;\r\n  }\r\n\r\n  public checkHasProperty(propertyName: string): boolean {\r\n    if (!this.thing.hasOwnProperty(propertyName)) {\r\n      this.addError(propertyName + \" is missing\");\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n\r\n  public checkIsInteger(propertyName: string): boolean {\r\n    if (isNaN(Number(this.thing[propertyName])) || this.thing[propertyName] % 1 !== 0) { //\r\n      this.addError(propertyName + \" is not an integer\");\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n\r\n  public checkIsNumber(propertyName: string): boolean {\r\n    if (isNaN(Number(this.thing[propertyName]))) {\r\n      this.addError(propertyName + \" is not a number\");\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n\r\n  public checkIsBoolean(propertyName: string): boolean {\r\n    if (this.thing[propertyName] !== true && this.thing[propertyName] !== false) {\r\n      this.addError(propertyName + \" is not a boolean\");\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n\r\n  public checkIsString(propertyName: string): boolean {\r\n    if (typeof this.thing[propertyName] !== \"string\") {\r\n      this.addError(propertyName + \" is not a string\");\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n\r\n  public checkIsArray(propertyName: string): boolean {\r\n    if (!Array.isArray(this.thing[propertyName])) {\r\n      this.addError(propertyName + \" is not an array\");\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n\r\n  public checkIsObject(obj: any): boolean {\r\n    if (typeof obj !== \"object\") {\r\n      this.addError(JSON.stringify(obj) + \" is not an object\");\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n\r\n  public checkIsNull(propertyName: string): boolean {\r\n    if (this.thing[propertyName] === null) {\r\n      this.addError(propertyName + \" is not null\");\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n\r\n  public combineVerificationResults(otherResult: IInterfaceCheckResult): void {\r\n    if (otherResult.error === true) {\r\n      this.error = otherResult.error;\r\n      for (const detail of otherResult.details) {\r\n        this.details.push(detail);\r\n      }\r\n    }\r\n  }\r\n\r\n  public addParentObject(name: string) {\r\n    this.parentObjectChain.push(name);\r\n  }\r\n\r\n  public removeParentObject() {\r\n    this.parentObjectChain.pop();\r\n  }\r\n\r\n  public addError(error: string): void {\r\n    this.details.push(this.parentObjectChain.join(\" >> \") + \": \" + error);\r\n    this.error = true;\r\n  }\r\n}\r\n","export function formatName(firstName: string, lastName: string, sortOrder: string, onlyShowFirstInitial: boolean): string {\r\n\r\n  const lastNamePosition = sortOrder.toLowerCase().lastIndexOf(\"lastname\");\r\n  const firstNamePosition = sortOrder.toLowerCase().lastIndexOf(\"firstname\");\r\n\r\n  let adjustedFirstName = firstName;\r\n  if (onlyShowFirstInitial) {\r\n    if (adjustedFirstName.length > 0) {\r\n      adjustedFirstName = adjustedFirstName[0] + \".\";\r\n    }\r\n  }\r\n\r\n  let name: string = \"\";\r\n  if (lastNamePosition <= firstNamePosition) {\r\n    name = lastName + \", \" + adjustedFirstName;\r\n  } else {\r\n    name = adjustedFirstName + \" \" + lastName;\r\n  }\r\n\r\n  return name;\r\n};\r\n\r\nexport function nullCheck(item: any): string {\r\n  if (item) {\r\n    return item;\r\n  } else {\r\n    return \"\";\r\n  }\r\n}\r\n\r\nexport function speakPhoneAsNumbers(phone: string): string {\r\n  let output = \"\";\r\n  // I'm compiling down to ES3 (instead of ES5) because IE9 does not handle reserved works (like e.default instead e[\"default\"]) which result when compile to ES5.\r\n  // However, this means I can't for use for..of loops, have to dropd down to a for loop, which TS Loint dislikes.\r\n  for (let i = 0; i < phone.length; i++) { // tslint:disable-line\r\n    output += phone[i] + \" \";\r\n  }\r\n  return output;\r\n}\r\n","// Class interfaces:\r\n\r\nimport { ILocalization } from \"./classes/Localization\";\r\n\r\nexport interface IAPI {\r\n  settings(portletInstanceId: number): ISettings;\r\n  searchResults(): IStaffBasic[];\r\n  searchResultsExtended(): { [userID: number]: IStaffExtended };\r\n}\r\n\r\nexport interface ISettings {\r\n  portletInstanceID: number;\r\n  emailPrivacy: boolean;\r\n  useExternalEmailApp: boolean;\r\n  sortOrder: string;\r\n  onlyShowFirstInitial: boolean;\r\n  searchByJobTitle: boolean;\r\n  groups: IGroup[];\r\n  localization: ILocalization;\r\n  error: string;\r\n}\r\n\r\nexport interface IStaffBasic {\r\n  userID: number;\r\n  firstName: string;\r\n  lastName: string;\r\n  imageURL: string;\r\n  jobTitle: string;\r\n  mailUrl: string;\r\n  website: string;\r\n  email: string;\r\n  phone: string;\r\n  expanded: boolean;\r\n}\r\n\r\nexport interface IStaffExtended {\r\n  userID: number;\r\n  groupIDs: number[];\r\n  blog: string;\r\n  socialMediaLinks: ISocialMediaLink[];\r\n  room: string;\r\n  grades: string;\r\n  subjects: string;\r\n  officeHours: string;\r\n  biography: string;\r\n  personalMessage: string;\r\n}\r\n\r\nexport interface ISocialMediaLink {\r\n  name: string;\r\n  website: string;\r\n}\r\n\r\nexport interface IGroup {\r\n  groupID: number;\r\n  name: string;\r\n}\r\n\r\nexport interface IInterfaceCheckResult {\r\n  error: boolean;\r\n  details: string[];\r\n}\r\n\r\nexport interface IPagerSettings {\r\n  currentPageNumber: number;\r\n  resultsPerPage: number;\r\n  numberOfPageLinks: number;\r\n}\r\n\r\n// Enumerations:\r\n\r\nexport enum EmailStyle { small, medium };\r\n","import * as React from \"react\";\r\n\r\nexport interface ILargeLoadingSpinnerProps {\r\n  loadingText: string;\r\n}\r\n\r\nexport const LargeLoadingSpinner = (props: ILargeLoadingSpinnerProps) => {\r\n\r\n  return (\r\n    <div className=\"DIR-slideOut DIR-LoadExtendedStaff\" >\r\n      <div className=\"PO-loading\" title={props.loadingText}>\r\n        <div className=\"sk-fading-circle\">\r\n          <div className=\"sk-circle1 sk-circle\"></div>\r\n          <div className=\"sk-circle2 sk-circle\"></div>\r\n          <div className=\"sk-circle3 sk-circle\"></div>\r\n          <div className=\"sk-circle4 sk-circle\"></div>\r\n          <div className=\"sk-circle5 sk-circle\"></div>\r\n          <div className=\"sk-circle6 sk-circle\"></div>\r\n          <div className=\"sk-circle7 sk-circle\"></div>\r\n          <div className=\"sk-circle8 sk-circle\"></div>\r\n          <div className=\"sk-circle9 sk-circle\"></div>\r\n          <div className=\"sk-circle10 sk-circle\"></div>\r\n          <div className=\"sk-circle11 sk-circle\"></div>\r\n          <div className=\"sk-circle12 sk-circle\"></div>\r\n        </div>\r\n      </div>\r\n    </div>\r\n  );\r\n};\r\n","import * as React from \"react\";\r\n\r\nimport { EmailStyle } from \"./IStaffDirectorySearch\";\r\nimport { formatName } from \"./Utilities\";\r\n\r\nimport { EnviroConfig } from \"../EnviroConfig\";\r\nimport { Localization } from \"./classes/Localization\";\r\n\r\nexport interface IEmailProps {\r\n  style: EmailStyle;\r\n  email: string;\r\n  emailPrivacy: boolean;\r\n  useExternalEmailApp: boolean;\r\n  firstName: string;\r\n  mailUrl: string;\r\n  lastName: string;\r\n  userID: number;\r\n  sortOrder: string;\r\n  onlyShowFirstInitial: boolean;\r\n  localization: Localization;\r\n}\r\n\r\nconst OpenModalDialog = (url, name, width, height) => {\r\n  width = width || 640;\r\n  height = height || 480;\r\n  const result = false;\r\n  let feature;\r\n  feature = \"width=\" + width + \",height=\" + height + \",toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=0,resizable=0\";\r\n  window.open(url, name, feature);\r\n  return result;\r\n};\r\n\r\nexport const Email = (props: IEmailProps) => {\r\n\r\n  const emailText = props.localization.email;\r\n\r\n  const name = formatName(props.firstName, props.lastName, props.sortOrder, props.onlyShowFirstInitial);\r\n  const alt = emailText + \" (\" + name + \")\";\r\n\r\n  const emailPopupURL = props.mailUrl;\r\n\r\n  let linkhref = \"\";\r\n  if (props.emailPrivacy || !props.useExternalEmailApp) {\r\n    linkhref = \"#!\";\r\n  } else {\r\n    linkhref = \"mailto:\" + props.email;\r\n  }\r\n\r\n  const emailAria =  emailText + \" \" + props.firstName + \" \" + props.lastName;\r\n\r\n  const handleLinkClick = () => {\r\n    if (props.emailPrivacy || !props.useExternalEmailApp) {\r\n      OpenModalDialog(emailPopupURL, \"sendemail\", 700, 530);\r\n    };\r\n  };\r\n\r\n  let email: JSX.Element = null;\r\n\r\n  if (props.email !== \"\") {\r\n    switch (props.style) {\r\n\r\n      case EmailStyle.small:\r\n\r\n        email = (\r\n          <li role=\"presentation\">\r\n            <a href={linkhref} onClick={() => { handleLinkClick(); }} aria-label={emailAria}>\r\n              <em className=\"fa fa-envelope DIR-infoOption\" aria-hidden=\"true\" title={alt}></em>\r\n              {!props.emailPrivacy &&\r\n                <span>{props.email}</span>\r\n              }\r\n            </a>\r\n          </li>\r\n        );\r\n        break;\r\n\r\n      case EmailStyle.medium:\r\n        email = (\r\n          <li role=\"presentation\">\r\n            <a href={linkhref} onClick={() => { handleLinkClick(); }} className=\"DIR-contactButton\" aria-label={emailAria} >\r\n              <em className=\"fa fa-envelope\" aria-hidden=\"true\" title={alt}></em>\r\n              {!props.emailPrivacy &&\r\n                props.email\r\n              }\r\n            </a>\r\n          </li >\r\n        );\r\n        break;\r\n\r\n      default:\r\n        email = <div>Unknown email style</div>;\r\n    }\r\n  }\r\n\r\n  return (\r\n    email\r\n  );\r\n};\r\n","import { IInterfaceCheckResult } from \"../IStaffDirectorySearch\";\r\nimport { ObjectVerifier } from \"./ObjectVerifier\";\r\n\r\nexport interface ILocalization {\r\n  all: string;\r\n  biography: string;\r\n  currentlyDisplayingPage: string;\r\n  displayPage: string;\r\n  displayPreviousPageOfResults: string;\r\n  displayPreviousSetOfPageLinks: string;\r\n  displayNextPageOfResults: string;\r\n  displayNextSetOfPageLinks: string;\r\n  email: string;\r\n  errorMessage: string;\r\n  gradesTaught: string;\r\n  less: string;\r\n  lessAria: string;\r\n  loading: string;\r\n  more: string;\r\n  moreAria: string;\r\n  myblog: string;\r\n  mywebsite: string;\r\n  noResultsFound: string;\r\n  noNextPageOfResults: string;\r\n  noNextSetOfPageLinks: string;\r\n  noPreviousPageOfResults: string;\r\n  noPreviousSetOfPageLinks: string;\r\n  of: string;\r\n  officeHours: string;\r\n  ofResults: string;\r\n  personalMessage: string;\r\n  resetText: string;\r\n  room: string;\r\n  searchTermPlaceHolder: string;\r\n  searchTermPlaceHolderAria: string;\r\n  searchTermPlaceHolder_NameOnly: string;\r\n  searchTermPlaceHolderAria_NameOnly: string;\r\n  searchText: string;\r\n  staffMember: string;\r\n  subjectsTaught: string;\r\n  telephonePersonAt: string;\r\n  website: string;\r\n}\r\n\r\nexport class Localization implements ILocalization {\r\n\r\n  public all: string = \"\";\r\n  public biography: string = \"\";\r\n  public currentlyDisplayingPage: string = \"\";\r\n  public displayPage: string = \"\";\r\n  public displayPreviousPageOfResults: string = \"\";\r\n  public displayPreviousSetOfPageLinks: string = \"\";\r\n  public displayNextPageOfResults: string = \"\";\r\n  public displayNextSetOfPageLinks: string = \"\";\r\n  public email: string = \"\";\r\n  public errorMessage = \"\";\r\n  public gradesTaught: string = \"\";\r\n  public less: string = \"\";\r\n  public lessAria: string = \"\";\r\n  public loading: string = \"\";\r\n  public more: string = \"\";\r\n  public moreAria: string = \"\";\r\n  public myblog: string = \"\";\r\n  public mywebsite: string = \"\";\r\n  public noResultsFound: string = \"\";\r\n  public noNextPageOfResults: string = \"\";\r\n  public noNextSetOfPageLinks: string = \"\";\r\n  public noPreviousPageOfResults: string = \"\";\r\n  public noPreviousSetOfPageLinks: string = \"\";\r\n  public of: string = \"\";\r\n  public officeHours: string = \"\";\r\n  public ofResults: string = \"\";\r\n  public personalMessage: string = \"\";\r\n  public resetText: string = \"\";\r\n  public room: string = \"\";\r\n  public searchTermPlaceHolder: string = \"\";\r\n  public searchTermPlaceHolderAria: string = \"\";\r\n  public searchTermPlaceHolder_NameOnly: string = \"\"; // tslint:disable-line\r\n  public searchTermPlaceHolderAria_NameOnly: string = \"\"; // tslint:disable-line\r\n  public searchText: string = \"\";\r\n  public staffMember: string = \"\";\r\n  public subjectsTaught: string = \"\";\r\n  public telephonePersonAt: string = \"\";\r\n  public website: string = \"\";\r\n}\r\n\r\nexport function verifyLocalizer(thing: any, parentObjectChain: string[] = []): IInterfaceCheckResult {\r\n  // Verify that the object has all the properties expected on the Localization.\r\n\r\n  const result: IInterfaceCheckResult = { error: false, details: [] };\r\n\r\n  parentObjectChain.push(\"Localization\");\r\n  const v = new ObjectVerifier(thing, parentObjectChain);\r\n\r\n  const exampleLocalization = new Localization();\r\n  for (const key in exampleLocalization) {\r\n    // if (thing.hasOwnProperty(key)) {\r\n    if (v.checkHasProperty(key)) {\r\n      v.addParentObject(key);\r\n      v.checkIsString(key);\r\n      v.removeParentObject();\r\n    }\r\n    // }\r\n  }\r\n\r\n  if (v.details.length > 0) {\r\n    result.error = v.error;\r\n    result.details = v.details;\r\n  }\r\n\r\n  return result;\r\n}\r\n","export interface IEnviroConfig {\r\n  readonly bannerServiceURL: string;\r\n  readonly calendarServiceURL: string;\r\n  readonly emailPopupPath: string;\r\n  readonly socialMediaManagementURL: string;\r\n  readonly staffDirServiceURL: string;\r\n  readonly unifiedPublishingAlertServiceURL: string;\r\n  readonly modernSocialMediaAlertsInTestMode: boolean;\r\n}\r\n\r\nexport class EnviroConfig implements IEnviroConfig {\r\n  public bannerServiceURL: string;\r\n  public calendarServiceURL: string;\r\n  public newsroomServiceURL: string;\r\n  public createAlertServiceURL: string;\r\n  public emailPopupPath: string;\r\n  public iconpickerServiceURL: string;\r\n  public newsroomApiBaseUrl: string;\r\n  public portletLibraryServiceURL: string;\r\n  public quicklinkportletServiceURL: string;\r\n  public searchServiceURL: string;\r\n  public socialMediaManagementURL: string;\r\n  public staffDirServiceURL: string;\r\n  public unifiedPublishingBaseURL: string;\r\n  public unifiedPublishingAlertServiceURL: string;\r\n\r\n  public modernSocialMediaAlertsInTestMode: boolean;\r\n\r\n  constructor() {\r\n    // When webpack_config_prod.ts builds the code, it has mode:production set, which sets process.env.NODE_ENV === \"production\"\r\n    // When webpack_config_dev.ts builds the code, it has mode:development set, which sets process.env.NODE_ENV === \"development\"\r\n    if (process.env.NODE_ENV === \"production\") {\r\n      this.useProductionConfig();\r\n    } else if (this.toBoolean(process.env.USE_NGROK) === true) {\r\n      // NGROK is for exposing your local site and services via ngrok at an external URL. See webpack_config_dev.ts\r\n      this.useNgrokConfig();\r\n    } else {\r\n        this.useDevConfig();\r\n    }\r\n\r\n    // // This is for accessing the site and services via my machine's local IP address. Change this to your machine's IP address if you need to debug off another machine.\r\n    // // Occasionally useful for testing on other machines.\r\n    // if (process.env.NODE_ENV === \"remote_dev\") {\r\n    //   const localURL = \"http://192.168.3.124:3000\";\r\n    //   this.staffDirServiceURL = localURL + \"/staffDirectory/\";\r\n    //   this.calendarServiceURL = localURL + \"/calendar/\";\r\n    //   this.unifiedPublishingAlertServiceURL = localURL + \"/unifiedPublishingAlert/\";\r\n    //   this.emailPopupPath = \"./\";\r\n    // }\r\n  }\r\n\r\n  private useDevConfig() {\r\n    this.newsroomServiceURL = \"http://localhost:3000/newsroom/\";\r\n    this.createAlertServiceURL = \"http://localhost:3000/createAlert/\";\r\n    this.portletLibraryServiceURL = \"http://localhost:3000/WebApi/portal/\";\r\n    this.iconpickerServiceURL = \"http://localhost:3000/iconpicker/\";\r\n    this.newsroomApiBaseUrl = \"http://localhost:3000/unifiedPublishing/\";\r\n    this.quicklinkportletServiceURL = \"http://localhost:3000/quicklinkportlet/\";\r\n    this.searchServiceURL = \"http://localhost:3000/WebApi/search/\";\r\n    this.staffDirServiceURL = \"http://localhost:3000/staffDirectory/\";\r\n    this.calendarServiceURL = \"http://localhost:3000/calendar/\";\r\n    this.unifiedPublishingBaseURL = \"http://localhost:3000/unifiedPublishing/\";\r\n    this.unifiedPublishingAlertServiceURL = \"http://localhost:3000/unifiedPublishingAlert/\";\r\n    this.bannerServiceURL = \"http://localhost:3000/banner/\";\r\n    this.socialMediaManagementURL = \"http://localhost:3000/webapi/\";\r\n    this.emailPopupPath = \"./\";\r\n    this.modernSocialMediaAlertsInTestMode = true;\r\n  }\r\n\r\n  private useNgrokConfig() {\r\n    const ngrokURL = process.env.NGROK_URL;\r\n    this.newsroomServiceURL = ngrokURL + \"/newsroom/\";\r\n    this.createAlertServiceURL = ngrokURL + \"/createAlert/\";\r\n    this.portletLibraryServiceURL = ngrokURL + \"/WebApi/portal/\";\r\n    this.iconpickerServiceURL = ngrokURL + \"/iconpicker/\";\r\n    this.newsroomApiBaseUrl = ngrokURL + \"/unifiedPublishing/\";\r\n    this.quicklinkportletServiceURL = ngrokURL + \"/WebApi/quicklinkportlet/\";\r\n    this.searchServiceURL = ngrokURL + \"/WebApi/search/\";\r\n    this.staffDirServiceURL = ngrokURL + \"/staffDirectory/\";\r\n    this.calendarServiceURL = ngrokURL + \"/calendar/\";\r\n    this.unifiedPublishingBaseURL = ngrokURL + \"/unifiedPublishing/\";\r\n    this.unifiedPublishingAlertServiceURL = ngrokURL + \"/unifiedPublishingAlert/\";\r\n    this.bannerServiceURL = ngrokURL + \"/banner/\";\r\n    this.socialMediaManagementURL = ngrokURL + \"/webapi/\";\r\n    this.emailPopupPath = \"./\";\r\n    this.modernSocialMediaAlertsInTestMode = true;\r\n  }\r\n\r\n  private useProductionConfig() {\r\n    this.newsroomServiceURL = \"/WebApi/Newsroom/\";\r\n    this.createAlertServiceURL = \"../WebServices/UnifiedPublishing/UnifiedPublishingService.asmx/\";\r\n    this.portletLibraryServiceURL = \"/WebApi/portal/\";\r\n    this.iconpickerServiceURL = \"/WebApi/quicklinkportlet/\";\r\n    this.newsroomApiBaseUrl = \"/unifiedPublishing/\";\r\n    this.quicklinkportletServiceURL = \"/WebApi/quicklinkportlet/\";\r\n    this.searchServiceURL = \"/WebApi/search/\";\r\n    this.staffDirServiceURL = \"../Common/controls/StaffDirectory/ws/StaffDirectoryWS.asmx/\";\r\n    this.calendarServiceURL = \"../Common/controls/WorkspaceCalendar/ws/WorkspaceCalendarWS.asmx/\";\r\n    this.unifiedPublishingBaseURL = \"/unifiedPublishing/\";\r\n    this.unifiedPublishingAlertServiceURL = \"../WebServices/UnifiedPublishing/UnifiedPublishingService.asmx/\";\r\n    this.bannerServiceURL = \"/WebApi/Banner\";\r\n    this.socialMediaManagementURL = \"/WebApi/\";\r\n    this.emailPopupPath = \"../common/controls/General/Email/Default.aspx?action=staffDirectoryEmail&recipients=\";\r\n    this.modernSocialMediaAlertsInTestMode = false;\r\n  }\r\n\r\n  private toBoolean = (x) => !!x;\r\n}\r\n","import { IGroup, IInterfaceCheckResult, ISettings } from \"../IStaffDirectorySearch\";\r\n\r\nimport { verifyGroup } from \"./Group\";\r\nimport { ILocalization, Localization } from \"./Localization\";\r\nimport { verifyLocalizer } from \"./Localization\";\r\nimport { ObjectVerifier } from \"./ObjectVerifier\";\r\n\r\nexport class Settings implements ISettings {\r\n  public portletInstanceID: number;\r\n  public emailPrivacy: boolean = false;\r\n  public useExternalEmailApp: boolean = false;\r\n  public sortOrder: string = \"LastName, FirstName\";\r\n  public onlyShowFirstInitial: boolean = false;\r\n  public searchByJobTitle: boolean = true;\r\n  public groups: IGroup[] = [];\r\n  public localization: ILocalization;\r\n  public error: string = \"\";\r\n\r\n  constructor(portletInstanceId: number) {\r\n    this.portletInstanceID = portletInstanceId;\r\n    this.localization = new Localization();\r\n  }\r\n}\r\n\r\nexport function verifySettings(thing: any, parentObjectChain: string[] = []): IInterfaceCheckResult {\r\n  const result: IInterfaceCheckResult = { error: false, details: [] };\r\n\r\n  // Verify that the object has all the fields required by an ISettings.\r\n\r\n  parentObjectChain.push(\"Settings\");\r\n  const v = new ObjectVerifier(thing, parentObjectChain);\r\n\r\n  if (v.checkHasProperty(\"portletInstanceID\")) {\r\n    v.checkIsInteger(\"portletInstanceID\");\r\n  }\r\n\r\n  if (v.checkHasProperty(\"emailPrivacy\")) {\r\n    v.checkIsBoolean(\"emailPrivacy\");\r\n  }\r\n\r\n  if (v.checkHasProperty(\"useExternalEmailApp\")) {\r\n    v.checkIsBoolean(\"useExternalEmailApp\");\r\n  }\r\n\r\n  if (v.checkHasProperty(\"sortOrder\")) {\r\n    v.checkIsString(\"sortOrder\");\r\n  }\r\n\r\n  if (v.checkHasProperty(\"onlyShowFirstInitial\")) {\r\n    v.checkIsBoolean(\"onlyShowFirstInitial\");\r\n  }\r\n\r\n  if (v.checkHasProperty(\"searchByJobTitle\")) {\r\n    v.checkIsBoolean(\"searchByJobTitle\");\r\n  }\r\n\r\n  if (v.checkHasProperty(\"groups\")) {\r\n    if (v.checkIsArray(\"groups\")) {\r\n      const propName = \"groups\";\r\n      v.addParentObject(\"Groups\");\r\n      for (const group of thing[propName]) {\r\n        if (v.checkIsObject(group)) {\r\n          const groupVerificationResult = verifyGroup(group, v.parentObjectChain);\r\n          v.combineVerificationResults(groupVerificationResult);\r\n        }\r\n      }\r\n      v.removeParentObject();\r\n    }\r\n  }\r\n\r\n  if (v.checkHasProperty(\"localization\")) {\r\n    const propName = \"localization\";\r\n    if (v.checkIsObject(thing[propName])) {\r\n      const localizationVerificationResult = verifyLocalizer(thing[propName]);\r\n      v.combineVerificationResults(localizationVerificationResult);\r\n    }\r\n  }\r\n\r\n  if (v.checkHasProperty(\"error\")) {\r\n    v.checkIsString(\"error\");\r\n  }\r\n\r\n  if (v.details.length > 0) {\r\n    result.error = v.error;\r\n    result.details = v.details;\r\n  }\r\n\r\n  return result;\r\n}\r\n"],"sourceRoot":""}