Added Grid layout and adjusted compact layout
This commit is contained in:
parent
800f21cd14
commit
15bea4986c
|
@ -19,7 +19,14 @@ extensions:
|
||||||
|
|
||||||
Using Microsoft Graph, this webpart grabs the Office 365 groups the current user is a member of with links to the groups SharePoint site.
|
Using Microsoft Graph, this webpart grabs the Office 365 groups the current user is a member of with links to the groups SharePoint site.
|
||||||
|
|
||||||
![Demo](./assets/example.png)
|
The webpart has been updated to include a grid like in addition to the compact layout as seen below:
|
||||||
|
![Grid Demo](./assets/React-MyGroups_Grid.png)
|
||||||
|
|
||||||
|
Compact Layout:
|
||||||
|
![Compact Demo](./assets/React-MyGroups_Compact.png)
|
||||||
|
|
||||||
|
You can change between the grid and compact layout through the settings in the property pane:
|
||||||
|
![Property Pane Demo](./assets/React-MyGroups_Property.png)
|
||||||
|
|
||||||
## Used SharePoint Framework Version
|
## Used SharePoint Framework Version
|
||||||
|
|
||||||
|
@ -42,6 +49,7 @@ Version|Date|Comments
|
||||||
-------|----|--------
|
-------|----|--------
|
||||||
1.0|September 13, 2019|Initial release
|
1.0|September 13, 2019|Initial release
|
||||||
1.1|June 1, 2020| Updated to SPFX 1.10.0
|
1.1|June 1, 2020| Updated to SPFX 1.10.0
|
||||||
|
1.2|July 8, 2020| Added Grid Layout
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 51 KiB |
|
@ -2,13 +2,14 @@ import * as React from 'react';
|
||||||
import * as ReactDom from 'react-dom';
|
import * as ReactDom from 'react-dom';
|
||||||
import { Version } from '@microsoft/sp-core-library';
|
import { Version } from '@microsoft/sp-core-library';
|
||||||
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
|
||||||
import { IPropertyPaneConfiguration, PropertyPaneTextField } from "@microsoft/sp-property-pane";
|
import { IPropertyPaneConfiguration, PropertyPaneTextField, PropertyPaneChoiceGroup } from "@microsoft/sp-property-pane";
|
||||||
import GroupService from '../../services/GroupService';
|
import GroupService from '../../services/GroupService';
|
||||||
import * as strings from 'ReactMyGroupsWebPartStrings';
|
import * as strings from 'ReactMyGroupsWebPartStrings';
|
||||||
import { ReactMyGroups, IReactMyGroupsProps } from './components';
|
import { ReactMyGroups, IReactMyGroupsProps } from './components';
|
||||||
|
|
||||||
export interface IReactMyGroupsWebPartProps {
|
export interface IReactMyGroupsWebPartProps {
|
||||||
description: string;
|
title: string;
|
||||||
|
layout: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ReactMyGroupsWebPart extends BaseClientSideWebPart<IReactMyGroupsWebPartProps> {
|
export default class ReactMyGroupsWebPart extends BaseClientSideWebPart<IReactMyGroupsWebPartProps> {
|
||||||
|
@ -17,7 +18,8 @@ export default class ReactMyGroupsWebPart extends BaseClientSideWebPart<IReactMy
|
||||||
const element: React.ReactElement<IReactMyGroupsProps > = React.createElement(
|
const element: React.ReactElement<IReactMyGroupsProps > = React.createElement(
|
||||||
ReactMyGroups,
|
ReactMyGroups,
|
||||||
{
|
{
|
||||||
description: this.properties.description
|
title: this.properties.title,
|
||||||
|
layout: this.properties.layout
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -39,6 +41,7 @@ export default class ReactMyGroupsWebPart extends BaseClientSideWebPart<IReactMy
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||||
|
const { layout } = this.properties;
|
||||||
return {
|
return {
|
||||||
pages: [
|
pages: [
|
||||||
{
|
{
|
||||||
|
@ -49,8 +52,26 @@ export default class ReactMyGroupsWebPart extends BaseClientSideWebPart<IReactMy
|
||||||
{
|
{
|
||||||
groupName: strings.BasicGroupName,
|
groupName: strings.BasicGroupName,
|
||||||
groupFields: [
|
groupFields: [
|
||||||
PropertyPaneTextField('description', {
|
PropertyPaneTextField('title', {
|
||||||
label: strings.DescriptionFieldLabel
|
label: 'Title'
|
||||||
|
}),
|
||||||
|
PropertyPaneChoiceGroup("layout", {
|
||||||
|
label: 'Layout Option',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
key: "Grid",
|
||||||
|
text: "Grid",
|
||||||
|
iconProps: { officeFabricIconFontName: "GridViewSmall"},
|
||||||
|
checked: layout === "Grid" ? true : false,
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "Compact",
|
||||||
|
text: "Compact",
|
||||||
|
iconProps: { officeFabricIconFontName: "BulletedList2"},
|
||||||
|
checked: layout === "Compact" ? true : false
|
||||||
|
}
|
||||||
|
]
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
@import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss";
|
||||||
|
|
||||||
|
:export {
|
||||||
|
padding: 20;
|
||||||
|
minWidth: 210;
|
||||||
|
maxWidth: 320;
|
||||||
|
compactThreshold: 480;
|
||||||
|
rowsPerPage: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gridLayout {
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 0;
|
||||||
|
position: relative;
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
:global(.ms-DocumentCard) {
|
||||||
|
position: relative;
|
||||||
|
background-color: $ms-color-white;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&:global(.ms-DocumentCard--compact) {
|
||||||
|
:global(.ms-DocumentCardPreview) {
|
||||||
|
-ms-flex-negative: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 144px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ms-DocumentCardPreview-icon) img {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ms-DocumentCard:not(.ms-DocumentCard--compact)) {
|
||||||
|
min-width: 212px;
|
||||||
|
max-width: 286px;
|
||||||
|
|
||||||
|
:global(.ms-DocumentCardActivity) {
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ms-DocumentCardTile-titleArea) {
|
||||||
|
height: 81px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ms-DocumentCardLocation) {
|
||||||
|
padding: 12px 16px 5px 16px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ms-List-cell) {
|
||||||
|
vertical-align: top;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import styles from './GridLayout.module.scss';
|
||||||
|
|
||||||
|
// Used to render list grid
|
||||||
|
import { FocusZone } from 'office-ui-fabric-react/lib/FocusZone';
|
||||||
|
import { List } from 'office-ui-fabric-react/lib/List';
|
||||||
|
import { IRectangle, ISize } from 'office-ui-fabric-react/lib/Utilities';
|
||||||
|
import { Spinner } from 'office-ui-fabric-react';
|
||||||
|
|
||||||
|
import { IGridLayoutProps, IGridLayoutState } from './GridLayout.types';
|
||||||
|
|
||||||
|
const ROWS_PER_PAGE: number = +styles.rowsPerPage;
|
||||||
|
const MAX_ROW_HEIGHT: number = +styles.maxWidth;
|
||||||
|
const PADDING: number = +styles.padding;
|
||||||
|
const MIN_WIDTH: number = +styles.minWidth;
|
||||||
|
const COMPACT_THRESHOLD: number = +styles.compactThreshold;
|
||||||
|
|
||||||
|
|
||||||
|
export class GridLayout extends React.Component<IGridLayoutProps, IGridLayoutState> {
|
||||||
|
constructor(props: IGridLayoutProps) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isLoading: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
private _columnCount: number;
|
||||||
|
private _columnWidth: number;
|
||||||
|
private _rowHeight: number;
|
||||||
|
private _isCompact: boolean;
|
||||||
|
|
||||||
|
public render(): React.ReactElement<IGridLayoutProps> {
|
||||||
|
return (
|
||||||
|
<div role="group" aria-label={this.props.ariaLabel}>
|
||||||
|
<FocusZone>
|
||||||
|
<List
|
||||||
|
role="presentation"
|
||||||
|
className={styles.gridLayout}
|
||||||
|
items={this.props.items}
|
||||||
|
getItemCountForPage={this._getItemCountForPage}
|
||||||
|
getPageHeight={this._getPageHeight}
|
||||||
|
onRenderCell={this._onRenderCell}
|
||||||
|
{...this.props.listProps}
|
||||||
|
/>
|
||||||
|
</FocusZone>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public componentDidMount = (): void => {
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getItemCountForPage = (itemIndex: number, surfaceRect: IRectangle): number => {
|
||||||
|
if (itemIndex === 0) {
|
||||||
|
this._isCompact = surfaceRect.width < COMPACT_THRESHOLD;
|
||||||
|
if (this._isCompact) {
|
||||||
|
this._columnCount = 1;
|
||||||
|
this._columnWidth = surfaceRect.width;
|
||||||
|
} else {
|
||||||
|
this._columnCount = Math.ceil(surfaceRect.width / (MAX_ROW_HEIGHT));
|
||||||
|
this._columnWidth = Math.max(MIN_WIDTH, Math.floor(surfaceRect.width / this._columnCount) + Math.floor(PADDING / this._columnCount));
|
||||||
|
this._rowHeight = this._columnWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._columnCount * ROWS_PER_PAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getPageHeight = (): number => {
|
||||||
|
return this._rowHeight * ROWS_PER_PAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onRenderCell = (item: any, index: number | undefined): JSX.Element => {
|
||||||
|
console.log(item.displayName);
|
||||||
|
const isCompact: boolean = this._isCompact;
|
||||||
|
const cellPadding: number = index % this._columnCount !== this._columnCount - 1 && !isCompact ? PADDING : 0;
|
||||||
|
const finalSize: ISize = { width: this._columnWidth, height: this._rowHeight };
|
||||||
|
const cellWidth: number = isCompact ? this._columnWidth + PADDING : this._columnWidth - PADDING;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: `${cellWidth}px`,
|
||||||
|
marginRight: `${cellPadding}px`
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{this.props.onRenderGridItem(item, finalSize, isCompact)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { ISize } from 'office-ui-fabric-react/lib/Utilities';
|
||||||
|
import { IListProps } from 'office-ui-fabric-react/lib/List';
|
||||||
|
|
||||||
|
export interface IGridLayoutProps {
|
||||||
|
/**
|
||||||
|
* Accessible text for the grid layout
|
||||||
|
*/
|
||||||
|
ariaLabel?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The array of items to display
|
||||||
|
*/
|
||||||
|
items: any[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In case you want to override the underlying list
|
||||||
|
*/
|
||||||
|
listProps?: Partial<IListProps>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The method to render each cell item
|
||||||
|
*/
|
||||||
|
onRenderGridItem: (item: any, finalSize: ISize, isCompact: boolean) => JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IGridLayoutState {
|
||||||
|
isLoading?: boolean;
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './GridLayout.types';
|
||||||
|
export * from './GridLayout';
|
|
@ -1,12 +1,14 @@
|
||||||
@import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss";
|
@import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss";
|
||||||
|
|
||||||
:export {
|
:export {
|
||||||
padding: 20;
|
padding: 5;
|
||||||
minWidth: 210;
|
minWidth: 210;
|
||||||
maxWidth: 320;
|
maxWidth: 320;
|
||||||
rowsPerPage: 3;
|
rowsPerPage: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.compactLayout {
|
.compactLayout {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
|
@ -44,6 +46,5 @@
|
||||||
:global(.ms-List-cell) {
|
:global(.ms-List-cell) {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
export interface IReactMyGroupsProps {
|
export interface IReactMyGroupsProps {
|
||||||
description: string;
|
title: string;
|
||||||
|
layout: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,5 @@ import * as MicrosoftGroup from '@microsoft/microsoft-graph-types';
|
||||||
|
|
||||||
export interface IReactMyGroupsState {
|
export interface IReactMyGroupsState {
|
||||||
groups: MicrosoftGroup.Group[];
|
groups: MicrosoftGroup.Group[];
|
||||||
|
isLoading: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,131 @@
|
||||||
|
|
||||||
.reactMyGroups {
|
.reactMyGroups {
|
||||||
|
|
||||||
|
.compactContainer {
|
||||||
|
margin: 0px 5px 5px;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compactA {
|
||||||
|
outline: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
margin-top: 4px;
|
||||||
|
width: 251.333px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compactWrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compactBanner {
|
||||||
|
margin-right: 12px;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compactDetails {
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.compactTitle {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 6px 0;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: rgb(50,49,48);
|
||||||
|
display: block;
|
||||||
|
margin-block-start: 1em;
|
||||||
|
margin-block-end: 1em;
|
||||||
|
margin-inline-start: 0px;
|
||||||
|
margin-inline-end: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardContainer{
|
||||||
|
outline: transparent;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.siteCard {
|
||||||
|
height: 200px;
|
||||||
|
max-width: 286px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
outline: transparent;
|
||||||
|
position: relative;
|
||||||
|
background-color: rgb(255, 255, 255);
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.133) 0px 1.6px 3.6px 0px, rgba(0, 0, 0, 0.11) 0px 0.3px 0.9px 0px;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-image: initial;
|
||||||
|
border-radius: 2px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-color: rgb(237, 235, 233);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardBanner {
|
||||||
|
position: relative;
|
||||||
|
height: 144px;
|
||||||
|
padding-top: 40px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardTitle {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-top: 28px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 20px;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
box-sizing: content-box;
|
||||||
|
max-height: 2.7em;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: left;
|
||||||
|
padding: 0 12px;
|
||||||
|
color: rgb(50, 49, 48);
|
||||||
|
}
|
||||||
|
|
||||||
|
.topBanner {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
height: 40px;
|
||||||
|
width: 100%;;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bannerImg {
|
||||||
|
position: absolute;
|
||||||
|
top: 12px;
|
||||||
|
left: 12px;
|
||||||
|
height: 48px;
|
||||||
|
width: 48px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
box-shadow: 0 0 4px 0 rgba(0,0,0,.2);
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-image: initial;
|
||||||
|
border-color: rgb(255,255,255);
|
||||||
|
background-position: 50%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docTile {
|
||||||
|
background-color: transparent;
|
||||||
|
outline: transparent;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
@ -28,8 +153,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include ms-font-xl;
|
text-align: left;
|
||||||
@include ms-fontColor-white;
|
color: rgb(50, 49, 48);
|
||||||
|
white-space: pre-wrap;
|
||||||
|
font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-right: 32px;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subTitle {
|
.subTitle {
|
||||||
|
|
|
@ -6,7 +6,10 @@ import GroupService from '../../../../services/GroupService';
|
||||||
import { IReactMyGroupsState } from './IReactMyGroupsState';
|
import { IReactMyGroupsState } from './IReactMyGroupsState';
|
||||||
import { GroupList } from '../GroupList';
|
import { GroupList } from '../GroupList';
|
||||||
import { IGroup } from '../../../../models';
|
import { IGroup } from '../../../../models';
|
||||||
import { DocumentCard, DocumentCardType, DocumentCardDetails, DocumentCardTitle, IDocumentCardPreviewProps, ImageFit, DocumentCardPreview } from 'office-ui-fabric-react';
|
import { Spinner, DocumentCard, DocumentCardType, DocumentCardDetails, DocumentCardTitle, IDocumentCardPreviewProps, ImageFit, DocumentCardPreview, IconFontSizes, ISize, isVirtualElement, DocumentCardLocation, DocumentCardActivity } from 'office-ui-fabric-react';
|
||||||
|
import { GridLayout } from '../GridList';
|
||||||
|
|
||||||
|
const colors = ['#17717A','#4A69DB','#303952','#A4262C','#3A96DD','#CA5010','#8764B8','#498205','#69797E'];
|
||||||
|
|
||||||
export class ReactMyGroups extends React.Component<IReactMyGroupsProps, IReactMyGroupsState> {
|
export class ReactMyGroups extends React.Component<IReactMyGroupsProps, IReactMyGroupsState> {
|
||||||
|
|
||||||
|
@ -14,7 +17,8 @@ export class ReactMyGroups extends React.Component<IReactMyGroupsProps, IReactMy
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
groups: []
|
groups: [],
|
||||||
|
isLoading: true
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,8 +26,17 @@ export class ReactMyGroups extends React.Component<IReactMyGroupsProps, IReactMy
|
||||||
public render(): React.ReactElement<IReactMyGroupsProps> {
|
public render(): React.ReactElement<IReactMyGroupsProps> {
|
||||||
return (
|
return (
|
||||||
<div className={ styles.reactMyGroups }>
|
<div className={ styles.reactMyGroups }>
|
||||||
<h1>My Office 365 Groups</h1>
|
<div className={styles.title} role="heading" aria-level={2}>{this.props.title} </div>
|
||||||
|
{this.state.isLoading ?
|
||||||
|
<Spinner label="Loading sites..." />
|
||||||
|
:
|
||||||
|
<div>
|
||||||
|
{this.props.layout == 'Compact' ?
|
||||||
<GroupList groups={this.state.groups} onRenderItem={(item: any, index: number) => this._onRenderItem(item, index)}/>
|
<GroupList groups={this.state.groups} onRenderItem={(item: any, index: number) => this._onRenderItem(item, index)}/>
|
||||||
|
: <GridLayout items={this.state.groups} onRenderGridItem={(item: any, finalSize: ISize, isCompact: boolean) => this._onRenderGridItem(item, finalSize, isCompact)}/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +47,6 @@ export class ReactMyGroups extends React.Component<IReactMyGroupsProps, IReactMy
|
||||||
|
|
||||||
public _getGroups = (): void => {
|
public _getGroups = (): void => {
|
||||||
GroupService.getGroups().then(groups => {
|
GroupService.getGroups().then(groups => {
|
||||||
// console.log(groups);
|
|
||||||
this.setState({
|
this.setState({
|
||||||
groups: groups
|
groups: groups
|
||||||
});
|
});
|
||||||
|
@ -45,7 +57,6 @@ export class ReactMyGroups extends React.Component<IReactMyGroupsProps, IReactMy
|
||||||
public _getGroupLinks = (groups: any): void => {
|
public _getGroupLinks = (groups: any): void => {
|
||||||
groups.map(groupItem => (
|
groups.map(groupItem => (
|
||||||
GroupService.getGroupLinks(groupItem).then(groupurl => {
|
GroupService.getGroupLinks(groupItem).then(groupurl => {
|
||||||
// console.log(groupurl.value);
|
|
||||||
this.setState(prevState => ({
|
this.setState(prevState => ({
|
||||||
groups: prevState.groups.map(group => group.id === groupItem.id ? {...group, url: groupurl.value} : group)
|
groups: prevState.groups.map(group => group.id === groupItem.id ? {...group, url: groupurl.value} : group)
|
||||||
}));
|
}));
|
||||||
|
@ -57,39 +68,44 @@ export class ReactMyGroups extends React.Component<IReactMyGroupsProps, IReactMy
|
||||||
public _getGroupThumbnails = (groups: any): void => {
|
public _getGroupThumbnails = (groups: any): void => {
|
||||||
groups.map(groupItem => (
|
groups.map(groupItem => (
|
||||||
GroupService.getGroupThumbnails(groupItem).then(grouptb => {
|
GroupService.getGroupThumbnails(groupItem).then(grouptb => {
|
||||||
console.log(grouptb);
|
//set group color:
|
||||||
|
const itemColor = colors[Math.floor(Math.random() * colors.length)];
|
||||||
this.setState(prevState => ({
|
this.setState(prevState => ({
|
||||||
groups: prevState.groups.map(group => group.id === groupItem.id ? {...group, thumbnail: grouptb} : group)
|
groups: prevState.groups.map(group => group.id === groupItem.id ? {...group, thumbnail: grouptb, color: itemColor} : group)
|
||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
console.log('Set False');
|
||||||
|
this.setState({
|
||||||
|
isLoading: false
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onRenderItem = (item: any, index: number): JSX.Element => {
|
private _onRenderItem = (item: any, index: number): JSX.Element => {
|
||||||
const previewProps: IDocumentCardPreviewProps = {
|
|
||||||
previewImages: [
|
|
||||||
{
|
|
||||||
previewImageSrc: item.thumbnail,
|
|
||||||
imageFit: ImageFit.center,
|
|
||||||
height: 48,
|
|
||||||
width: 48
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={styles.compactContainer}>
|
||||||
<DocumentCard
|
<a className={styles.compactA} href={item.url}>
|
||||||
type={DocumentCardType.compact}
|
<div className={styles.compactWrapper}>
|
||||||
>
|
<img className={styles.compactBanner} src={item.thumbnail} />
|
||||||
<DocumentCardPreview {...previewProps} />
|
<div className={styles.compactDetails}>
|
||||||
<DocumentCardDetails>
|
<div className={styles.compactTitle}>{item.displayName}</div>
|
||||||
<a href={item.url}>
|
</div>
|
||||||
<DocumentCardTitle
|
</div>
|
||||||
title={item.displayName}
|
</a>
|
||||||
/>
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onRenderGridItem = (item: any, finalSize: ISize, isCompact: boolean): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<div className={styles.siteCard}>
|
||||||
|
<a href={item.url}>
|
||||||
|
<div className={styles.cardBanner}>
|
||||||
|
<div className={styles.topBanner} style={{backgroundColor: item.color}}></div>
|
||||||
|
<img className={styles.bannerImg} src={item.thumbnail} />
|
||||||
|
<div className={styles.cardTitle}>{item.displayName}</div>
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</DocumentCardDetails>
|
|
||||||
</DocumentCard>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue