Updated with Pooling Status

This commit is contained in:
João Mendes 2020-07-09 19:10:37 +01:00
parent 13d4337fd7
commit 18d26c100f
5 changed files with 157 additions and 44 deletions

View File

@ -9,4 +9,5 @@ export interface IOrganizationChartProps {
themeVariant: IReadonlyTheme | undefined;
displayMode: DisplayMode;
updateProperty: (value: string) => void;
refreshInterval: number;
}

View File

@ -56,6 +56,10 @@ presenceStatus["PresenceUnknown"] = PersonaPresence.none;
export const OrganizationChart: React.FunctionComponent<IOrganizationChartProps> = (
props: IOrganizationChartProps
) => {
// Timer Id used by setInterval
let _timerId:number = 0;
// Application Context (React.Context)
const applicationContext: IAppContext = {
currentUser: props.currentUser,
context: props.context,
@ -255,10 +259,12 @@ export const OrganizationChart: React.FunctionComponent<IOrganizationChartProps>
_managersList,
_currentUserProfile,
_reportsList,
getPresenceStatus,
} = await useGetUserProperties(
applicationContext.currentUser.loginName,
applicationContext.context
);
setState({
...state,
isloading: false,
@ -266,6 +272,33 @@ export const OrganizationChart: React.FunctionComponent<IOrganizationChartProps>
reportsList: _reportsList,
userProfile: _currentUserProfile,
});
// Pooling status each x min ( value define as property in webpart)
// test if there are an Timer running if exist clear
if (_timerId) {
clearInterval(_timerId);
}
const _interval = props.refreshInterval * 60000;
_timerId = setInterval(async () => {
const newPresenceStatus = await getPresenceStatus(
_managersList,
_reportsList,
_currentUserProfile
);
const {
managersList,
currentUserProfile,
reportsList,
} = newPresenceStatus;
setState({
...state,
isloading: false,
managerList: managersList,
reportsList: reportsList,
userProfile: currentUserProfile,
});
}, _interval);
//
} catch (error) {
setState({

View File

@ -121,8 +121,13 @@ export const useGetUserProperties = async (
const _managersPresences: IUserPresence[] = await getUserPresence(
_managersObjIds
);
// Update Array of managers with presence
if (_managersPresences.length > 0) {
await updateManagersPresence(_managersPresences);
};
//************************************************************************************//
// function Update List os Managers with presence status
//************************************************************************************//
const updateManagersPresence = async (_managersPresences: IUserPresence[]):Promise<IUserInfo[]> => {
if (_managersPresences.length > 0) {
for (const _presence of _managersPresences) {
const i = _.findIndex(_managersList, (v) => {
return v.id == _presence.id;
@ -136,8 +141,10 @@ export const useGetUserProperties = async (
};
}
}
return _managersList;
};
//************************************************************************************//
// Get Direct Reports
//*************************************************************************************//
@ -172,8 +179,16 @@ export const useGetUserProperties = async (
_userReportObjIds
);
// Update Array of direct reports with presence
if (_directReportsPresences.length > 0) {
for (const _presence of _directReportsPresences) {
await updateDirectReportsPresence(_directReportsPresences);
};
//*************************************************************************************//
// Funcion Update List os Direct Reports with presence status
//*************************************************************************************//
const updateDirectReportsPresence = async (directReportsPresences: IUserPresence[]):Promise<IUserInfo[]> => {
// Update Array of direct reports with presence
if (directReportsPresences.length > 0) {
for (const _presence of directReportsPresences) {
const i = _.findIndex(_reportsList, (v) => {
return v.id == _presence.id;
});
@ -186,14 +201,51 @@ export const useGetUserProperties = async (
};
}
}
};
return _reportsList;
};
//*************************************************************************************//
// Get news status of managers and direct Reports
//*************************************************************************************//
const getPresenceStatus = async ( managersList: IUserInfo[],reportsList:IUserInfo[], currentUserProfile: any):Promise<any> => {
const _managersObjIds:string[] = [];
const _userReportObjIds:string[] = [];
// get managersObjIds
for (const _manager of managersList){
_managersObjIds.push(_manager.id);
}
// get new status of Managers and update list os managers
const _managersPresences: IUserPresence[] = await getUserPresence(_managersObjIds);
managersList = await updateManagersPresence(_managersPresences);
// Get objsId of DirectReports
for (const _userReport of reportsList){
_userReportObjIds.push(_userReport.id);
}
// get new status of Direct Reports and update list of direct Reports
const _directReportsPresences: IUserPresence[] = await getUserPresence(
_userReportObjIds
);
reportsList = await updateDirectReportsPresence(_directReportsPresences);
// Get update status for current user
const _currentUserPresenceUpd: IUserPresence[] = await getUserPresence([currentUserProfile.id]);
currentUserProfile.presence = { activity: _currentUserPresenceUpd[0].activity, availability: _currentUserPresenceUpd[0].availability};
return { managersList, currentUserProfile, reportsList };
};
//*************************************************************************************//
// End Functions
//*************************************************************************************//
//*************************************************************************************//
// Get Current User Profile
// MAIN - Get Current User Profile
//*************************************************************************************//
const _currentUserProfile: any = await sp.profiles
.usingCaching()
@ -204,6 +256,7 @@ export const useGetUserProperties = async (
const _directReports: string[] = _currentUserProfile.DirectReports;
// Get userObjId
const _currentUserObjId: string = await getUserId( _currentUserProfile.UserProfileProperties);
_currentUserProfile.id = _currentUserObjId;
// Get Current user Picture and User Presence
_currentUserProfile.PictureUrl = await getImageBase64(
`/_layouts/15/userphoto.aspx?size=M&accountname=${_currentUserProfile.Email}`, _currentUserObjId);
@ -219,5 +272,5 @@ export const useGetUserProperties = async (
// Return objects
// _managersList , _currentUserProfile , DirectReports
//*************************************************************************************//
return { _managersList, _currentUserProfile, _reportsList };
return { _managersList, _currentUserProfile, _reportsList, getPresenceStatus };
};

View File

@ -21,7 +21,8 @@
"description": { "default": "Organization Chart" },
"officeFabricIconFontName": "Org",
"properties": {
"title": "Organization Chart"
"title": "Organization Chart",
"refreshInterval": "5"
}
}]
}

View File

@ -1,45 +1,56 @@
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import * as React from "react";
import * as ReactDom from "react-dom";
import { Version } from "@microsoft/sp-core-library";
import {
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import { ThemeProvider, ThemeChangedEventArgs, IReadonlyTheme } from '@microsoft/sp-component-base';
import * as strings from 'OrganizationChartWebPartStrings';
import {OrganizationChart} from '../../components/OrganizationChart/OrganizationChart';
import { IOrganizationChartProps } from '../../components/OrganizationChart/IOrganizationChartProps';
PropertyPaneTextField,
PropertyPaneSlider,
PropertyPaneLabel,
} from "@microsoft/sp-property-pane";
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
import {
ThemeProvider,
ThemeChangedEventArgs,
IReadonlyTheme,
} from "@microsoft/sp-component-base";
import * as strings from "OrganizationChartWebPartStrings";
import { OrganizationChart } from "../../components/OrganizationChart/OrganizationChart";
import { IOrganizationChartProps } from "../../components/OrganizationChart/IOrganizationChartProps";
import { loadTheme } from "office-ui-fabric-react";
import { DisplayMode } from '@microsoft/sp-core-library';
import { DisplayMode } from "@microsoft/sp-core-library";
import { sp } from "@pnp/sp";
const teamsDefaultTheme = require("../../common/TeamsDefaultTheme.json");
const teamsDarkTheme = require("../../common/TeamsDarkTheme.json");
const teamsContrastTheme = require("../../common/TeamsContrastTheme.json");
export interface IOrganizationChartWebPartProps {
title: string;
displayMode: DisplayMode;
updateProperty: (value: string) => void;
refreshInterval: number;
}
export default class OrganizationChartWebPart extends BaseClientSideWebPart <IOrganizationChartWebPartProps> {
export default class OrganizationChartWebPart extends BaseClientSideWebPart<
IOrganizationChartWebPartProps
> {
private _themeProvider: ThemeProvider;
private _themeVariant: IReadonlyTheme | undefined;
protected async onInit(): Promise<void> {
sp.setup({
spfxContext: this.context
spfxContext: this.context,
});
this._themeProvider = this.context.serviceScope.consume(ThemeProvider.serviceKey);
this._themeProvider = this.context.serviceScope.consume(
ThemeProvider.serviceKey
);
// If it exists, get the theme variant
this._themeVariant = this._themeProvider.tryGetTheme();
// Register a handler to be notified if the theme variant changes
this._themeProvider.themeChangedEvent.add(this, this._handleThemeChangedEvent);
this._themeProvider.themeChangedEvent.add(
this,
this._handleThemeChangedEvent
);
if (this.context.sdks.microsoftTeams) {
// in teams ?
@ -62,31 +73,30 @@ export default class OrganizationChartWebPart extends BaseClientSideWebPart <IOr
this.render();
}
// Apply btheme id in Teams
// Apply btheme id in Teams
private _applyTheme = (theme: string): void => {
this.context.domElement.setAttribute("data-theme", theme);
document.body.setAttribute("data-theme", theme);
if (theme == "dark") {
loadTheme({
palette: teamsDarkTheme
palette: teamsDarkTheme,
});
}
if (theme == "default") {
if (theme == "default") {
loadTheme({
palette: teamsDefaultTheme
palette: teamsDefaultTheme,
});
}
if (theme == "contrast") {
loadTheme({
palette: teamsContrastTheme
palette: teamsContrastTheme,
});
}
}
public render(): void {
const element: React.ReactElement<IOrganizationChartProps> = React.createElement(
OrganizationChart,
@ -96,9 +106,10 @@ export default class OrganizationChartWebPart extends BaseClientSideWebPart <IOr
context: this.context,
themeVariant: this._themeVariant,
displayMode: this.displayMode,
updateProperty: (value: string) => {
this.properties.title = value;
}
updateProperty: (value: string) => {
this.properties.title = value;
},
refreshInterval: this.properties.refreshInterval,
}
);
@ -110,7 +121,7 @@ export default class OrganizationChartWebPart extends BaseClientSideWebPart <IOr
}
protected get dataVersion(): Version {
return Version.parse('1.0');
return Version.parse("1.0");
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
@ -118,20 +129,34 @@ export default class OrganizationChartWebPart extends BaseClientSideWebPart <IOr
pages: [
{
header: {
description: strings.PropertyPaneDescription
description: strings.PropertyPaneDescription,
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('title', {
label: strings.DescriptionFieldLabel
PropertyPaneTextField("title", {
label: strings.DescriptionFieldLabel,
}),
PropertyPaneLabel('',{
text: ""
})
]
}
]
}
]
,
PropertyPaneSlider("refreshInterval", {
max: 30,
min: 5,
showValue: true,
step: 2,
label: "Refresh Presence Status Every (min)",
value: this.properties.refreshInterval,
}),
],
},
],
},
],
};
}
}