UNPKG

gd-sprest-bs

Version:

SharePoint JavaScript, TypeScript and Web Components designed using the Bootstrap framework.

272 lines (230 loc) • 10.4 kB
import { Components } from "gd-bs"; import { ContextInfo, Helper, SPTypes } from "gd-sprest"; import { ISPFxWebPart, ISPFxWebPartProps } from "./types"; /** * SPFx WebPart Base Class */ class _SPFxWebPart implements ISPFxWebPart { private _props: ISPFxWebPartProps = null; /** The webpart configuration */ private _cfg: any = null; get Configuration(): any { return this._cfg; }; set Configuration(value: string) { // Clear the value this._cfg = {}; // Ensure a value exists if (value) { // Try to parse the value try { this._cfg = JSON.parse(value); } catch { } } } /** The configuration form. */ private _form: Components.IForm = null; get Form(): Components.IForm { return this._form; } /** The configuration modal. */ private _modal: Components.IModal = null; get Modal(): Components.IModal { return this._modal; } /** Is in display mode */ private _isDisplay: boolean = null; get IsDisplay(): boolean { return this._isDisplay; } /** Is in edit mode */ private _isEdit: boolean = null; get IsEdit(): boolean { return this._isEdit; } /** The configuration modal. */ // Constructor constructor(props: ISPFxWebPartProps) { // Save the properties this._props = props; // Ensure the spfx object was set if (this._props.spfx == null) { // Error console.error("[gd-sprest-bs] The spfx property wasn't set."); return; } // Set the page context ContextInfo.setPageContext(this._props.spfx.context.pageContext); // Set the configuration this.Configuration = this._props.spfx.properties.configuration; // See if this is the workbench if (window.location.pathname.indexOf("workbench.aspx") > 0) { // Set both flags to render edit/display this._isDisplay = true; this._isEdit = true; } else { // See if this is a classic page if (Helper.SP.Ribbon.exists) { // Set the flag this._isEdit = Helper.WebPart.isEditMode(); } else { // Set the flag this._isEdit = this._props.spfx.displayMode == SPTypes.DisplayMode.Edit; } // Set the flag this._isDisplay = !this._isEdit; } // Run the render method in another thread setTimeout(() => { // See if we are in edit mode if (this._isEdit) { // Render the configuration button this.renderEdit(); } // See if we are in display mode if (this.IsDisplay) { // Render the webpart this.render(); } }, 10); } // Method to render the webpart private render() { // Get the webpart element let elWP: HTMLElement = this._props.spfx.domElement.querySelector(".webpart"); if (elWP == null) { // Create the element elWP = document.createElement("div"); elWP.classList.add("webpart"); this._props.spfx.domElement.appendChild(elWP); } else { // Clear the element while (elWP.firstChild) { elWP.removeChild(elWP.firstChild); } } // Call the render event this._props.render ? this._props.render(elWP, this.Configuration) : null; } // Method to render the edit interface private renderEdit() { // Get the webpart element let elWPConfig: HTMLElement = this._props.spfx.domElement.querySelector(".webpart-cfg"); if (elWPConfig == null) { // Create the element elWPConfig = document.createElement("div"); elWPConfig.classList.add("webpart-cfg"); this._props.spfx.domElement.appendChild(elWPConfig); } else { // Do nothing return; } // Set the webpart properties pane to trigger the modal from displaying let propertyPageConfig = this._props.spfx.getPropertyPaneConfiguration; this._props.spfx.getPropertyPaneConfiguration = () => { // Get the original configuration let config = propertyPageConfig ? propertyPageConfig() : null; // Update the configuration w/ a button config = config || {}; config.pages = config.pages || []; config.pages.push({ header: { description: "Configuration" }, groups: [ { groupFields: [{ targetProperty: "configuration", type: SPTypes.PropertyPaneType.Button, properties: { text: "Configuration", onClick: () => { // Show the modal this.showEditModal(); } } }] } ] }); // Call the configuration return config; } // Render the edit button Components.Button({ el: elWPConfig, text: "Edit", onClick: () => { // Show the edit modal this.showEditModal(); } }); // Create the modal props let modalProps: Components.IModalProps = { el: elWPConfig, onClose: () => { // Hide the property pane to cause the webpart to re-render this._props.spfx.context.propertyPane.close(); }, onRenderBody: el => { // Create the form properties let formProps: Components.IFormProps = { el, value: this._cfg }; // Call the rendering event formProps = this._props.onConfigFormRendering ? this._props.onConfigFormRendering(formProps, this._cfg) : formProps; // Render the form this._form = Components.Form(formProps); // Call the rendered event this._props.onConfigFormRendered ? this._props.onConfigFormRendered(this._form, this._cfg) : null; }, onRenderFooter: el => { // Render the footer buttons let footerProps: Components.ITooltipGroupProps = { el, tooltips: [ { content: "Click to save the webpart configuration.", btnProps: { text: "Save", type: Components.ButtonTypes.OutlineSuccess, onClick: () => { // Ensure the form is valid if (this._form.isValid()) { let cfg = this._form.getValues(); // Call the saving event cfg = this._props.onConfigSaving ? this._props.onConfigSaving(cfg) : cfg; // Try to convert the form values let wpCfg = null; try { wpCfg = JSON.stringify(cfg); } catch { } // Save the configuration this._props.spfx.properties.configuration = wpCfg; // Update the configuration property this.Configuration = wpCfg; // Call the saved event this._props.onConfigSaved ? this._props.onConfigSaved(cfg) : null; // See if we are in display mode and the property pane is closed if (this.IsDisplay && !this._props.spfx.context.propertyPane.isPropertyPaneOpen()) { // Render the display webpart this.render(); } // Close the modal this._modal.hide(); } } } } ] } // Call the event footerProps = this._props.onConfigFormFooterRendering ? this._props.onConfigFormFooterRendering(footerProps, this._cfg) : footerProps; // Render the footer Components.TooltipGroup(footerProps); } }; // Call the rendering event let onRender = null; let newProps = this._props.onModalRendering ? this._props.onModalRendering(modalProps) : null; if (newProps) { onRender = newProps.onRenderBody; } // Render the modal this._modal = Components.Modal({ ...newProps, ...modalProps }); // Call the rendered event this._props.onModalRendered ? this._props.onModalRendered(this._modal) : null; // Call the renderEdit event this._props.renderEdit ? this._props.renderEdit(elWPConfig, this.Configuration) : null; } // Shows the modal showEditModal() { // Show the modal this._modal ? this._modal.show() : null; // Call the event this._props.onConfigFormDisplaying ? this._props.onConfigFormDisplaying(this.Configuration) : null; } } export const SPFxWebPart = (props: ISPFxWebPartProps): ISPFxWebPart => { return new _SPFxWebPart(props); }