Merge pull request #1765 from joaojmendes/master
This commit is contained in:
commit
329f20d196
|
@ -23,6 +23,8 @@ extensions:
|
|||
This web part shows the current user's colleagues, and allows the user to search AD directory, The user can configure the properties to show when expand the user card.
|
||||
|
||||
![staff](./assets/staffdirectory.gif)
|
||||
![staff](./assets/staffTeams01.png)
|
||||
![staff](./assets/staffTeams02.png)
|
||||
|
||||
## Compatibility
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 484 KiB |
Binary file not shown.
After Width: | Height: | Size: 446 KiB |
|
@ -49,7 +49,7 @@
|
|||
"jest": "^23.6.0",
|
||||
"jest-junit": "^10.0.0",
|
||||
"lodash": "^4.17.15",
|
||||
"spfx-uifabric-themes": "^0.8.0",
|
||||
"spfx-uifabric-themes": "^0.8.5",
|
||||
"typescript": "~3.7.x"
|
||||
},
|
||||
"jest-junit": {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"themePrimary": "#6264a7",
|
||||
"themeLighterAlt": "#f7f7fb",
|
||||
"themeLighter": "#e1e1f1",
|
||||
"themeLight": "#c8c9e4",
|
||||
"themeTertiary": "#989ac9",
|
||||
"themeSecondary": "#7173b0",
|
||||
"themeDarkAlt": "#585a95",
|
||||
"themeDark": "#4a4c7e",
|
||||
"themeDarker": "#37385d",
|
||||
"neutralLighterAlt": "#0b0b0b",
|
||||
"neutralLighter": "#151515",
|
||||
"neutralLight": "#252525",
|
||||
"neutralQuaternaryAlt": "#2f2f2f",
|
||||
"neutralQuaternary": "#373737",
|
||||
"neutralTertiaryAlt": "#595959",
|
||||
"neutralTertiary": "#c8c8c8",
|
||||
"neutralSecondary": "#d0d0d0",
|
||||
"neutralPrimaryAlt": "#dadada",
|
||||
"neutralPrimary": "#ffffff",
|
||||
"neutralDark": "#f4f4f4",
|
||||
"black": "#f8f8f8",
|
||||
"white": "#000000"
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"themePrimary": "#6264a7",
|
||||
"themeLighterAlt": "#f7f7fb",
|
||||
"themeLighter": "#e1e1f1",
|
||||
"themeLight": "#c8c9e4",
|
||||
"themeTertiary": "#989ac9",
|
||||
"themeSecondary": "#7173b0",
|
||||
"themeDarkAlt": "#585a95",
|
||||
"themeDark": "#4a4c7e",
|
||||
"themeDarker": "#37385d",
|
||||
"neutralLighterAlt": "#2d2c2c",
|
||||
"neutralLighter": "#2c2b2b",
|
||||
"neutralLight": "#2a2929",
|
||||
"neutralQuaternaryAlt": "#272626",
|
||||
"neutralQuaternary": "#252525",
|
||||
"neutralTertiaryAlt": "#242323",
|
||||
"neutralTertiary": "#c8c8c8",
|
||||
"neutralSecondary": "#d0d0d0",
|
||||
"neutralPrimaryAlt": "#dadada",
|
||||
"neutralPrimary": "#ffffff",
|
||||
"neutralDark": "#f4f4f4",
|
||||
"black": "#f8f8f8",
|
||||
"white": "#2d2c2c"
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"themePrimary": "#6264a7",
|
||||
"themeLighterAlt": "#f7f7fb",
|
||||
"themeLighter": "#e1e1f1",
|
||||
"themeLight": "#c8c9e4",
|
||||
"themeTertiary": "#989ac9",
|
||||
"themeSecondary": "#7173b0",
|
||||
"themeDarkAlt": "#585a95",
|
||||
"themeDark": "#4a4c7e",
|
||||
"themeDarker": "#37385d",
|
||||
"neutralLighterAlt": "#ecebe9",
|
||||
"neutralLighter": "#e8e7e6",
|
||||
"neutralLight": "#dedddc",
|
||||
"neutralQuaternaryAlt": "#cfcecd",
|
||||
"neutralQuaternary": "#c6c5c4",
|
||||
"neutralTertiaryAlt": "#bebdbc",
|
||||
"neutralTertiary": "#b5b4b2",
|
||||
"neutralSecondary": "#9d9c9a",
|
||||
"neutralPrimaryAlt": "#868482",
|
||||
"neutralPrimary": "#252423",
|
||||
"neutralDark": "#565453",
|
||||
"black": "#3e3d3b",
|
||||
"white": "#f3f2f1"
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
$default-background: #f3f2f1;
|
||||
$default-color: #252423;
|
||||
$default-button-background: #6264a7;
|
||||
$default-Button-color: #f3f2f1;
|
||||
|
||||
// dark theme
|
||||
$dark-background: #2d2c2c;
|
||||
$dark-color: #ffffff;
|
||||
$dark-button-background: #6264a7;
|
||||
$dark-button-color: #2d2c2c;
|
||||
|
||||
// contrast theme
|
||||
$contrast-background: #000000;
|
||||
$contrast-color: #ffffff;
|
||||
$contrast-button-background: #b5c01c;
|
||||
$contrast-Button-color: #000000;
|
||||
|
|
@ -46,7 +46,7 @@ import { AppContext } from "../../common/AppContext";
|
|||
import { UserCard } from "../UserCard/UserCard";
|
||||
import { useRef } from "react";
|
||||
import strings from "StaffDirectoryWebPartStrings";
|
||||
|
||||
import {Theme} from 'spfx-uifabric-themes';
|
||||
const imageNoData: string = require("../../../assets/Nodatarafiki.svg");
|
||||
|
||||
|
||||
|
@ -73,7 +73,7 @@ export const StaffDirectory: React.FunctionComponent<IStaffDirectoryProps> = (
|
|||
props: IStaffDirectoryProps
|
||||
) => {
|
||||
const { showBox, maxHeight } = props;
|
||||
|
||||
const _theme = window.__themeState__.theme;
|
||||
const styleClasses = mergeStyleSets({
|
||||
webPartTitle: {
|
||||
marginBottom: 20,
|
||||
|
@ -85,7 +85,7 @@ export const StaffDirectory: React.FunctionComponent<IStaffDirectoryProps> = (
|
|||
margin: 20,
|
||||
borderBottomStyle: "solid",
|
||||
borderWidth: 1,
|
||||
borderBottomColor: props.themeVariant.palette.themeLighter,
|
||||
borderBottomColor: props.themeVariant?.palette?.themeLighter ?? _theme.themeLighter,
|
||||
},
|
||||
|
||||
styleIcon: {
|
||||
|
@ -93,7 +93,7 @@ export const StaffDirectory: React.FunctionComponent<IStaffDirectoryProps> = (
|
|||
minWidth: 44,
|
||||
minHeight: 30,
|
||||
height: 30,
|
||||
borderColor: props.themeVariant.palette.themePrimary,
|
||||
borderColor: props.themeVariant?.palette?.themePrimary ?? _theme.themePrimary,
|
||||
borderRightWidth: 0,
|
||||
borderRightStyle: "none",
|
||||
borderLeftWidth: 1,
|
||||
|
@ -123,24 +123,24 @@ export const StaffDirectory: React.FunctionComponent<IStaffDirectoryProps> = (
|
|||
width: "100%",
|
||||
maxHeight: 32,
|
||||
minHeight: 32,
|
||||
borderColor: props.themeVariant.palette.themePrimary,
|
||||
borderColor: props.themeVariant?.palette?.themePrimary ?? _theme.themePrimary,
|
||||
},
|
||||
itemsWrapper: {
|
||||
borderColor: props.themeVariant.palette.themePrimary,
|
||||
borderColor: props.themeVariant?.palette?.themePrimary ?? _theme.themePrimary,
|
||||
},
|
||||
text: {
|
||||
borderLeftWidth: 0,
|
||||
minHeight: 32,
|
||||
borderColor: props.themeVariant.palette.themePrimary,
|
||||
borderColor: props.themeVariant?.palette?.themePrimary ?? _theme.themePrimary,
|
||||
selectors: {
|
||||
":focus": {
|
||||
borderColor: props.themeVariant.palette.themePrimary,
|
||||
borderColor:props.themeVariant?.palette?.themePrimary ?? _theme.themePrimary,
|
||||
},
|
||||
":hover": {
|
||||
borderColor: props.themeVariant.palette.themePrimary,
|
||||
borderColor: props.themeVariant?.palette?.themePrimary ?? _theme.themePrimary,
|
||||
},
|
||||
"::after": {
|
||||
borderColor: props.themeVariant.palette.themePrimary,
|
||||
borderColor: props.themeVariant?.palette?.themePrimary ?? _theme.themePrimary,
|
||||
borderWidth: 1,
|
||||
borderLeftWidth: 0,
|
||||
},
|
||||
|
@ -151,7 +151,7 @@ export const StaffDirectory: React.FunctionComponent<IStaffDirectoryProps> = (
|
|||
const nextPageStyle: ILinkStyles = {
|
||||
root: {
|
||||
fontWeight: 600,
|
||||
fontSize: props.themeVariant.fonts.mediumPlus.fontSize,
|
||||
fontSize: props.themeVariant?.fonts?.mediumPlus?.fontSize ?? window.__themeState__.theme["ms-font-mediumPlus-fontSize"],
|
||||
selectors: { ":hover": { textDecoration: "underline" } },
|
||||
},
|
||||
};
|
||||
|
@ -383,8 +383,8 @@ export const StaffDirectory: React.FunctionComponent<IStaffDirectoryProps> = (
|
|||
iconName="Search"
|
||||
style={{
|
||||
verticalAlign: "center",
|
||||
fontSize: props.themeVariant.fonts.mediumPlus.fontSize,
|
||||
color: props.themeVariant.palette.themePrimary,
|
||||
fontSize: props.themeVariant?.fonts?.mediumPlus?.fontSize ?? window.__themeState__.theme["ms-font-mediumPlus-fontSize"],
|
||||
color: props.themeVariant?.palette.themePrimary ?? _theme.themePrimary,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
Link,
|
||||
ITextFieldStyles,
|
||||
IPersonaProps,
|
||||
loadTheme,
|
||||
} from "office-ui-fabric-react";
|
||||
import { presenceStatus, IPresenceStatus } from "../../common/PresenceStatus";
|
||||
import { AppContext } from "../../common/AppContext";
|
||||
|
@ -18,13 +19,18 @@ import { IUserExtended } from "../../entites/IUserExtended";
|
|||
import { IAppContext } from "../../common/IAppContext";
|
||||
import { IUserCardProps } from "./IUserCardProps";
|
||||
|
||||
|
||||
const teamsDefaultTheme = require("../../common/TeamsDefaultTheme.json");
|
||||
const teamsDarkTheme = require("../../common/TeamsDarkTheme.json");
|
||||
const teamsContrastTheme = require("../../common/TeamsContrastTheme.json");
|
||||
|
||||
export const UserCard = (props: IUserCardProps) => {
|
||||
const { userData, updateUsersPresence } = props;
|
||||
const _context: IAppContext = React.useContext(AppContext);
|
||||
|
||||
const [expandIcon, setExpandIcon] = React.useState("ChevronDownSmall");
|
||||
const [isDetailsOpen, setIsDetailsOpen] = React.useState(false);
|
||||
|
||||
const _Theme = window.__themeState__.theme;
|
||||
|
||||
const styleClasses = mergeStyleSets({
|
||||
separator: {
|
||||
|
@ -33,31 +39,32 @@ export const UserCard = (props: IUserCardProps) => {
|
|||
marginTop: 15,
|
||||
borderBottomStyle: "solid",
|
||||
borderWidth: 1,
|
||||
borderBottomColor: _context.themeVariant.palette.neutralLighterAlt,
|
||||
borderBottomColor: _context.themeVariant?.palette?.themeLighter ?? _Theme.themeLighter,
|
||||
},
|
||||
stylContainerDetails: {
|
||||
marginTop: 25,
|
||||
display: "grid",
|
||||
justifyContent: "stretch",
|
||||
alignItems: "center",
|
||||
backgroundColor: _context.themeVariant.palette.themeLighter,
|
||||
backgroundColor: _context.themeVariant?.palette?.neutralLighterAlt ?? _Theme.neutralLighterAlt,
|
||||
gridTemplateColumns: "repeat( auto-fit, minmax(280px, 1fr) )",
|
||||
gridTemplateRows: "auto",
|
||||
},
|
||||
|
||||
styleIconDetails: {
|
||||
fontSize: 16,
|
||||
color: _context.themeVariant.palette.themePrimary,
|
||||
color: _context.themeVariant?.palette?.themePrimary ?? _Theme.themePrimary,
|
||||
},
|
||||
styleFieldLabel: {
|
||||
fontSize: 12,
|
||||
fontWeight: 400,
|
||||
paddingLeft: 3,
|
||||
color: _Theme.inputText
|
||||
},
|
||||
|
||||
styleField: {
|
||||
paddingTop: 15,
|
||||
|
||||
color: _context.themeVariant?.palette?.themePrimary ?? _Theme.themePrimary,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -127,12 +134,12 @@ export const UserCard = (props: IUserCardProps) => {
|
|||
root: {
|
||||
height: 21,
|
||||
width: 26,
|
||||
color: _context.themeVariant.palette.themePrimary,
|
||||
color: _context.themeVariant?.palette?.themeSecondary ?? _Theme.themeSecondary,
|
||||
},
|
||||
}}
|
||||
iconProps={{
|
||||
iconName: "CannedChat",
|
||||
color: _context.themeVariant.palette.themePrimary,
|
||||
color: _context.themeVariant?.palette?.themeSecondary ??_Theme.themeSecondary,
|
||||
}}
|
||||
allowDisabledFocus={true}
|
||||
disabled={false}
|
||||
|
@ -156,12 +163,13 @@ export const UserCard = (props: IUserCardProps) => {
|
|||
root: {
|
||||
height: 21,
|
||||
width: 26,
|
||||
color: _context.themeVariant.palette.themePrimary,
|
||||
|
||||
},
|
||||
}}
|
||||
iconProps={{
|
||||
iconName: expandIcon,
|
||||
color: _context.themeVariant.palette.themePrimary,
|
||||
color: _Theme.themeSecondary
|
||||
|
||||
}}
|
||||
allowDisabledFocus={true}
|
||||
disabled={false}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// Components that allow authors to embed arbitrary script code should set this to true.
|
||||
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
|
||||
"requiresCustomScript": false,
|
||||
"supportedHosts": ["SharePointWebPart"],
|
||||
"supportedHosts": ["SharePointWebPart","TeamsTab","TeamsPersonalApp"],
|
||||
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
|
||||
|
|
|
@ -6,16 +6,19 @@ import {
|
|||
PropertyPaneTextField,
|
||||
PropertyPaneSlider,
|
||||
PropertyPaneToggle,
|
||||
PropertyPaneHorizontalRule
|
||||
PropertyPaneHorizontalRule,
|
||||
PropertyPaneLabel,
|
||||
PopupWindowPosition
|
||||
} from '@microsoft/sp-property-pane';
|
||||
import { BaseClientSideWebPart, PropertyPaneLabel } from '@microsoft/sp-webpart-base';
|
||||
import { BaseClientSideWebPart, } from '@microsoft/sp-webpart-base';
|
||||
|
||||
import * as strings from 'StaffDirectoryWebPartStrings';
|
||||
import {StaffDirectory} from '../../components/StaffDirectory/StaffDirectory';
|
||||
import { IStaffDirectoryProps } from '../../components/StaffDirectory/IStaffDirectoryProps';
|
||||
import { PropertyFieldMultiSelect } from '@pnp/spfx-property-controls/lib/PropertyFieldMultiSelect';
|
||||
|
||||
import {Theme} from 'spfx-uifabric-themes';
|
||||
import { ThemeProvider, ThemeChangedEventArgs, IReadonlyTheme } from '@microsoft/sp-component-base';
|
||||
import { loadTheme } from 'office-ui-fabric-react';
|
||||
export interface IStaffDirectoryWebPartProps {
|
||||
title: string;
|
||||
maxHeight: number;
|
||||
|
@ -28,27 +31,77 @@ export interface IStaffDirectoryWebPartProps {
|
|||
pageSize:number;
|
||||
}
|
||||
|
||||
const teamsDefaultTheme = require("../../common/TeamsDefaultTheme.json");
|
||||
const teamsDarkTheme = require("../../common/TeamsDarkTheme.json");
|
||||
const teamsContrastTheme = require("../../common/TeamsContrastTheme.json");
|
||||
export default class StaffDirectoryWebPart extends BaseClientSideWebPart<IStaffDirectoryWebPartProps> {
|
||||
|
||||
private _themeProvider: ThemeProvider;
|
||||
private _themeVariant: IReadonlyTheme | undefined;
|
||||
|
||||
|
||||
protected async onInit(): Promise<void> {
|
||||
window.sessionStorage.clear();
|
||||
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 ?
|
||||
const context = this.context.sdks.microsoftTeams!.context;
|
||||
this._applyTheme(context.theme || "default");
|
||||
this.context.sdks.microsoftTeams.teamsJs.registerOnThemeChangeHandler(
|
||||
this._applyTheme
|
||||
);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current theme variant reference and re-render.
|
||||
*
|
||||
* @param args The new theme
|
||||
*/
|
||||
private _handleThemeChangedEvent(args: ThemeChangedEventArgs): void {
|
||||
this._themeVariant = args.theme;
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
// 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,
|
||||
});
|
||||
}
|
||||
|
||||
if (theme == "default") {
|
||||
loadTheme({
|
||||
palette: teamsDefaultTheme,
|
||||
});
|
||||
}
|
||||
|
||||
if (theme == "contrast") {
|
||||
loadTheme({
|
||||
palette: teamsContrastTheme,
|
||||
});
|
||||
}
|
||||
this.render();
|
||||
}
|
||||
|
||||
|
||||
public render(): void {
|
||||
const element: React.ReactElement<IStaffDirectoryProps> = React.createElement(
|
||||
|
@ -58,7 +111,7 @@ export default class StaffDirectoryWebPart extends BaseClientSideWebPart<IStaffD
|
|||
context: this.context,
|
||||
maxHeight: this.properties.maxHeight,
|
||||
showBox: this.properties.showBox,
|
||||
themeVariant: this._themeVariant,
|
||||
themeVariant: this._themeVariant ,
|
||||
displayMode: this.displayMode,
|
||||
updateProperty: (value:string ) => {
|
||||
this.properties.title = value;
|
||||
|
|
Loading…
Reference in New Issue