Skip to content

Commit

Permalink
Merge pull request #324 from sudharsank/js-application-alert-message
Browse files Browse the repository at this point in the history
Configured few properties and also added the codetour
  • Loading branch information
hugoabernier authored Jul 10, 2020
2 parents e17aa5d + 879f9dd commit e4c4ee4
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 52 deletions.
155 changes: 155 additions & 0 deletions samples/js-application-alert-message/.tours/extension-walkthrough.tour
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
{
"title": "Extension Walkthrough",
"steps": [
{
"file": "src/extensions/globalAlerts/GlobalAlertsApplicationCustomizer.ts",
"line": 24,
"description": "Property declaration\n1. **animationType** - Property to hold the animation to be played for the alerts. Default is set to be '**_bounceInRight_**', if there is no property defined.\n2. **animationDelay** - Delay to be used between multiple alerts. Default is set to be '**_5000ms_**', if there is no property defined.\n3. **alertBackgoundColor** - Background color for the alert container. Default is set to be '**_Red_**' if there is no property defined.\n4. **textColor** - Text color based on the background color. Default is set to be '**_White_**', if there is no property defined.",
"selection": {
"start": {
"line": 21,
"character": 5
},
"end": {
"line": 24,
"character": 23
}
}
},
{
"file": "src/extensions/globalAlerts/GlobalAlertsApplicationCustomizer.ts",
"line": 53,
"description": "Render Placeholder method to render the actual alert component once the Placeholder is available in the page. We are also passing all the properties to the alert component where the actual alert fetching and redering is maintained.",
"selection": {
"start": {
"line": 31,
"character": 5
},
"end": {
"line": 53,
"character": 6
}
}
},
{
"file": "src/extensions/globalAlerts/GlobalAlertsApplicationCustomizer.ts",
"line": 59,
"description": "Setting up the **_spfxcontext_** for the **PnP** library. Since we get all the alerts from SharePoint list using the **PnP** library.",
"selection": {
"start": {
"line": 59,
"character": 9
},
"end": {
"line": 59,
"character": 32
}
}
},
{
"file": "src/extensions/globalAlerts/GlobalAlertsApplicationCustomizer.ts",
"line": 61,
"description": "Make sure the placeholders are rendered in the page and after rendering the default placeholders, we have to call our custom render method to apply the customization.\n\n**_Note_**: Without this line, the extension will not work properly. Sometimes the extension will load and sometimes not.",
"selection": {
"start": {
"line": 61,
"character": 9
},
"end": {
"line": 61,
"character": 91
}
}
},
{
"file": "src/extensions/globalAlerts/Alerts.tsx",
"line": 6,
"description": "Using **selective imports** from **PnP** library to reduce the package size.",
"selection": {
"start": {
"line": 4,
"character": 1
},
"end": {
"line": 6,
"character": 24
}
}
},
{
"file": "src/extensions/globalAlerts/Alerts.tsx",
"line": 55,
"description": "Defining the **background color** and the **forecolor** of the text based on the properties defined.",
"selection": {
"start": {
"line": 54,
"character": 5
},
"end": {
"line": 55,
"character": 73
}
}
},
{
"file": "src/extensions/globalAlerts/Alerts.tsx",
"line": 74,
"description": "Animation method to trigger the animation using **Morphext.js** and **Animate.css**.",
"selection": {
"start": {
"line": 58,
"character": 5
},
"end": {
"line": 74,
"character": 7
}
}
},
{
"file": "src/extensions/globalAlerts/Alerts.tsx",
"line": 86,
"description": "Method to hide the **Top Placeholder** if there is no alert to display.",
"selection": {
"start": {
"line": 75,
"character": 5
},
"end": {
"line": 86,
"character": 7
}
}
},
{
"file": "src/extensions/globalAlerts/Alerts.tsx",
"line": 97,
"description": "Method to get the active and non-expired alerts from the SharePoint list.",
"selection": {
"start": {
"line": 87,
"character": 5
},
"end": {
"line": 97,
"character": 7
}
}
},
{
"file": "sharepoint/assets/elements.xml",
"line": 8,
"description": "Custom properties defined. Pre-allocated height for the top placeholder is defined to reduce the page flick when the extension is deployed. For more details, please [click here](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/extensions/overview-extensions).",
"selection": {
"start": {
"line": 7,
"character": 9
},
"end": {
"line": 8,
"character": 98
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "js-application-alert-message-client-side-solution",
"name": "js-application-alert-message",
"title": "Alert Message Extn",
"id": "e06a3f71-616c-495d-9ce9-ece921d8f58d",
"version": "1.0.0.0",
"includeClientSideAssets": true,
"isDomainIsolated": false,
"features": [
{
"title": "Application Extension - Deployment of custom action.",
"description": "Deploys a custom action with ClientSideComponentId association",
"title": "Alert Message",
"description": "Custom extension to display alert message on the top placeholder.",
"id": "15a67329-5278-4d3e-be53-6fdc6ccfc689",
"version": "1.0.0.0",
"assets": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Title="GlobalAlerts"
Location="ClientSideExtension.ApplicationCustomizer"
ComponentId="6ba4b6c1-ee22-421f-97d9-d2bad0a4cc57"
Properties="{"testMessage":"Test message"}"
HostProperties="{"preAllocatedApplicationCustomizerTopHeight":"50"}">
Properties="{"animationType":"bounceInRight","animationDelay":"3000","alertBackgroundColor":"blue"}"
HostProperties="{"preAllocatedApplicationCustomizerTopHeight":"35"}">
</ClientSideComponentInstance>
</Elements>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Title="GlobalAlerts"
Location="ClientSideExtension.ApplicationCustomizer"
ClientSideComponentId="6ba4b6c1-ee22-421f-97d9-d2bad0a4cc57"
ClientSideComponentProperties="{&quot;testMessage&quot;:&quot;Test message&quot;}"
HostProperties="{&quot;preAllocatedApplicationCustomizerTopHeight&quot;:&quot;50&quot;}">
ClientSideComponentProperties="{&quot;animationType&quot;:&quot;bounceInRight&quot;,&quot;animationDelay&quot;:&quot;3000&quot;,&quot;alertBackgroundColor&quot;:&quot;blue&quot;}"
HostProperties="{&quot;preAllocatedApplicationCustomizerTopHeight&quot;:&quot;35&quot;}">
</CustomAction>
</Elements>
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,14 @@ const Qry_Alert = `<View>

export interface IAlertsProps {
animationType: string;
animationDelay: number;
alertBackgroundColor: string;
textColor: string;
}

export default function (props: IAlertsProps) {
let bgColor: string = props.alertBackgroundColor ? props.alertBackgroundColor : 'red';
let textColor: string = props.textColor ? props.textColor : 'white';
const [alerts, setAlerts] = React.useState<string>('');
const [showAlerts, setShowAlerts] = React.useState<boolean>(false);
const _startAlertAnimation = () => {
Expand All @@ -58,7 +63,7 @@ export default function (props: IAlertsProps) {
// An array of phrases to rotate are created based on this separator. Change it if you wish to separate the phrases differently (e.g. So Simple | Very Doge | Much Wow | Such Cool).
separator: "~",
// The delay between the changing of each phrase in milliseconds.
speed: 5000,
speed: props.animationDelay ? props.animationDelay : 5000,
complete: () => {
// Called after the entrance animation is executed.
jQuery("#alertMessage").find(".morphext").css("display", "inline-block");
Expand Down Expand Up @@ -96,7 +101,7 @@ export default function (props: IAlertsProps) {
return (
<>
{alerts.length > 0 &&
<div className={css("ms-Grid-row", styles.alertContainer)}>
<div className={css("ms-Grid-row", styles.alertContainer)} style={{ backgroundColor: bgColor, color: textColor }}>
{showAlerts &&
<span id="alertMessage">{alerts}</span>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
.alertContainer {
height: 30px;
height: 35px;
padding-left: 20px;
background-color: red;
color: white;
padding-top: 3px;
padding-top: 4px;
font-weight: bold;
&.animated {
display: inline-block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@
"alias": "GlobalAlertsApplicationCustomizer",
"componentType": "Extension",
"extensionType": "ApplicationCustomizer",

// The "*" signifies that the version should be taken from the package.json
"version": "*",
"manifestVersion": 2,

// If true, the component can only be installed on sites where Custom Script is allowed.
// 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
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as ReactDOM from 'react-dom';
import { override } from '@microsoft/decorators';
import { Log } from '@microsoft/sp-core-library';
import {
BaseApplicationCustomizer, PlaceholderName, PlaceholderContent
BaseApplicationCustomizer, PlaceholderName, PlaceholderContent
} from '@microsoft/sp-application-base';
import * as strings from 'GlobalAlertsApplicationCustomizerStrings';
import { sp } from "@pnp/sp";
Expand All @@ -17,40 +17,48 @@ const LOG_SOURCE: string = 'GlobalAlertsApplicationCustomizer';
* You can define an interface to describe it.
*/
export interface IGlobalAlertsApplicationCustomizerProperties {
// This is an example; replace with your own property
animationType: string;
// This is an example; replace with your own property
animationType: string;
animationDelay: number;
alertBackgroundColor: string;
textColor: string;
}

/** A Custom Action which can be run during execution of a Client Side Application */
export default class GlobalAlertsApplicationCustomizer
extends BaseApplicationCustomizer<IGlobalAlertsApplicationCustomizerProperties> {
private _topPlaceholder: PlaceholderContent | undefined;
private _renderPlaceHolders(): void {
// Handling the top placeholder
if (!this._topPlaceholder) {
this._topPlaceholder = this.context.placeholderProvider.tryCreateContent(
PlaceholderName.Top,
{ onDispose: this._onDispose }
);
// The extension should not assume that the expected placeholder is available.
if (!this._topPlaceholder) {
console.error("The expected placeholder (Top) was not found.");
return;
}
if (this._topPlaceholder.domElement) {
const elem: React.ReactElement<IAlertsProps> = React.createElement(Alerts, { animationType: this.properties.animationType });
ReactDOM.render(elem, this._topPlaceholder.domElement);
}
}
}
private _onDispose(): void {
console.log('[GlobalAlertApplicationCustomizer._onDispose] Disposed custom top placeholders.');
}
@override
public onInit(): Promise<void> {
sp.setup(this.context);
// Wait for the placeholders to be created (or handle them being changed) and then render.
this.context.placeholderProvider.changedEvent.add(this, this._renderPlaceHolders);
return Promise.resolve();
}
extends BaseApplicationCustomizer<IGlobalAlertsApplicationCustomizerProperties> {
private _topPlaceholder: PlaceholderContent | undefined;
private _renderPlaceHolders(): void {
// Handling the top placeholder
if (!this._topPlaceholder) {
this._topPlaceholder = this.context.placeholderProvider.tryCreateContent(
PlaceholderName.Top,
{ onDispose: this._onDispose }
);
// The extension should not assume that the expected placeholder is available.
if (!this._topPlaceholder) {
console.error("The expected placeholder (Top) was not found.");
return;
}
if (this._topPlaceholder.domElement) {
const elem: React.ReactElement<IAlertsProps> = React.createElement(Alerts, {
animationType: this.properties.animationType,
animationDelay: this.properties.animationDelay,
alertBackgroundColor: this.properties.alertBackgroundColor,
textColor: this.properties.textColor
});
ReactDOM.render(elem, this._topPlaceholder.domElement);
}
}
}
private _onDispose(): void {
console.log('[GlobalAlertApplicationCustomizer._onDispose] Disposed custom top placeholders.');
}
@override
public onInit(): Promise<void> {
sp.setup(this.context);
// Wait for the placeholders to be created (or handle them being changed) and then render.
this.context.placeholderProvider.changedEvent.add(this, this._renderPlaceHolders);
return Promise.resolve();
}
}

0 comments on commit e4c4ee4

Please sign in to comment.