Merge pull request #1468 from joaojmendes/master

react-my-sites. bug fix and new features
This commit is contained in:
Hugo Bernier 2020-09-02 18:46:20 -04:00 committed by GitHub
commit 466728e54e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 274 additions and 74 deletions

View File

@ -59,6 +59,7 @@ Version|Date|Comments
-------|----|-------- -------|----|--------
1.0.0|August 6, 2020|Initial release 1.0.0|August 6, 2020|Initial release
1.0.1|August 29, 2020|Additional updates 1.0.1|August 29, 2020|Additional updates
1.0.2|August 30, 2020|Bug Fix, new Properties
## Disclaimer ## Disclaimer

View File

@ -3,7 +3,7 @@
"solution": { "solution": {
"name": "react-my-sites-client-side-solution", "name": "react-my-sites-client-side-solution",
"id": "ad28b382-886b-4b2a-9646-92de8a0b1d13", "id": "ad28b382-886b-4b2a-9646-92de8a0b1d13",
"version": "1.0.1.0", "version": "1.0.2.0",
"includeClientSideAssets": true, "includeClientSideAssets": true,
"skipFeatureDeployment": true, "skipFeatureDeployment": true,
"isDomainIsolated": false, "isDomainIsolated": false,

View File

@ -1,6 +1,6 @@
{ {
"name": "react-my-sites", "name": "react-my-sites",
"version": "1.0.1", "version": "1.0.2.0",
"private": true, "private": true,
"main": "lib/index.js", "main": "lib/index.js",
"engines": { "engines": {

View File

@ -0,0 +1,22 @@
export interface ITeam {
guestSettings: GuestSettings;
memberSettings: GuestSettings;
messagingSettings: GuestSettings;
funSettings: GuestSettings;
discoverySettings: GuestSettings;
internalId: string;
isArchived: boolean;
webUrl: string;
displayName: string;
description: string;
classification: string;
specialization: string;
visibility: string;
classSettings: GuestSettings;
isMembershipLimitedToOwners: string;
id:string;
}
interface GuestSettings {
'@odata.type': string;
}

View File

@ -1,6 +1,10 @@
import { MSGraphClient, AadTokenProvider } from "@microsoft/sp-http"; import { MSGraphClient, AadTokenProvider } from "@microsoft/sp-http";
import { Filters } from "../Entities/EnumFilters"; import { Filters } from "../Entities/EnumFilters";
import { sp } from "@pnp/sp"; import { sp } from "@pnp/sp";
import "@pnp/sp/sites";
import { Web } from "@pnp/sp/webs";
import { Webs, IWebs } from "@pnp/sp/webs";
import { graph } from "@pnp/graph"; import { graph } from "@pnp/graph";
import { dateAdd, PnPClientStorage } from "@pnp/common"; import { dateAdd, PnPClientStorage } from "@pnp/common";
@ -10,8 +14,10 @@ import {
SearchResults, SearchResults,
SearchQueryBuilder, SearchQueryBuilder,
SortDirection, SortDirection,
ISearchResult
} from "@pnp/sp/search"; } from "@pnp/sp/search";
import { IWebInfo } from "@pnp/spfx-controls-react";
import {ITeam } from "../Entities/ITeam";
const storage = new PnPClientStorage(); const storage = new PnPClientStorage();
@ -62,10 +68,10 @@ export const useUserSites = () => {
case Filters.Group: case Filters.Group:
_filter = ` GroupId:a* OR GroupId:b* OR GroupId:c* OR GroupId:d* OR GroupId:e* OR GroupId:f* OR GroupId:g* OR GroupId:h* OR GroupId:i* OR GroupId:j* OR GroupId:k* OR GroupId:l* OR GroupId:m* OR GroupId:n* OR GroupId:o* OR GroupId:p* OR GroupId:q* OR GroupId:r* OR GroupId:s* OR GroupId:t* OR GroupId:u* OR GroupId:v* OR GroupId:w* OR GroupId:x* OR GroupId:y* OR GroupId:z* OR GroupId:1* OR GroupId:2* OR GroupId:3* OR GroupId:4* OR GroupId:5* OR GroupId:6* OR GroupId:7* OR GroupId:8* OR GroupId:9* OR GroupId:0*`; _filter = ` GroupId:a* OR GroupId:b* OR GroupId:c* OR GroupId:d* OR GroupId:e* OR GroupId:f* OR GroupId:g* OR GroupId:h* OR GroupId:i* OR GroupId:j* OR GroupId:k* OR GroupId:l* OR GroupId:m* OR GroupId:n* OR GroupId:o* OR GroupId:p* OR GroupId:q* OR GroupId:r* OR GroupId:s* OR GroupId:t* OR GroupId:u* OR GroupId:v* OR GroupId:w* OR GroupId:x* OR GroupId:y* OR GroupId:z* OR GroupId:1* OR GroupId:2* OR GroupId:3* OR GroupId:4* OR GroupId:5* OR GroupId:6* OR GroupId:7* OR GroupId:8* OR GroupId:9* OR GroupId:0*`;
break; break;
case Filters.OneDrive: /* case Filters.OneDrive:
_filter = " WebTemplate:SPSPERS"; // OneDrive _filter = " WebTemplate:SPSPERS"; // OneDrive
// _filter = " SiteGroup:Onedrive"; // _filter = " SiteGroup:Onedrive";
break; break; */
case Filters.SharePoint: case Filters.SharePoint:
_filter = _filter =
" SiteGroup:SharePoint AND NOT(GroupId:b* OR GroupId:c* OR GroupId:d* OR GroupId:e* OR GroupId:f* OR GroupId:g* OR GroupId:h* OR GroupId:i* OR GroupId:j* OR GroupId:k* OR GroupId:l* OR GroupId:m* OR GroupId:n* OR GroupId:o* OR GroupId:p* OR GroupId:q* OR GroupId:r* OR GroupId:s* OR GroupId:t* OR GroupId:u* OR GroupId:v* OR GroupId:w* OR GroupId:x* OR GroupId:y* OR GroupId:z* OR GroupId:1* OR GroupId:2* OR GroupId:3* OR GroupId:4* OR GroupId:5* OR GroupId:6* OR GroupId:7* OR GroupId:8* OR GroupId:9* OR GroupId:0*)"; " SiteGroup:SharePoint AND NOT(GroupId:b* OR GroupId:c* OR GroupId:d* OR GroupId:e* OR GroupId:f* OR GroupId:g* OR GroupId:h* OR GroupId:i* OR GroupId:j* OR GroupId:k* OR GroupId:l* OR GroupId:m* OR GroupId:n* OR GroupId:o* OR GroupId:p* OR GroupId:q* OR GroupId:r* OR GroupId:s* OR GroupId:t* OR GroupId:u* OR GroupId:v* OR GroupId:w* OR GroupId:x* OR GroupId:y* OR GroupId:z* OR GroupId:1* OR GroupId:2* OR GroupId:3* OR GroupId:4* OR GroupId:5* OR GroupId:6* OR GroupId:7* OR GroupId:8* OR GroupId:9* OR GroupId:0*)";
@ -77,7 +83,7 @@ export const useUserSites = () => {
} }
const q = SearchQueryBuilder( const q = SearchQueryBuilder(
`(contentclass:STS_Site OR contentclass:STS_Web) ${_filter} ${_searchString}` `(contentclass:STS_Site OR contentclass:STS_Web) AND -Webtemplate:SPSPERS* ${_filter} ${_searchString}`
) )
.rowLimit(itemsPerPage ? itemsPerPage : 20) .rowLimit(itemsPerPage ? itemsPerPage : 20)
.enableSorting.sortList({ .enableSorting.sortList({
@ -112,7 +118,7 @@ export const useUserSites = () => {
); );
const results = await sp.search(q); const results = await sp.search(q);
searchResults = results; // set the current results searchResults = results; // set the current results
console.log(searchResults);
return searchResults; return searchResults;
}; };
@ -122,7 +128,7 @@ const getUserWebs = async (
): Promise<SearchResults> => { ): Promise<SearchResults> => {
let searchResults: SearchResults = null; let searchResults: SearchResults = null;
const q = SearchQueryBuilder( const q = SearchQueryBuilder(
`(contentclass:STS_Web)` `(contentclass:STS_Web AND -Webtemplate:SPSPERS*)`
) )
.rowLimit(100000) .rowLimit(100000)
.selectProperties( .selectProperties(
@ -153,10 +159,100 @@ const getUserWebs = async (
); );
const results = await sp.search(q); const results = await sp.search(q);
searchResults = results; // set the current results searchResults = results; // set the current results
console.log("webs",searchResults);
return searchResults; return searchResults;
}; };
return { getUserSites, checkGroupHasTeam, getUserWebs }; // Get User Sites
const getUserGroups = async (
): Promise<SearchResults> => {
let searchResults: SearchResults = null;
const _filter = ` AND GroupId:a* OR GroupId:b* OR GroupId:c* OR GroupId:d* OR GroupId:e* OR GroupId:f* OR GroupId:g* OR GroupId:h* OR GroupId:i* OR GroupId:j* OR GroupId:k* OR GroupId:l* OR GroupId:m* OR GroupId:n* OR GroupId:o* OR GroupId:p* OR GroupId:q* OR GroupId:r* OR GroupId:s* OR GroupId:t* OR GroupId:u* OR GroupId:v* OR GroupId:w* OR GroupId:x* OR GroupId:y* OR GroupId:z* OR GroupId:1* OR GroupId:2* OR GroupId:3* OR GroupId:4* OR GroupId:5* OR GroupId:6* OR GroupId:7* OR GroupId:8* OR GroupId:9* OR GroupId:0*`;
const q = SearchQueryBuilder(
`(contentclass:STS_Site AND -Webtemplate:SPSPERS*) ${_filter}`
)
.rowLimit(100000)
.selectProperties(
"ParentLink",
"SPSiteURL",
"SiteID",
"SPWebUrl",
"WebId",
"SiteLogo",
"SiteClosed",
"RelatedHubSites",
"IsHubSite",
"GroupId",
"RelatedGroupId",
"SiteGroup",
"Author",
"CreatedBy",
"CreatedById",
"AccountName",
"ModifiedBy",
"ModifiedById",
"LastModifiedTime",
"OriginalPath",
"Path",
"Title",
"Created",
"WebTemplate"
);
const results = await sp.search(q);
searchResults = results; // set the current results
return searchResults;
};
// Get Properties for Web
const getSiteProperties = async (webUrl:string) : Promise<any> => {
const cachedWebIdValue:any = storage.local.get(webUrl);
if (!cachedWebIdValue){
const _openWeb = Web(webUrl);
const _webProps = await _openWeb();
storage.local.put(webUrl, _webProps, dateAdd(new Date(), "day", 1));
//we got all the data from the web as well
return _webProps.Title;
}
// we can chain
return cachedWebIdValue.Title;
};
const getUserTeams = async (userId:string,msGraphClient:MSGraphClient):Promise<ITeam[]> => {
const cachedListTeamsValue:ITeam[] = storage.local.get(userId);
if (!cachedListTeamsValue) {
try {
const _listOfTeams: any = await msGraphClient
.api(`/me/joinedTeams`)
.version("V1.0")
.get();
// put a value into storage with an expiration
storage.local.put(userId, _listOfTeams.value , dateAdd(new Date(), "day", 1));
return _listOfTeams.value as any[];
} catch (error) {
// put a value into storage with an expiration
storage.local.put(userId, [], dateAdd(new Date(), "day", 1));
return [];
}
}else{
// return cached value
return cachedListTeamsValue ;
}
};
return { getUserSites, checkGroupHasTeam, getUserWebs, getUserGroups, getSiteProperties, getUserTeams };
}; };

View File

@ -23,7 +23,10 @@
"officeFabricIconFontName": "SharepointLogo", "officeFabricIconFontName": "SharepointLogo",
"properties": { "properties": {
"title": "My Sites", "title": "My Sites",
"itemsPerPage": 20 "itemsPerPage": 20,
"enableFilterSharepointSites": true,
"enableFilterO365groups": true,
"enableFilterSitesWithSubWebs": true
} }
}] }]
} }

