Updated the WebPart with the latest spfx packages.
Multiple bottle-neck bugs have been fixed in SPFX which allows to update the WebPart with the latest SPFX packages. Overall performance should now be better and other minor bugs have been fixed.
This commit is contained in:
parent
ac8fa43ab6
commit
3c77c0b8e0
|
@ -0,0 +1,75 @@
|
|||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
// Configure glob patterns for excluding files and folders in the file explorer.
|
||||
"files.exclude": {
|
||||
"**/.git": true,
|
||||
"**/.DS_Store": true,
|
||||
"**/bower_components": true,
|
||||
"**/coverage": true,
|
||||
"**/lib-amd": true,
|
||||
"src/**/*.scss.ts": true
|
||||
},
|
||||
"typescript.tsdk": ".\\node_modules\\typescript\\lib",
|
||||
"json.schemas": [
|
||||
{
|
||||
"fileMatch": [
|
||||
"/config/config.json"
|
||||
],
|
||||
"url": "./node_modules/@microsoft/sp-build-web/lib/schemas/config.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"/config/copy-assets.json"
|
||||
],
|
||||
"url": "./node_modules/@microsoft/sp-build-core-tasks/lib/copyAssets/copy-assets.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"/config/deploy-azure-storage.json"
|
||||
],
|
||||
"url": "./node_modules/@microsoft/sp-build-core-tasks/lib/deployAzureStorage/deploy-azure-storage.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"/config/package-solution.json"
|
||||
],
|
||||
"url": "./node_modules/@microsoft/sp-build-core-tasks/lib/packageSolution/package-solution.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"/config/serve.json"
|
||||
],
|
||||
"url": "./node_modules/@microsoft/gulp-core-build-serve/lib/serve.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"/config/tslint.json"
|
||||
],
|
||||
"url": "./node_modules/@microsoft/gulp-core-build-typescript/lib/schemas/tslint.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"/config/write-manifests.json"
|
||||
],
|
||||
"url": "./node_modules/@microsoft/sp-build-core-tasks/lib/writeManifests/write-manifests.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"/config/configure-webpack.json"
|
||||
],
|
||||
"url": "./node_modules/@microsoft/sp-build-core-tasks/lib/configureWebpack/configure-webpack.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"/config/configure-external-bundling-webpack.json"
|
||||
],
|
||||
"url": "./node_modules/@microsoft/sp-build-core-tasks/lib/configureWebpack/configure-webpack-external-bundling.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": [
|
||||
"/copy-static-assets.json"
|
||||
],
|
||||
"url": "./node_modules/@microsoft/sp-build-core-tasks/lib/copyStaticAssets/copy-static-assets.schema.json"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"@microsoft/generator-sharepoint": {
|
||||
"libraryName": "content-query-webpart",
|
||||
"framework": "react",
|
||||
"version": "1.0.0",
|
||||
"libraryId": "00406271-0276-406f-9666-512623eb6709"
|
||||
"version": "1.1.1",
|
||||
"libraryName": "react-content-query",
|
||||
"libraryId": "489c9f8f-8e66-4efb-8365-85279ba91433",
|
||||
"environment": "spo"
|
||||
}
|
||||
}
|
|
@ -6,4 +6,4 @@
|
|||
"port": 5432,
|
||||
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"label-position": false,
|
||||
"member-access": true,
|
||||
"no-arg": false,
|
||||
"no-console": true,
|
||||
"no-console": false,
|
||||
"no-construct": false,
|
||||
"no-duplicate-case": true,
|
||||
"no-duplicate-variable": true,
|
||||
|
@ -39,8 +39,7 @@
|
|||
"use-named-parameter": true,
|
||||
"valid-typeof": true,
|
||||
"variable-name": false,
|
||||
"whitespace": false,
|
||||
"prefer-const": false
|
||||
"whitespace": false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"cdnBasePath": "https://publiccdn.sharepointonline.com/spptechnologies.sharepoint.com/110700492eeea162ee5bad0f35b1f0061ded8bf436ce0199efe2a4d24109e1c0df1ec594/react-content-query-1.0.1"
|
||||
"cdnBasePath": "https://publiccdn.sharepointonline.com/spptechnologies.sharepoint.com/110700492eeea162ee5bad0f35b1f0061ded8bf436ce0199efe2a4d24109e1c0df1ec594/react-content-query-1.0.2"
|
||||
}
|
|
@ -11,11 +11,12 @@ const build = require('@microsoft/sp-build-web');
|
|||
********************************************************************************************/
|
||||
build.configureWebpack.mergeConfig({
|
||||
additionalConfiguration: (generatedConfiguration) => {
|
||||
|
||||
generatedConfiguration.resolve.alias = { handlebars: 'handlebars/dist/handlebars.min.js' };
|
||||
|
||||
generatedConfiguration.module.loaders.push({
|
||||
test: /\.js$/, loader: 'unlazy'
|
||||
});
|
||||
generatedConfiguration.module.rules.push(
|
||||
{ test: /\.js$/, loader: 'unlazy-loader' }
|
||||
);
|
||||
|
||||
generatedConfiguration.node = {
|
||||
fs: 'empty'
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
22
package.json
22
package.json
|
@ -1,38 +1,34 @@
|
|||
{
|
||||
"name": "react-content-query",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/sp-client-base": "~1.0.0",
|
||||
"@microsoft/sp-core-library": "~1.0.0",
|
||||
"@microsoft/sp-webpart-base": "~1.0.0",
|
||||
"@types/handlebars": "^4.0.32",
|
||||
"@microsoft/sp-core-library": "~1.1.0",
|
||||
"@microsoft/sp-webpart-base": "~1.1.1",
|
||||
"@types/handlebars": "4.0.32",
|
||||
"@types/react": "0.14.46",
|
||||
"@types/react-addons-shallow-compare": "0.14.17",
|
||||
"@types/react-addons-test-utils": "0.14.15",
|
||||
"@types/react-addons-update": "0.14.14",
|
||||
"@types/react-dom": "0.14.18",
|
||||
"@types/webpack-env": ">=1.12.1 <1.14.0",
|
||||
"brace": "^0.10.0",
|
||||
"handlebars": "^4.0.6",
|
||||
"handlebars-helpers": "^0.8.2",
|
||||
"moment": "^2.18.1",
|
||||
"office-ui-fabric-react": "1.14.3",
|
||||
"react": "15.4.2",
|
||||
"react-ace": "^4.2.1",
|
||||
"react-ace": "^5.1.0",
|
||||
"react-dom": "15.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/sp-build-web": "https://registry.npmjs.org/@microsoft/sp-build-web/-/sp-build-web-1.0.0.tgz",
|
||||
"@microsoft/sp-module-interfaces": "~1.0.0",
|
||||
"@microsoft/sp-webpart-workbench": "~1.0.0",
|
||||
"@microsoft/sp-build-web": "~1.1.0",
|
||||
"@microsoft/sp-module-interfaces": "~1.1.0",
|
||||
"@microsoft/sp-webpart-workbench": "~1.1.0",
|
||||
"@types/chai": ">=3.4.34 <3.6.0",
|
||||
"@types/microsoft-ajax": "0.0.31",
|
||||
"@types/mocha": ">=2.2.33 <2.6.0",
|
||||
"@types/sharepoint": "^2013.1.4",
|
||||
"awesome-typescript-loader": "^3.2.1",
|
||||
"gulp": "~3.9.1",
|
||||
"unlazy-loader": "^0.1.2"
|
||||
},
|
||||
|
|
Binary file not shown.
|
@ -19,7 +19,8 @@ export class CamlQueryHelper {
|
|||
|
||||
// Generates the <Where /> part
|
||||
if(querySettings.filters && !isEmpty(querySettings.filters)) {
|
||||
query += Text.format('<Where>{0}</Where>', this.generateFilters(querySettings.filters));
|
||||
let sortedFilters = querySettings.filters.sort((a, b) => { if(a.index > b.index) { return 1; } else { return 0; } });
|
||||
query += Text.format('<Where>{0}</Where>', this.generateFilters(sortedFilters));
|
||||
}
|
||||
|
||||
// Generates the <OrderBy /> part
|
||||
|
@ -127,6 +128,7 @@ export class CamlQueryHelper {
|
|||
let termValue:ITag[] = [ term ];
|
||||
|
||||
let taxFilter:IQueryFilter = {
|
||||
index: null,
|
||||
field: filter.field,
|
||||
value: termValue,
|
||||
join: QueryFilterJoin.And,
|
||||
|
@ -170,6 +172,7 @@ export class CamlQueryHelper {
|
|||
let userValue:IPersonaProps[] = [ user ];
|
||||
|
||||
let userFilter:IQueryFilter = {
|
||||
index: null,
|
||||
field: filter.field,
|
||||
value: userValue,
|
||||
join: QueryFilterJoin.And,
|
||||
|
|
|
@ -14,7 +14,7 @@ export interface IContentQueryService {
|
|||
getFilterFields: (webUrl: string, listTitle: string) => Promise<IQueryFilterField[]>;
|
||||
getViewFieldsChecklistItems: (webUrl: string, listTitle: string) => Promise<IChecklistItem[]>;
|
||||
getPeoplePickerSuggestions: (webUrl: string, filterText: string, currentPersonas: IPersonaProps[], limitResults?: number) => Promise<IPersonaProps[]>;
|
||||
getTaxonomyPickerSuggestions: (webUrl: string, listTitle: string, field: IQueryFilterField, filterText: string, currentTerms: ITag[]) => Promise<IPersonaProps[]>;
|
||||
getTaxonomyPickerSuggestions: (webUrl: string, listTitle: string, field: IQueryFilterField, filterText: string, currentTerms: ITag[]) => Promise<ITag[]>;
|
||||
ensureFileResolves: (filePath: string) => Promise<{}>;
|
||||
isValidTemplateFile: (filePath: string) => boolean;
|
||||
generateDefaultTemplate: (viewFields: string[]) => string;
|
||||
|
|
|
@ -35,29 +35,18 @@ export class ListService {
|
|||
};
|
||||
let options: ISPHttpClientOptions = { headers: { 'odata-version': '3.0' }, body: JSON.stringify(data) };
|
||||
|
||||
// Tests the web URL against 404 errors before executing the query, to avoid a bug that occurs with SPHttpClient.post when trying to post
|
||||
// https://github.com/SharePoint/sp-dev-docs/issues/553
|
||||
this.spHttpClient.get(webUrl, SPHttpClient.configurations.v1, { method: 'HEAD' })
|
||||
.then((headResponse: SPHttpClientResponse) => {
|
||||
if(headResponse.status != 404) {
|
||||
|
||||
// If there is no 404, proceeds with the CAML query
|
||||
this.spHttpClient.post(endpoint, SPHttpClient.configurations.v1, options)
|
||||
.then((postResponse: SPHttpClientResponse) => {
|
||||
if(postResponse.ok) {
|
||||
resolve(postResponse.json());
|
||||
}
|
||||
else {
|
||||
reject(postResponse);
|
||||
}
|
||||
})
|
||||
.catch((error) => { reject(error); });
|
||||
this.spHttpClient.post(endpoint, SPHttpClient.configurations.v1, options)
|
||||
.then((postResponse: SPHttpClientResponse) => {
|
||||
if(postResponse.ok) {
|
||||
resolve(postResponse.json());
|
||||
}
|
||||
else {
|
||||
reject(headResponse);
|
||||
reject(postResponse);
|
||||
}
|
||||
})
|
||||
.catch((error) => { reject(error); });
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import { QueryFilterJoin } from './QueryFilterJoin';
|
|||
import { IPersonaProps, ITag } from 'office-ui-fabric-react';
|
||||
|
||||
export interface IQueryFilter {
|
||||
index: number;
|
||||
field: IQueryFilterField;
|
||||
operator: QueryFilterOperator;
|
||||
value: string | IPersonaProps[] | ITag[] | Date;
|
||||
|
|
|
@ -9,8 +9,7 @@ export interface IQueryFilterProps {
|
|||
fields: IQueryFilterField[];
|
||||
onLoadTaxonomyPickerSuggestions: (field: IQueryFilterField, filterText: string, currentTerms: ITag[]) => Promise<ITag[]>;
|
||||
onLoadPeoplePickerSuggestions: (filterText: string, currentPersonas: IPersonaProps[], limitResults?: number) => Promise<IPersonaProps[]>;
|
||||
onChanged?: (filter: IQueryFilter, index: number) => void;
|
||||
onChanged?: (filter: IQueryFilter) => void;
|
||||
disabled?: boolean;
|
||||
strings: IQueryFilterStrings;
|
||||
index?: number;
|
||||
}
|
|
@ -33,7 +33,7 @@ export class QueryFilter extends React.Component<IQueryFilterProps, IQueryFilter
|
|||
moment.locale(this.props.strings.datePickerLocale);
|
||||
|
||||
this.state = {
|
||||
filter: (this.props.filter ? cloneDeep(this.props.filter) : { field: null, operator: QueryFilterOperator.Eq, value: '', join: QueryFilterJoin.Or }),
|
||||
filter: (this.props.filter ? cloneDeep(this.props.filter) : { index: 0, field: null, operator: QueryFilterOperator.Eq, value: '', join: QueryFilterJoin.Or }),
|
||||
pickersKey: Math.random()
|
||||
};
|
||||
|
||||
|
@ -71,8 +71,10 @@ export class QueryFilter extends React.Component<IQueryFilterProps, IQueryFilter
|
|||
* When the TextField value changes
|
||||
*************************************************************************************/
|
||||
private onValueTextFieldChange(newValue: string): string {
|
||||
this.state.filter.value = newValue;
|
||||
this.onAnyChange();
|
||||
if(this.state.filter.value != newValue) {
|
||||
this.state.filter.value = newValue;
|
||||
this.onAnyChange();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -169,7 +171,7 @@ export class QueryFilter extends React.Component<IQueryFilterProps, IQueryFilter
|
|||
*************************************************************************************/
|
||||
private onAnyChange() {
|
||||
if(this.props.onChanged) {
|
||||
this.props.onChanged(this.state.filter, this.props.index);
|
||||
this.props.onChanged(this.state.filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,14 +15,6 @@ import styles from './QueryFilterPanel.module.
|
|||
|
||||
export class QueryFilterPanel extends React.Component<IQueryFilterPanelProps, IQueryFilterPanelState> {
|
||||
|
||||
/*************************************************************************************
|
||||
* Adds a default filter that always appears
|
||||
*************************************************************************************/
|
||||
private defaultFilters:IQueryFilter[] = [
|
||||
{ field: null, operator: QueryFilterOperator.Eq, join: QueryFilterJoin.Or, value: '' }
|
||||
];
|
||||
|
||||
|
||||
/*************************************************************************************
|
||||
* Component's constructor
|
||||
* @param props
|
||||
|
@ -48,11 +40,11 @@ export class QueryFilterPanel extends React.Component<IQueryFilterPanelProps, IQ
|
|||
*************************************************************************************/
|
||||
private getDefaultFilters():IQueryFilter[] {
|
||||
if(this.props.filters != null && this.props.filters.length > 0) {
|
||||
return this.props.filters;
|
||||
return this.sortFiltersByIndex(this.props.filters);
|
||||
}
|
||||
|
||||
let defaultFilters:IQueryFilter[] = [
|
||||
{ field: null, operator: QueryFilterOperator.Eq, join: QueryFilterJoin.Or, value: '' }
|
||||
{ index: 0, field: null, operator: QueryFilterOperator.Eq, join: QueryFilterJoin.Or, value: '' }
|
||||
];
|
||||
return defaultFilters;
|
||||
}
|
||||
|
@ -83,9 +75,7 @@ export class QueryFilterPanel extends React.Component<IQueryFilterPanelProps, IQ
|
|||
|
||||
this.setState((prevState: IQueryFilterPanelState, props: IQueryFilterPanelProps): IQueryFilterPanelState => {
|
||||
prevState.loading = true;
|
||||
prevState.fields = new Array<IQueryFilterField>();
|
||||
prevState.error = null;
|
||||
prevState.filters = this.getDefaultFilters();
|
||||
return prevState;
|
||||
});
|
||||
|
||||
|
@ -93,6 +83,7 @@ export class QueryFilterPanel extends React.Component<IQueryFilterPanelProps, IQ
|
|||
this.setState((prevState: IQueryFilterPanelState, props: IQueryFilterPanelProps): IQueryFilterPanelState => {
|
||||
prevState.loading = false;
|
||||
prevState.fields = fields;
|
||||
prevState.filters = this.getDefaultFilters();
|
||||
return prevState;
|
||||
});
|
||||
})
|
||||
|
@ -109,17 +100,18 @@ export class QueryFilterPanel extends React.Component<IQueryFilterPanelProps, IQ
|
|||
/*************************************************************************************
|
||||
* When one of the filter changes
|
||||
*************************************************************************************/
|
||||
private onFilterChanged(filter:IQueryFilter, index:number): void {
|
||||
private onFilterChanged(filter:IQueryFilter): void {
|
||||
// Makes sure the parent is not notified for no reason if the modified filter was (and still is) considered empty
|
||||
let isWorthNotifyingParent = true;
|
||||
let oldFilter = this.state.filters[index];
|
||||
let oldFilter = this.state.filters.filter((i) => { return i.index == filter.index; })[0];
|
||||
let oldFilterIndex = this.state.filters.indexOf(oldFilter);
|
||||
|
||||
if(this.props.trimEmptyFiltersOnChange && this.isFilterEmpty(oldFilter) && this.isFilterEmpty(filter)) {
|
||||
isWorthNotifyingParent = false;
|
||||
}
|
||||
|
||||
// Updates the modified filter in the state
|
||||
this.state.filters[index] = cloneDeep(filter);
|
||||
this.state.filters[oldFilterIndex] = cloneDeep(filter);
|
||||
this.setState((prevState: IQueryFilterPanelState, props: IQueryFilterPanelProps): IQueryFilterPanelState => {
|
||||
prevState.filters = this.state.filters;
|
||||
return prevState;
|
||||
|
@ -170,7 +162,8 @@ export class QueryFilterPanel extends React.Component<IQueryFilterPanelProps, IQ
|
|||
*************************************************************************************/
|
||||
private onAddFilterClick(): void {
|
||||
// Updates the state with an all fresh new filter
|
||||
let newFilter:IQueryFilter = { field: null, operator: QueryFilterOperator.Eq, join: QueryFilterJoin.Or, value: '' };
|
||||
let nextAvailableFilterIndex = this.state.filters[this.state.filters.length-1].index + 1;
|
||||
let newFilter:IQueryFilter = { index: nextAvailableFilterIndex, field: null, operator: QueryFilterOperator.Eq, join: QueryFilterJoin.Or, value: '' };
|
||||
this.state.filters.push(newFilter);
|
||||
|
||||
this.setState((prevState: IQueryFilterPanelState, props: IQueryFilterPanelProps): IQueryFilterPanelState => {
|
||||
|
@ -180,6 +173,13 @@ export class QueryFilterPanel extends React.Component<IQueryFilterPanelProps, IQ
|
|||
}
|
||||
|
||||
|
||||
private sortFiltersByIndex(filters:IQueryFilter[]): IQueryFilter[] {
|
||||
return filters.sort((a, b) => {
|
||||
if(a.index > b.index) { return 1; } else { return 0; }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************************
|
||||
* Renders the the QueryFilter component
|
||||
*************************************************************************************/
|
||||
|
@ -196,7 +196,7 @@ export class QueryFilterPanel extends React.Component<IQueryFilterPanelProps, IQ
|
|||
onLoadPeoplePickerSuggestions={this.props.onLoadPeoplePickerSuggestions}
|
||||
onChanged={this.onFilterChanged.bind(this)}
|
||||
strings={this.props.strings.queryFilterStrings}
|
||||
index={index} />
|
||||
key={index} />
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ import { PropertyPaneAsyncDropdown }
|
|||
import { PropertyPaneQueryFilterPanel } from '../../controls/PropertyPaneQueryFilterPanel/PropertyPaneQueryFilterPanel';
|
||||
import { PropertyPaneAsyncChecklist } from '../../controls/PropertyPaneAsyncChecklist/PropertyPaneAsyncChecklist';
|
||||
import { PropertyPaneTextDialog } from '../../controls/PropertyPaneTextDialog/PropertyPaneTextDialog';
|
||||
import { IQueryFilter } from '../../controls/PropertyPaneQueryFilterPanel/components/QueryFilter/IQueryFilter';
|
||||
import { IQueryFilterField } from '../../controls/PropertyPaneQueryFilterPanel/components/QueryFilter/IQueryFilterField';
|
||||
import { IChecklistItem } from '../../controls/PropertyPaneAsyncChecklist/components/AsyncChecklist/IChecklistItem';
|
||||
import { ContentQueryService } from '../../common/services/ContentQueryService';
|
||||
|
@ -55,7 +54,7 @@ export default class ContentQueryWebPart extends BaseClientSideWebPart<IContentQ
|
|||
* Returns the WebPart's version
|
||||
***************************************************************************/
|
||||
protected get dataVersion(): Version {
|
||||
return Version.parse('1.0.1');
|
||||
return Version.parse('1.0.2');
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,7 +113,7 @@ export default class ContentQueryWebPart extends BaseClientSideWebPart<IContentQ
|
|||
loadingLabel: strings.WebUrlFieldLoadingLabel,
|
||||
errorLabelFormat: strings.WebUrlFieldLoadingError,
|
||||
loadOptions: this.loadWebUrlOptions.bind(this),
|
||||
onPropertyChange: this.onWebUrlChange.bind(this),
|
||||
onPropertyChange: this.onCustomPropertyPaneChange.bind(this),
|
||||
selectedKey: this.properties.webUrl || ""
|
||||
});
|
||||
|
||||
|
@ -124,7 +123,7 @@ export default class ContentQueryWebPart extends BaseClientSideWebPart<IContentQ
|
|||
loadingLabel: strings.ListTitleFieldLoadingLabel,
|
||||
errorLabelFormat: strings.ListTitleFieldLoadingError,
|
||||
loadOptions: this.loadListTitleOptions.bind(this),
|
||||
onPropertyChange: this.onListTitleChange.bind(this),
|
||||
onPropertyChange: this.onCustomPropertyPaneChange.bind(this),
|
||||
selectedKey: this.properties.listTitle || "",
|
||||
disabled: firstCascadingLevelDisabled
|
||||
});
|
||||
|
@ -135,7 +134,7 @@ export default class ContentQueryWebPart extends BaseClientSideWebPart<IContentQ
|
|||
loadingLabel: strings.OrderByFieldLoadingLabel,
|
||||
errorLabelFormat: strings.OrderByFieldLoadingError,
|
||||
loadOptions: this.loadOrderByOptions.bind(this),
|
||||
onPropertyChange: this.onOrderByChange.bind(this),
|
||||
onPropertyChange: this.onCustomPropertyPaneChange.bind(this),
|
||||
selectedKey: this.properties.orderBy || "",
|
||||
disabled: secondCascadingLevelDisabled
|
||||
});
|
||||
|
@ -146,7 +145,7 @@ export default class ContentQueryWebPart extends BaseClientSideWebPart<IContentQ
|
|||
loadFields: this.loadFilterFields.bind(this),
|
||||
onLoadTaxonomyPickerSuggestions: this.loadTaxonomyPickerSuggestions.bind(this),
|
||||
onLoadPeoplePickerSuggestions: this.loadPeoplePickerSuggestions.bind(this),
|
||||
onPropertyChange: this.onFiltersChange.bind(this),
|
||||
onPropertyChange: this.onCustomPropertyPaneChange.bind(this),
|
||||
trimEmptyFiltersOnChange: true,
|
||||
disabled: secondCascadingLevelDisabled,
|
||||
strings: strings.queryFilterPanelStrings
|
||||
|
@ -156,7 +155,7 @@ export default class ContentQueryWebPart extends BaseClientSideWebPart<IContentQ
|
|||
this.viewFieldsChecklist = new PropertyPaneAsyncChecklist(ContentQueryConstants.propertyViewFields, {
|
||||
loadItems: this.loadViewFieldsChecklistItems.bind(this),
|
||||
checkedItems: this.properties.viewFields,
|
||||
onPropertyChange: this.onViewFieldsChange.bind(this),
|
||||
onPropertyChange: this.onCustomPropertyPaneChange.bind(this),
|
||||
disable: secondCascadingLevelDisabled,
|
||||
strings: strings.viewFieldsChecklistStrings
|
||||
});
|
||||
|
@ -164,7 +163,7 @@ export default class ContentQueryWebPart extends BaseClientSideWebPart<IContentQ
|
|||
// Creates a custom PropertyPaneTextDialog for the templateText property
|
||||
this.templateTextDialog = new PropertyPaneTextDialog(ContentQueryConstants.propertyTemplateText, {
|
||||
dialogTextFieldValue: this.properties.templateText,
|
||||
onPropertyChange: this.onTemplateTextChange.bind(this),
|
||||
onPropertyChange: this.onCustomPropertyPaneChange.bind(this),
|
||||
disabled: false,
|
||||
strings: strings.templateTextStrings
|
||||
});
|
||||
|
@ -238,17 +237,7 @@ export default class ContentQueryWebPart extends BaseClientSideWebPart<IContentQ
|
|||
groupName: strings.DisplayGroupName,
|
||||
groupFields: [
|
||||
this.viewFieldsChecklist,
|
||||
this.templateTextDialog
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
header: { description: strings.ExternalPageDescription },
|
||||
groups: [
|
||||
{
|
||||
groupName: strings.ExternalGroupName,
|
||||
groupFields: [
|
||||
this.templateTextDialog,
|
||||
this.templateUrlTextField
|
||||
]
|
||||
}
|
||||
|
@ -339,116 +328,59 @@ export default class ContentQueryWebPart extends BaseClientSideWebPart<IContentQ
|
|||
|
||||
|
||||
/***************************************************************************
|
||||
* Handles the change of the webUrl property
|
||||
* When a custom property pane updates
|
||||
***************************************************************************/
|
||||
private onWebUrlChange(propertyPath: string, newValue: any): void {
|
||||
Log.verbose(this.logSource, "WebPart property 'webUrl' has changed, refreshing WebPart...", this.context.serviceScope);
|
||||
private onCustomPropertyPaneChange(propertyPath: string, newValue: any): void {
|
||||
Log.verbose(this.logSource, "WebPart property '" + propertyPath + "' has changed, refreshing WebPart...", this.context.serviceScope);
|
||||
let rerenderTemplateTextDialog = false;
|
||||
const oldValue = get(this.properties, propertyPath);
|
||||
|
||||
|
||||
// Stores the new value in web part properties
|
||||
update(this.properties, propertyPath, (): any => { return newValue; });
|
||||
|
||||
// Resets the web-dependent property panes
|
||||
this.resetListTitlePropertyPane();
|
||||
this.resetOrderByPropertyPane();
|
||||
this.resetFiltersPropertyPane();
|
||||
this.resetViewFieldsPropertyPane();
|
||||
|
||||
// Refreshes the web part
|
||||
this.onPropertyPaneFieldChanged(propertyPath, oldValue, newValue);
|
||||
}
|
||||
|
||||
// Resets dependent property panes if needed
|
||||
this.resetDependentPropertyPanes(propertyPath);
|
||||
|
||||
/***************************************************************************
|
||||
* Handles the change of the listTitle property
|
||||
***************************************************************************/
|
||||
private onListTitleChange(propertyPath: string, newValue: any): void {
|
||||
Log.verbose(this.logSource, "WebPart property 'listTitle' has changed, refreshing WebPart...", this.context.serviceScope);
|
||||
const oldValue = get(this.properties, propertyPath);
|
||||
|
||||
// Stores the new value in web part properties
|
||||
update(this.properties, propertyPath, (): any => { return newValue; });
|
||||
|
||||
// Resets the list-dependent property panes
|
||||
this.resetOrderByPropertyPane();
|
||||
this.resetFiltersPropertyPane();
|
||||
this.resetViewFieldsPropertyPane();
|
||||
|
||||
// refresh web part
|
||||
this.onPropertyPaneFieldChanged(propertyPath, oldValue, newValue);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Handles the change of the orderBy property
|
||||
***************************************************************************/
|
||||
private onOrderByChange(propertyPath: string, newValue: string): void {
|
||||
Log.verbose(this.logSource, "WebPart property 'orderBy' has changed, refreshing WebPart...", this.context.serviceScope);
|
||||
const oldValue = get(this.properties, propertyPath);
|
||||
|
||||
// Stores the new value in web part properties
|
||||
update(this.properties, propertyPath, (): any => { return newValue; });
|
||||
|
||||
// refresh web part
|
||||
this.onPropertyPaneFieldChanged(propertyPath, oldValue, newValue);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Handles the change of the filters property
|
||||
***************************************************************************/
|
||||
private onFiltersChange(propertyPath: string, newFilters:IQueryFilter[]) {
|
||||
Log.verbose(this.logSource, "WebPart property 'filters' has changed, refreshing WebPart...", this.context.serviceScope);
|
||||
const oldValue = get(this.properties, propertyPath);
|
||||
|
||||
// Stores the new value in web part properties
|
||||
update(this.properties, propertyPath, (): any => { return newFilters; });
|
||||
|
||||
// refresh web part
|
||||
this.onPropertyPaneFieldChanged(propertyPath, oldValue, newFilters);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Handles the change of the viewFields property
|
||||
***************************************************************************/
|
||||
private onViewFieldsChange(propertyPath: string, checkedKeys: string[]) {
|
||||
Log.verbose(this.logSource, "WebPart property 'viewFields' has changed, refreshing WebPart...", this.context.serviceScope);
|
||||
const oldValue = get(this.properties, propertyPath);
|
||||
|
||||
// Stores the new value in web part properties
|
||||
update(this.properties, propertyPath, (): any => { return checkedKeys; });
|
||||
|
||||
// Updates the default template text if it hasn't been altered by the user
|
||||
if(!this.properties.hasDefaultTemplateBeenUpdated) {
|
||||
let generatedTemplate = this.ContentQueryService.generateDefaultTemplate(checkedKeys);
|
||||
// If the viewfields have changed, update the default template text if it hasn't been altered by the user
|
||||
if(propertyPath == ContentQueryConstants.propertyViewFields && !this.properties.hasDefaultTemplateBeenUpdated) {
|
||||
let generatedTemplate = this.ContentQueryService.generateDefaultTemplate(newValue);
|
||||
update(this.properties, ContentQueryConstants.propertyTemplateText, (): any => { return generatedTemplate; });
|
||||
this.templateTextDialog.properties.dialogTextFieldValue = generatedTemplate;
|
||||
this.templateTextDialog.render();
|
||||
rerenderTemplateTextDialog = true;
|
||||
}
|
||||
|
||||
// refresh web part
|
||||
this.onPropertyPaneFieldChanged(propertyPath, oldValue, checkedKeys);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Handles the change of the viewFields property
|
||||
***************************************************************************/
|
||||
private onTemplateTextChange(propertyPath: string, text: string) {
|
||||
Log.verbose(this.logSource, "WebPart property 'templateText' has changed, refreshing WebPart...", this.context.serviceScope);
|
||||
const oldValue = get(this.properties, propertyPath);
|
||||
|
||||
// Stores the new value in web part properties
|
||||
update(this.properties, propertyPath, (): any => { return text; });
|
||||
|
||||
// Updates the "hasDefaultTemplateBeenUpdated" to true so the WebPart doesn't override the user template after updating view fields
|
||||
if(!this.properties.hasDefaultTemplateBeenUpdated) {
|
||||
// If the templateText have changed, update the "hasDefaultTemplateBeenUpdated" to true so the WebPart doesn't override the user template after updating view fields
|
||||
if(propertyPath == ContentQueryConstants.propertyTemplateText && !this.properties.hasDefaultTemplateBeenUpdated) {
|
||||
update(this.properties, ContentQueryConstants.propertyhasDefaultTemplateBeenUpdated, (): any => { return true; });
|
||||
}
|
||||
|
||||
// refresh web part
|
||||
this.onPropertyPaneFieldChanged(propertyPath, oldValue, text);
|
||||
// Refreshes the web part manually because custom fields don't update since sp-webpart-base@1.1.1
|
||||
// https://github.com/SharePoint/sp-dev-docs/issues/594
|
||||
if (!this.disableReactivePropertyChanges)
|
||||
this.render();
|
||||
|
||||
if(rerenderTemplateTextDialog) {
|
||||
this.templateTextDialog.render();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Resets dependent property panes if needed
|
||||
***************************************************************************/
|
||||
private resetDependentPropertyPanes(propertyPath: string): void {
|
||||
if(propertyPath == ContentQueryConstants.propertyWebUrl) {
|
||||
this.resetListTitlePropertyPane();
|
||||
this.resetOrderByPropertyPane();
|
||||
this.resetFiltersPropertyPane();
|
||||
this.resetViewFieldsPropertyPane();
|
||||
}
|
||||
else if (propertyPath == ContentQueryConstants.propertyListTitle) {
|
||||
this.resetOrderByPropertyPane();
|
||||
this.resetFiltersPropertyPane();
|
||||
this.resetViewFieldsPropertyPane();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,11 +3,9 @@ define([], function() {
|
|||
SourcePageDescription: "Specify where the WebPart should get the results from.",
|
||||
QueryPageDescription: "If needed, choose the sorting behavior, limit the results, or add filters in order to narrow the query down.",
|
||||
DisplayPageDescription: "Specify which fields should be available for rendering within the HandleBars template, and edit your handlebars template.",
|
||||
ExternalPageDescription: "Optionally, externalize the properties below by specifying valid sharepoint urls.",
|
||||
SourceGroupName: "Source",
|
||||
QueryGroupName: "Query",
|
||||
DisplayGroupName: "Display",
|
||||
ExternalGroupName: "External Resources",
|
||||
WebUrlFieldLabel: "Web Url",
|
||||
WebUrlFieldPlaceholder: "Select the source web...",
|
||||
WebUrlFieldLoadingLabel: "Loading webs from current site...",
|
||||
|
|
|
@ -2,11 +2,9 @@ declare interface IContentQueryStrings {
|
|||
SourcePageDescription: string;
|
||||
QueryPageDescription: string;
|
||||
DisplayPageDescription: string;
|
||||
ExternalPageDescription: string;
|
||||
SourceGroupName: string;
|
||||
QueryGroupName: string;
|
||||
DisplayGroupName: string;
|
||||
ExternalGroupName: string;
|
||||
WebUrlFieldLabel: string;
|
||||
WebUrlFieldPlaceholder: string;
|
||||
WebUrlFieldLoadingLabel: string;
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"types": [
|
||||
"es6-promise",
|
||||
"es6-collections",
|
||||
"webpack-env",
|
||||
"microsoft-ajax",
|
||||
"sharepoint"
|
||||
"webpack-env"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,4 +5,7 @@
|
|||
Code that is wrapped inside an if(UNIT_TEST) {...}
|
||||
block will not be included in the final bundle when the
|
||||
--ship flag is specified */
|
||||
declare const UNIT_TEST: boolean;
|
||||
declare const UNIT_TEST: boolean;
|
||||
|
||||
/* Global defintion for SPO builds */
|
||||
declare const DATACENTER: boolean;
|
Loading…
Reference in New Issue