@@ -2,7 +2,6 @@ import * as React from "react";
22import * as ReactDom from "react-dom" ;
33import { Version } from "@microsoft/sp-core-library" ;
44import { PropertyPaneTagCategoryPicker } from "./controls/TagCategoryPicker/PropertyPaneTagCategoryPicker" ;
5-
65import {
76 type IPropertyPaneConfiguration ,
87 PropertyPaneDropdown ,
@@ -13,32 +12,26 @@ import { BaseClientSideWebPart } from "@microsoft/sp-webpart-base";
1312import { IReadonlyTheme } from "@microsoft/sp-component-base" ;
1413import WordPressRssFeed from "./components/WordPressRssFeed" ;
1514import { ITagOrCategory , IWordPressRssFeedWebPartProps } from "./interfaces" ;
16- import { DEFAULTS , defaultSettings } from "./defaults" ;
15+ import { defaultDisplaySettings , defaultFeedRequestSettings } from "./defaults" ;
1716import { filterJoinOperators , layouts } from "./dropdownOptions" ;
1817import { PropertyPaneWordPressUrlField } from "./controls/WordPressUrlField/PropertyPaneWordPressUrlField" ;
1918import { validateUrl } from "./util" ;
2019import { PropertyPaneNumericTextField } from "./controls/NumericTextField/PropertyPaneNumericTextField" ;
21-
2220export default class WordPressRssFeedWebPart extends BaseClientSideWebPart < IWordPressRssFeedWebPartProps > {
2321 // store data that you need to fetch asynchronously within
2422 // configuration panel as private variables, and load them
2523 // onInit.
2624 private _tagOptions : { key : number ; text : string } [ ] = [ ] ;
2725 private _categoryOptions : { key : number ; text : string } [ ] = [ ] ;
2826 private _siteName : string = "" ;
29-
3027 public render ( ) : void {
3128 const element : React . ReactElement < IWordPressRssFeedWebPartProps > = React . createElement ( WordPressRssFeed , {
32- title : this . properties . title ,
33- description : this . properties . description ,
34- readMoreLink : this . properties . readMoreLink ,
35- feedSettings : this . properties . feedSettings ,
29+ displaySettings : this . properties . displaySettings ,
30+ feedFilterSettings : this . properties . feedFilterSettings ,
3631 url : this . properties . url ,
3732 } ) ;
38-
3933 ReactDom . render ( element , this . domElement ) ;
4034 }
41-
4235 private loadSiteDataFromURL : ( ) => Promise < void > = async ( ) => {
4336 const apiBase = this . properties . url ;
4437 const [ general , tags , categories ] = await Promise . all ( [
@@ -51,168 +44,197 @@ export default class WordPressRssFeedWebPart extends BaseClientSideWebPart<IWord
5144 this . _categoryOptions = categories . map ( ( cat : ITagOrCategory ) => ( { key : cat . id , text : cat . name } ) ) ;
5245 return Promise . resolve ( ) ;
5346 } ;
54-
5547 protected onInit ( ) : Promise < void > {
5648 // initialize values to defaults if database instance has nothing stored
57-
5849 if ( ! this . properties . url ) {
59- this . properties . url = DEFAULTS . siteUrl ;
50+ this . properties . url = "" ;
6051 }
61- if ( ! this . properties . feedSettings ) {
62- this . properties . feedSettings = defaultSettings ;
52+ if ( ! this . properties . feedFilterSettings ) {
53+ this . properties . feedFilterSettings = defaultFeedRequestSettings ;
6354 }
64- if ( ! this . properties . title ) {
65- this . properties . title = DEFAULTS . title ;
55+ if ( ! this . properties . displaySettings ) {
56+ this . properties . displaySettings = defaultDisplaySettings ;
6657 }
67- if ( ! this . properties . description ) {
68- this . properties . description = DEFAULTS . description ;
69- }
70- if ( ! this . properties . readMoreLink ) {
71- this . properties . readMoreLink = DEFAULTS . readMoreLink ;
72- }
73-
7458 if ( validateUrl ( this . properties . url ) ) {
7559 this . loadSiteDataFromURL ( ) . catch ( ( e ) => console . error ( e ) ) ;
7660 }
7761 return super . onInit ( ) ;
7862 }
79-
8063 protected onThemeChanged ( currentTheme : IReadonlyTheme | undefined ) : void {
8164 if ( ! currentTheme ) {
8265 return ;
8366 }
8467 const { semanticColors } = currentTheme ;
85-
8668 if ( semanticColors ) {
8769 this . domElement . style . setProperty ( "--bodyText" , semanticColors . bodyText || null ) ;
8870 this . domElement . style . setProperty ( "--link" , semanticColors . link || null ) ;
8971 this . domElement . style . setProperty ( "--linkHovered" , semanticColors . linkHovered || null ) ;
9072 }
9173 }
92-
9374 protected onDispose ( ) : void {
9475 ReactDom . unmountComponentAtNode ( this . domElement ) ;
9576 }
96-
9777 protected get dataVersion ( ) : Version {
9878 return Version . parse ( "1.0" ) ;
9979 }
100-
10180 public getPropertyPaneConfiguration ( ) : IPropertyPaneConfiguration {
10281 return {
10382 pages : [
10483 {
10584 header : { description : "Configure your WordPress feed" } ,
10685 groups : [
10786 {
108- groupName : "Feed Basics " ,
87+ groupName : "WordPress Site Connection " ,
10988 groupFields : [
110- PropertyPaneTextField ( "title" , {
89+ new PropertyPaneWordPressUrlField ( "url" , {
90+ label : "WordPress Site URL" ,
91+ key : "url" ,
92+ value : this . properties . url ,
93+ siteName : this . _siteName ,
94+ onChange : ( s : string ) => {
95+ this . properties . url = s ;
96+ this . context . propertyPane . refresh ( ) ;
97+ } ,
98+ siteFetchHandler : async ( ) => {
99+ await this . loadSiteDataFromURL ( )
100+ . then ( ( ) => {
101+ this . context . propertyPane . refresh ( ) ;
102+ this . render ( ) ;
103+ } )
104+ . catch ( ( e ) => console . error ( e ) ) ;
105+ } ,
106+ } ) ,
107+ ] ,
108+ } ,
109+ {
110+ groupName : "Display Settings" ,
111+ groupFields : [
112+ PropertyPaneTextField ( "displaySettings.title" , {
111113 label : "Feed Title" ,
112- value : this . properties . title ,
114+ value : this . properties . displaySettings . title ,
113115 } ) ,
114- PropertyPaneTextField ( "description" , {
116+ PropertyPaneTextField ( "displaySettings. description" , {
115117 label : "Feed Description" ,
116118 multiline : true ,
117- value : this . properties . description ,
119+ value : this . properties . displaySettings . description ,
118120 } ) ,
119- PropertyPaneToggle ( "readMoreLink.include" , {
121+ PropertyPaneToggle ( "displaySettings. readMoreLink.include" , {
120122 label : "Include Link Below Feed?" ,
121- checked : this . properties . readMoreLink . include ,
123+ checked : this . properties . displaySettings . readMoreLink . include ,
122124 } ) ,
123- PropertyPaneTextField ( "readMoreLink.linkText" , {
125+ PropertyPaneTextField ( "displaySettings. readMoreLink.linkText" , {
124126 label : "Link Text" ,
125- disabled : ! this . properties . readMoreLink . include ,
126- value : this . properties . readMoreLink . linkText ,
127+ disabled : ! this . properties . displaySettings . readMoreLink . include ,
128+ value : this . properties . displaySettings . readMoreLink . linkText ,
127129 } ) ,
128- PropertyPaneTextField ( "readMoreLink.linkUrl" , {
130+ PropertyPaneTextField ( "displaySettings. readMoreLink.linkUrl" , {
129131 label : "Link URL" ,
130- disabled : ! this . properties . readMoreLink . include ,
131- value : this . properties . readMoreLink . linkUrl ,
132+ disabled : ! this . properties . displaySettings . readMoreLink . include ,
133+ value : this . properties . displaySettings . readMoreLink . linkUrl ,
132134 } ) ,
133- PropertyPaneToggle ( "readMoreLink.linkNewTab" , {
135+ PropertyPaneToggle ( "displaySettings. readMoreLink.linkNewTab" , {
134136 label : "Open link in new tab" ,
135- checked : this . properties . readMoreLink . linkNewTab ,
137+ checked : this . properties . displaySettings . readMoreLink . linkNewTab ,
136138 } ) ,
137- new PropertyPaneWordPressUrlField ( "url" , {
138- label : "WordPress Site URL" ,
139- key : "url" ,
140- value : this . properties . url ,
141- siteName : this . _siteName ,
139+ PropertyPaneToggle ( "displaySettings.showAuthor" , {
140+ label : "Show Author on Posts" ,
141+ checked : this . properties . displaySettings . showAuthor ,
142+ } ) ,
143+ PropertyPaneToggle ( "displaySettings.showMedia" , {
144+ label : "Show Media / Thumbnail (if available)" ,
145+ checked : this . properties . displaySettings . showMedia ,
146+ } ) ,
147+ PropertyPaneDropdown ( "displaySettings.layoutType" , {
148+ label : "Feed Layout" ,
149+ options : layouts ,
150+ selectedKey : this . properties . displaySettings . layoutType ,
151+ } ) ,
152+ new PropertyPaneNumericTextField ( "displaySettings.itemsPerPage" , {
153+ label : "Pagination - Items Per Page (set equal to Number of Posts for no pagination)" ,
154+ min : 1 ,
155+ max : 100 , // obviously the real limit will be the number of posts in the feed
156+ key : "displaySettings.itemsPerPage" ,
157+ value : this . properties . displaySettings . itemsPerPage . toString ( ) ,
142158 onChange : ( s : string ) => {
143- this . properties . url = s ;
159+ this . properties . displaySettings . itemsPerPage = parseInt ( s ) ;
144160 this . context . propertyPane . refresh ( ) ;
161+ this . render ( ) ;
145162 } ,
146- siteFetchHandler : async ( ) => {
147- await this . loadSiteDataFromURL ( )
148- . then ( ( ) => this . context . propertyPane . refresh ( ) )
149- . catch ( ( e ) => console . error ( e ) ) ;
163+ } ) ,
164+ new PropertyPaneNumericTextField ( "displaySettings.excerptLength" , {
165+ label : "Excerpt Preview Length (set to 0 to hide excerpt)" ,
166+ min : 0 ,
167+ max : 300 ,
168+ key : "displaySettings.excerptLength" ,
169+ value : this . properties . displaySettings . excerptLength . toString ( ) ,
170+ onChange : ( s : string ) => {
171+ this . properties . displaySettings . excerptLength = parseInt ( s ) ;
172+ this . context . propertyPane . refresh ( ) ;
173+ this . render ( ) ;
150174 } ,
151175 } ) ,
152176 ] ,
153177 } ,
154-
155178 {
156- groupName : "Feed Settings" ,
179+ groupName : "Feed Filter Settings" ,
157180 groupFields : [
158- new PropertyPaneNumericTextField ( "feedSettings .numPosts" , {
181+ new PropertyPaneNumericTextField ( "feedFilterSettings .numPosts" , {
159182 label : "Number of Posts" ,
160- key : "feedSettings.numPosts" ,
161- value : this . properties . feedSettings . numPosts . toString ( ) ,
183+ min : 1 ,
184+ max : 50 ,
185+ key : "feedFilterSettings.numPosts" ,
186+ value : this . properties . feedFilterSettings . numPosts . toString ( ) ,
162187 onChange : ( s : string ) => {
163- this . properties . feedSettings . numPosts = parseInt ( s ) ;
188+ this . properties . feedFilterSettings . numPosts = parseInt ( s ) ;
164189 this . context . propertyPane . refresh ( ) ;
165190 this . render ( ) ;
166191 } ,
167192 } ) ,
168- new PropertyPaneNumericTextField ( "feedSettings .pastDays" , {
193+ new PropertyPaneNumericTextField ( "feedFilterSettings .pastDays" , {
169194 label : "Past Days" ,
170- key : "feedSettings.pastDays" ,
171- value : this . properties . feedSettings . pastDays . toString ( ) ,
195+ min : 1 ,
196+ max : 3650 , // 10 years seems sufficient :)
197+ key : "feedFilterSettings.pastDays" ,
198+ value : this . properties . feedFilterSettings . pastDays . toString ( ) ,
172199 onChange : ( s : string ) => {
173- this . properties . feedSettings . pastDays = parseInt ( s ) ;
200+ this . properties . feedFilterSettings . pastDays = parseInt ( s ) ;
174201 this . context . propertyPane . refresh ( ) ;
175202 this . render ( ) ;
176203 } ,
177204 } ) ,
178205 // Tag/category filtering would require dynamic loading,
179206 // which SPFX doesn't support directly in the property pane.
180207 // I am using a customPropertyPaneField for this if needed.
181- new PropertyPaneTagCategoryPicker ( "feedSettings .tagIds" , {
208+ new PropertyPaneTagCategoryPicker ( "feedFilterSettings .tagIds" , {
182209 label : "Select Tags" ,
183- key : "feedSettings .tagIds" ,
184- selectedKeys : this . properties . feedSettings . tagIds || [ ] ,
210+ key : "feedFilterSettings .tagIds" ,
211+ selectedKeys : this . properties . feedFilterSettings . tagIds || [ ] ,
185212 options : this . _tagOptions ,
186213 onChange : ( newTagIds : number [ ] ) => {
187- this . properties . feedSettings . tagIds = newTagIds ;
214+ this . properties . feedFilterSettings . tagIds = newTagIds ;
188215 this . context . propertyPane . refresh ( ) ;
189216 this . render ( ) ;
190217 } ,
191218 } ) ,
192- new PropertyPaneTagCategoryPicker ( "feedSettings .categoryIds" , {
219+ new PropertyPaneTagCategoryPicker ( "feedFilterSettings .categoryIds" , {
193220 label : "Select Categories" ,
194- key : "feedSettings .categoryIds" ,
195- selectedKeys : this . properties . feedSettings . categoryIds || [ ] ,
221+ key : "feedFilterSettings .categoryIds" ,
222+ selectedKeys : this . properties . feedFilterSettings . categoryIds || [ ] ,
196223 options : this . _categoryOptions ,
197224 onChange : ( newCategoryIds : number [ ] ) => {
198- this . properties . feedSettings . categoryIds = newCategoryIds ;
225+ this . properties . feedFilterSettings . categoryIds = newCategoryIds ;
199226 this . context . propertyPane . refresh ( ) ;
200227 this . render ( ) ;
201228 } ,
202229 } ) ,
203- PropertyPaneTextField ( "feedSettings .postPattern" , {
230+ PropertyPaneTextField ( "feedFilterSettings .postPattern" , {
204231 label : "Post Pattern (Wildcard OK)" ,
205- value : this . properties . feedSettings . postPattern ,
232+ value : this . properties . feedFilterSettings . postPattern ,
206233 } ) ,
207- PropertyPaneDropdown ( "feedSettings .filterJoinOperator" , {
234+ PropertyPaneDropdown ( "feedFilterSettings .filterJoinOperator" , {
208235 label : "Join Operator" ,
209236 options : filterJoinOperators ,
210- selectedKey : this . properties . feedSettings . filterJoinOperator ,
211- } ) ,
212- PropertyPaneDropdown ( "feedSettings.layoutType" , {
213- label : "Feed Layout" ,
214- options : layouts ,
215- selectedKey : this . properties . feedSettings . layoutType ,
237+ selectedKey : this . properties . feedFilterSettings . filterJoinOperator ,
216238 } ) ,
217239 ] ,
218240 } ,
0 commit comments