View File

@ -4,9 +4,12 @@ import { Version } from '@microsoft/sp-core-library';
import { import {
IPropertyPaneConfiguration, IPropertyPaneConfiguration,
PropertyPaneTextField, PropertyPaneTextField,
PropertyPaneSlider PropertyPaneSlider,
PropertyPaneLabel,
PropertyPaneHorizontalRule,
IPropertyPaneDropdownOption
} from '@microsoft/sp-property-pane'; } from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base'; import { BaseClientSideWebPart, PropertyPaneToggle, PropertyPaneCheckbox } from '@microsoft/sp-webpart-base';
import * as strings from 'MySitesWebPartStrings'; import * as strings from 'MySitesWebPartStrings';
import { MySites } from './components/MySites/MySites'; import { MySites } from './components/MySites/MySites';
@ -15,7 +18,17 @@ import { loadTheme } from "office-ui-fabric-react";
import { DisplayMode } from '@microsoft/sp-core-library'; import { DisplayMode } from '@microsoft/sp-core-library';
import { ThemeProvider, ThemeChangedEventArgs, IReadonlyTheme } from '@microsoft/sp-component-base'; import { ThemeProvider, ThemeChangedEventArgs, IReadonlyTheme } from '@microsoft/sp-component-base';
import { sp } from "@pnp/sp"; import { sp } from "@pnp/sp";
import { PropertyFieldSitePicker } from '@pnp/spfx-property-controls/lib/PropertyFieldSitePicker';
import { IPropertyFieldSite } from "@pnp/spfx-property-controls/lib/PropertyFieldSitePicker";
import { PropertyFieldMultiSelect } from '@pnp/spfx-property-controls/lib/PropertyFieldMultiSelect';
import { useUserSites } from '../../Hooks/useUserSites';
export interface IPropertyControlsTestWebPartProps {
sites: IPropertyFieldSite[];
}
import { graph } from "@pnp/graph"; import { graph } from "@pnp/graph";
import { ITeam } from '../../Entities/ITeam';
const teamsDefaultTheme = require("../../common/TeamsDefaultTheme.json"); const teamsDefaultTheme = require("../../common/TeamsDefaultTheme.json");
const teamsDarkTheme = require("../../common/TeamsDarkTheme.json"); const teamsDarkTheme = require("../../common/TeamsDarkTheme.json");
const teamsContrastTheme = require("../../common/TeamsContrastTheme.json"); const teamsContrastTheme = require("../../common/TeamsContrastTheme.json");
@ -26,11 +39,18 @@ export interface IMySitesWebPartProps {
displayMode: DisplayMode; displayMode: DisplayMode;
updateProperty: (value: string) => void; updateProperty: (value: string) => void;
itemsPerPage: number; itemsPerPage: number;
defaultSitesToFilter: IPropertyFieldSite[];
enableFilterSharepointSites:boolean;
enableFilterO365groups: boolean;
enableFilterSitesWithSubWebs: boolean;
DefaultTeamsToFilter: string[];
} }
export default class MySitesWebPart extends BaseClientSideWebPart<IMySitesWebPartProps> { export default class MySitesWebPart extends BaseClientSideWebPart<IMySitesWebPartProps> {
private _themeProvider: ThemeProvider; private _themeProvider: ThemeProvider;
private _themeVariant: IReadonlyTheme | undefined; private _themeVariant: IReadonlyTheme | undefined;
private _userTeamsOptions:IPropertyPaneDropdownOption[] = [];
protected async onInit(): Promise<void> { protected async onInit(): Promise<void> {
sp.setup({ sp.setup({
@ -51,12 +71,15 @@ export default class MySitesWebPart extends BaseClientSideWebPart<IMySitesWebPar
// in teams ? // in teams ?
const context = this.context.sdks.microsoftTeams!.context; const context = this.context.sdks.microsoftTeams!.context;
console.log('theme', this._themeVariant);
this._applyTheme(context.theme || "default"); this._applyTheme(context.theme || "default");
this.context.sdks.microsoftTeams.teamsJs.registerOnThemeChangeHandler( this.context.sdks.microsoftTeams.teamsJs.registerOnThemeChangeHandler(
this._applyTheme this._applyTheme
); );
} }
return Promise.resolve(); return Promise.resolve();
} }
@ -67,7 +90,7 @@ export default class MySitesWebPart extends BaseClientSideWebPart<IMySitesWebPar
*/ */
private _handleThemeChangedEvent(args: ThemeChangedEventArgs): void { private _handleThemeChangedEvent(args: ThemeChangedEventArgs): void {
this._themeVariant = args.theme; this._themeVariant = args.theme;
console.log('theme', this._themeVariant);
this.render(); this.render();
} }
@ -111,7 +134,11 @@ export default class MySitesWebPart extends BaseClientSideWebPart<IMySitesWebPar
itemsPerPage: this.properties.itemsPerPage, itemsPerPage: this.properties.itemsPerPage,
updateProperty: (value: string) => { updateProperty: (value: string) => {
this.properties.title = value; this.properties.title = value;
} },
defaultSitesToFilter: this.properties.defaultSitesToFilter,
enableFilterSharepointSites: this.properties.enableFilterSharepointSites,
enableFilterO365groups: this.properties.enableFilterO365groups,
enableFilterSitesWithSubWebs: this.properties.enableFilterSitesWithSubWebs
} }
); );
@ -130,6 +157,20 @@ export default class MySitesWebPart extends BaseClientSideWebPart<IMySitesWebPar
return true; return true;
} }
protected async onPropertyPaneConfigurationStart() {
const { getUserTeams } = useUserSites();
const _msGraphClient = await this.context.msGraphClientFactory.getClient();
const _userTeams:ITeam[] = await getUserTeams(this.context.pageContext.user.loginName, _msGraphClient);
for (const _team of _userTeams) {
this._userTeamsOptions.push({key: _team.id, text: _team.displayName });
}
this.context.propertyPane.refresh();
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration { protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return { return {
pages: [ pages: [
@ -145,13 +186,34 @@ export default class MySitesWebPart extends BaseClientSideWebPart<IMySitesWebPar
label: strings.TitleFieldLabel, label: strings.TitleFieldLabel,
value: this.properties.title value: this.properties.title
}), }),
PropertyPaneLabel('',{
text: ''
}),
PropertyPaneSlider('itemsPerPage', { PropertyPaneSlider('itemsPerPage', {
min: 1, min: 1,
max: 100, max: 100,
value: this.properties.itemsPerPage, value: this.properties.itemsPerPage,
step: 1, step: 1,
label: strings.ItemsPerPageLabel, label: strings.ItemsPerPageLabel,
}) }),
PropertyPaneLabel('',{
text: 'Filter scopes'
}),
PropertyPaneHorizontalRule(),
PropertyPaneCheckbox('enableFilterSharepointSites',{
checked: this.properties.enableFilterSharepointSites,
text: 'Filter SharePoint Sites',
}),
PropertyPaneCheckbox('enableFilterO365groups',{
checked: this.properties.enableFilterO365groups,
text: 'Filter Office 365 Groups'
}),
PropertyPaneCheckbox('enableFilterSitesWithSubWebs',{
checked: this.properties.enableFilterSitesWithSubWebs,
text: 'Filter sites with sub sites'
}),
] ]
} }
] ]

View File

@ -1,6 +1,7 @@
import { IReadonlyTheme } from '@microsoft/sp-component-base'; import { IReadonlyTheme } from '@microsoft/sp-component-base';
import { WebPartContext } from "@microsoft/sp-webpart-base"; import { WebPartContext } from "@microsoft/sp-webpart-base";
import { DisplayMode } from "@microsoft/sp-core-library"; import { DisplayMode } from "@microsoft/sp-core-library";
import { IPropertyFieldSite } from '@pnp/spfx-property-controls/lib/PropertyFieldSitePicker';
export interface IMySitesProps { export interface IMySitesProps {
title: string; title: string;
context: WebPartContext; context: WebPartContext;
@ -8,5 +9,9 @@ export interface IMySitesProps {
displayMode: DisplayMode; displayMode: DisplayMode;
updateProperty: (value: string) => void; updateProperty: (value: string) => void;
itemsPerPage:number; itemsPerPage:number;
defaultSitesToFilter: IPropertyFieldSite[];
enableFilterSharepointSites:boolean;
enableFilterO365groups: boolean;
enableFilterSitesWithSubWebs: boolean;
} }

View File

@ -36,7 +36,7 @@ let _msGraphClient: MSGraphClient = undefined;
let _filterMenuProps: IContextualMenuProps = undefined; let _filterMenuProps: IContextualMenuProps = undefined;
// Get Hook functions // Get Hook functions
const { getUserSites, getUserWebs } = useUserSites(); const { getUserSites, getUserWebs, getUserGroups, getSiteProperties } = useUserSites();
export const MySites: React.FunctionComponent<IMySitesProps> = ( export const MySites: React.FunctionComponent<IMySitesProps> = (
props: IMySitesProps props: IMySitesProps
@ -44,7 +44,7 @@ export const MySites: React.FunctionComponent<IMySitesProps> = (
// Global Compoment Styles // Global Compoment Styles
const stylesComponent = mergeStyleSets({ const stylesComponent = mergeStyleSets({
containerTiles: { containerTiles: {
marginTop: 25, marginTop: 5,
display: "grid", display: "grid",
marginBottom: 10, marginBottom: 10,
gridTemplateColumns: "repeat( auto-fit, minmax(300px, 1fr) )", gridTemplateColumns: "repeat( auto-fit, minmax(300px, 1fr) )",
@ -133,9 +133,9 @@ export const MySites: React.FunctionComponent<IMySitesProps> = (
case "Groups": case "Groups":
await _getUserSites("", Filters.Group, "Groups"); await _getUserSites("", Filters.Group, "Groups");
break; break;
case "OneDrive": /* case "OneDrive":
await _getUserSites("", Filters.OneDrive, "OneDrive"); await _getUserSites("", Filters.OneDrive, "OneDrive");
break; break; */
case "SharePoint": case "SharePoint":
await _getUserSites("", Filters.SharePoint, "SharePoint"); await _getUserSites("", Filters.SharePoint, "SharePoint");
break; break;
@ -149,17 +149,17 @@ export const MySites: React.FunctionComponent<IMySitesProps> = (
React.useEffect(() => { React.useEffect(() => {
(async () => { (async () => {
_msGraphClient = await props.context.msGraphClientFactory.getClient(); _msGraphClient = await props.context.msGraphClientFactory.getClient();
const _sitesWithSubSties = await getUserWebs(); const _sitesWithSubSties = await getUserWebs();
console.log("subsites", _sitesWithSubSties);
const _uniqweb = _.uniqBy( const _uniqweb = _.uniqBy(
_sitesWithSubSties.PrimarySearchResults, _sitesWithSubSties.PrimarySearchResults,
"ParentLink" "ParentLink"
); );
const {enableFilterO365groups, enableFilterSharepointSites, enableFilterSitesWithSubWebs } = props;
_filterMenuProps = { _filterMenuProps = {
items: [ items: [
{ {
key: "0", key: "0",
@ -174,7 +174,13 @@ export const MySites: React.FunctionComponent<IMySitesProps> = (
_Filtersites(item.text); _Filtersites(item.text);
}, },
}, },
{ ],
};
if( enableFilterSharepointSites ) {
_filterMenuProps.items.push({
key: "1", key: "1",
text: "SharePoint", text: "SharePoint",
iconProps: { iconName: "SharepointAppIcon16" }, iconProps: { iconName: "SharepointAppIcon16" },
@ -185,52 +191,41 @@ export const MySites: React.FunctionComponent<IMySitesProps> = (
item: IContextualMenuItem item: IContextualMenuItem
) => { ) => {
_Filtersites(item.text); _Filtersites(item.text);
}, }
}, }
{ );
key: "2", }
text: "Groups",
iconProps: { iconName: "Group" },
onClick: (
ev:
| React.MouseEvent<HTMLElement, MouseEvent>
| React.KeyboardEvent<HTMLElement>,
item: IContextualMenuItem
) => {
_Filtersites(item.text);
},
},
{
key: "3",
text: "OneDrive",
iconProps: { iconName: "onedrive" },
onClick: (
ev:
| React.MouseEvent<HTMLElement, MouseEvent>
| React.KeyboardEvent<HTMLElement>,
item: IContextualMenuItem
) => {
_Filtersites(item.text);
},
},
],
};
if( enableFilterO365groups ) {
_filterMenuProps.items.push({
key: "2",
text: "Groups",
iconProps: { iconName: "Group" },
onClick: (
ev:
| React.MouseEvent<HTMLElement, MouseEvent>
| React.KeyboardEvent<HTMLElement>,
item: IContextualMenuItem
) => {
_Filtersites(item.text);
}
}
);
}
if (_sitesWithSubSties.PrimarySearchResults.length > 0){ if (enableFilterSitesWithSubWebs && _sitesWithSubSties.PrimarySearchResults.length > 0){
_filterMenuProps.items.push( _filterMenuProps.items.push(
{ {
key: 'sites', key: 'sites',
itemType: ContextualMenuItemType.Header, itemType: ContextualMenuItemType.Header,
text: 'Sites with Sub Sites', text: 'Sites with sub sites',
itemProps: { itemProps: {
lang: 'en-us', lang: 'en-us',
}, },
} }
); );
}
// Add Site Collections with sub // Add Site Collections with sub
for (const web of _uniqweb) { for (const web of _uniqweb) {
// tslint:disable-next-line: no-use-before-declare // tslint:disable-next-line: no-use-before-declare
const _lastHasPosition: number = (web.ParentLink as string).lastIndexOf( const _lastHasPosition: number = (web.ParentLink as string).lastIndexOf(
@ -239,10 +234,13 @@ export const MySites: React.FunctionComponent<IMySitesProps> = (
const _siteName: string = (web.ParentLink as string).substring( const _siteName: string = (web.ParentLink as string).substring(
_lastHasPosition + 1 _lastHasPosition + 1
); );
const _webTitle = await getSiteProperties(web.ParentLink);
// tslint:disable-next-line: no-use-before-declare // tslint:disable-next-line: no-use-before-declare
_filterMenuProps.items.push({ _filterMenuProps.items.push({
key: web.ParentLink, key: web.ParentLink,
text: _siteName, text: _webTitle,
iconProps: { iconName: "DrillExpand" }, iconProps: { iconName: "DrillExpand" },
onClick: ( onClick: (
ev: ev:
@ -255,9 +253,11 @@ export const MySites: React.FunctionComponent<IMySitesProps> = (
}, },
}); });
} }
}
await _getUserSites("", state.currentFilter, state.currentFilterName); await _getUserSites("", state.currentFilter, state.currentFilterName);
})(); })();
}, [props.title, props.itemsPerPage]); }, [props]);
// On Search Sites // On Search Sites
const _onSearch = async (value: string) => { const _onSearch = async (value: string) => {
@ -290,14 +290,17 @@ export const MySites: React.FunctionComponent<IMySitesProps> = (
updateProperty={props.updateProperty} updateProperty={props.updateProperty}
className={stylesComponent.webPartTile} className={stylesComponent.webPartTile}
/> />
<Stack horizontal verticalAlign="center" horizontalAlign="end" wrap tokens={{ childrenGap: 5 }}> <Stack horizontal verticalAlign="center" horizontalAlign='start' styles={{root:{width: '100%'}}}>
<SearchBox <SearchBox
placeholder="Search my sites" placeholder="Search my sites"
underlined={true} styles={{root:{width:'100%', marginBottom: 10}}}
value={state.searchValue} value={state.searchValue}
onSearch={_onSearch} onSearch={_onSearch}
onClear={_onClear} onClear={_onClear}
/> />
</Stack>
<Stack horizontal verticalAlign="center" horizontalAlign="end" wrap tokens={{ childrenGap: 5 }}>
<CommandButton <CommandButton
iconProps={{ iconName: "refresh" }} iconProps={{ iconName: "refresh" }}
onClick={_onClear} onClick={_onClear}
@ -329,6 +332,7 @@ export const MySites: React.FunctionComponent<IMySitesProps> = (
site={site} site={site}
msGraphClient={_msGraphClient} msGraphClient={_msGraphClient}
themeVariant={props.themeVariant} themeVariant={props.themeVariant}
locale={props.context.pageContext.cultureInfo.currentCultureName}
></SiteTile> ></SiteTile>
); );
})} })}
@ -367,6 +371,8 @@ export const MySites: React.FunctionComponent<IMySitesProps> = (
color="primary" color="primary"
count={state.totalPages} count={state.totalPages}
page={state.currentPage} page={state.currentPage}
size="small"
siblingCount={0}
onChange={async (event: any, page: number) => { onChange={async (event: any, page: number) => {
const rs = await _searchResults.getPage(page); const rs = await _searchResults.getPage(page);
_searchResults = rs; _searchResults = rs;

View File

@ -5,4 +5,5 @@ export interface ISiteTileProps {
msGraphClient:MSGraphClient; msGraphClient:MSGraphClient;
site:any; site:any;
themeVariant: IReadonlyTheme | undefined; themeVariant: IReadonlyTheme | undefined;
locale:string;
} }

View File

@ -130,15 +130,16 @@ export const SiteTile: React.FunctionComponent<ISiteTileProps> = (
// Use Effect on Mounting // Use Effect on Mounting
React.useEffect(() => { React.useEffect(() => {
(async () => { (async () => {
if (ModifiedById) { if (ModifiedById && LastModifiedTime) {
const _modifiedBySplit = ModifiedById.split("|"); const _modifiedBySplit = ModifiedById.split("|");
_activityUserEmail = _modifiedBySplit[0].trim(); _activityUserEmail = _modifiedBySplit[0].trim();
_activityUser = _modifiedBySplit[1].trim(); _activityUser = _modifiedBySplit[1].trim();
_activityDate = new Date(LastModifiedTime).toLocaleString(); const _lastModified = new Date(LastModifiedTime);
_activityDate = _lastModified.toLocaleDateString() + ' ' + _lastModified.toLocaleTimeString();
_activityMessage = `${strings.ChangedOnLabel}${_activityDate}`; _activityMessage = `${strings.ChangedOnLabel}${_activityDate}`;
try { try {
if (_activityUserEmail) { if (_activityUserEmail) {
console.log(_activityUserEmail);
_userPhoto = await getUserPhoto(_activityUserEmail); _userPhoto = await getUserPhoto(_activityUserEmail);
} }
} catch (error) { } catch (error) {
@ -148,7 +149,9 @@ export const SiteTile: React.FunctionComponent<ISiteTileProps> = (
} else { } else {
_activityUserEmail = undefined; _activityUserEmail = undefined;
_activityUser = CreatedBy; _activityUser = CreatedBy;
_activityDate = new Date(Created).toLocaleString(); const _lastCreated = new Date(Created);
_activityDate = _lastCreated.toLocaleDateString() + ' ' + _lastCreated.toLocaleTimeString();
_activityMessage = `${strings.CreatedOnLabel}${_activityDate}`; _activityMessage = `${strings.CreatedOnLabel}${_activityDate}`;
_userPhoto = undefined; _userPhoto = undefined;
} }
@ -189,6 +192,7 @@ export const SiteTile: React.FunctionComponent<ISiteTileProps> = (
styles={documentCardStyles} styles={documentCardStyles}
type={DocumentCardType.compact} type={DocumentCardType.compact}
onClickHref={OriginalPath} onClickHref={OriginalPath}
onClickTarget={"_blank"}
> >
{props.site.SiteLogo ? ( {props.site.SiteLogo ? (
<DocumentCardPreview <DocumentCardPreview
@ -244,13 +248,13 @@ export const SiteTile: React.FunctionComponent<ISiteTileProps> = (
title="is Hub Site" title="is Hub Site"
></Icon> ></Icon>
)} )}
{WebTemplate == "SPSPERS" && ( {/* {WebTemplate == "SPSPERS" && (
<Icon <Icon
styles={groupIconStyles} styles={groupIconStyles}
iconName="onedrive" iconName="onedrive"
title="User OneDrive" title="User OneDrive"
></Icon> ></Icon>
)} )} */}
{SiteGroup == "SharePoint" && !GroupId && ( {SiteGroup == "SharePoint" && !GroupId && (
<Icon <Icon
styles={groupIconStyles} styles={groupIconStyles}
@ -259,13 +263,13 @@ export const SiteTile: React.FunctionComponent<ISiteTileProps> = (
></Icon> ></Icon>
)} )}
</div> </div>
<TooltipHost content={activityMessage} calloutProps={{gapSpace:5}}> <div title={activityMessage} >
<DocumentCardActivity <DocumentCardActivity
styles={DocumentCardActivityStyles} styles={DocumentCardActivityStyles}
activity={activityMessage} activity={activityMessage}
people={[{ name: activityUser, profileImageSrc: userPhoto }]} people={[{ name: activityUser, profileImageSrc: userPhoto }]}
/> />
</TooltipHost> </div>
</DocumentCardDetails> </DocumentCardDetails>
</DocumentCard> </DocumentCard>
</> </>

View File

@ -4,7 +4,7 @@ define([], function() {
ChangedOnLabel: "Changed on ", ChangedOnLabel: "Changed on ",
RefreshLabel: "Refresh", RefreshLabel: "Refresh",
LoadingLabel: "Loading...", LoadingLabel: "Loading...",
"PropertyPaneDescription": "List sites user has permissions, Include SharePoint Sites, Office365 Groups, OneDrive, Add-Ins App Sites", "PropertyPaneDescription": "List sites user has permissions, Include SharePoint Sites, Office365 Groups, Add-Ins App Sites",
"BasicGroupName": "Properties", "BasicGroupName": "Properties",
"TitleFieldLabel": "Title", "TitleFieldLabel": "Title",
"ItemsPerPageLabel": "Number items per page" "ItemsPerPageLabel": "Number items per page"