Skip to content

Commit

Permalink
Merge pull request #3041 from microsoft-search/fix/2893
Browse files Browse the repository at this point in the history
Prefer thumbnailurl if present
  • Loading branch information
wobba committed May 29, 2023
2 parents 5536fe3 + e1b3f09 commit bf680f2
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 65 deletions.
3 changes: 2 additions & 1 deletion search-parts/src/dataSources/SharePointSearchDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,8 @@ export class SharePointSearchDataSource extends BaseDataSource<ISharePointSearch
'SiteTitle',
'CreatedBy',
'HtmlFileType',
'SiteLogo'
'SiteLogo',
'PictureThumbnailURL'
];
this.properties.resultSourceId = this.properties.resultSourceId !== undefined ? this.properties.resultSourceId : BuiltinSourceIds.LocalSharePointResults;
this.properties.hitHighlightedProperties = this.properties.hitHighlightedProperties ? this.properties.hitHighlightedProperties : '';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ export default class SearchResultsContainer extends React.Component<ISearchResul
};

this.templateService = this.props.serviceScope.consume<ITemplateService>(TemplateService.ServiceKey);

this._onSelectionChanged = this._onSelectionChanged.bind(this);

this._selection = new Selection({
onSelectionChanged: this._onSelectionChanged,
getKey: (item, index) => {
// Not suitable as keys
// - Stringified object as we can't rely on field values. Ex they can diverge from calls with SharePoint (ex: piSearchResultId with SharePoint)
return item.key = `${this.props.dataContext.pageNumber}${index}`;
// Not suitable as keys
// - Stringified object as we can't rely on field values. Ex they can diverge from calls with SharePoint (ex: piSearchResultId with SharePoint)
return item.key = `${this.props.dataContext.pageNumber}${index}`;
},
});
}
Expand Down Expand Up @@ -105,23 +105,23 @@ export default class SearchResultsContainer extends React.Component<ISearchResul
templateContent = this.templateService.getTemplateMarkup(this.props.templateContent);
const templateContext = this.getTemplateContext();
let renderType = this.props.renderType;

let selectionMode = SelectionMode.none;
if (this.props.properties.itemSelectionProps && this.props.properties.itemSelectionProps.allowItemSelection) {
selectionMode = this.props.properties.itemSelectionProps.allowMulti ? SelectionMode.multiple : SelectionMode.single;
selectionMode = this.props.properties.itemSelectionProps.allowMulti ? SelectionMode.multiple : SelectionMode.single;
}
renderTemplate = <SelectionZone
selection={this._selection}
selectionMode={selectionMode}>
<TemplateRenderer
templateContent={templateContent}
templateContext={templateContext}
templateService={this.templateService}
instanceId={this.props.instanceId}
renderType={renderType}
/>
</SelectionZone>;

renderTemplate = <SelectionZone
selection={this._selection}
selectionMode={selectionMode}>
<TemplateRenderer
templateContent={templateContent}
templateContext={templateContext}
templateService={this.templateService}
instanceId={this.props.instanceId}
renderType={renderType}
/>
</SelectionZone>;

// Determine if the component should show content according to Web Part parameters
if (this.state.data && this.state.data.items.length === 0) {
Expand Down Expand Up @@ -208,15 +208,15 @@ export default class SearchResultsContainer extends React.Component<ISearchResul

if (!isEqual(prevProps.dataContext.pageNumber, this.props.dataContext.pageNumber)) {
// Save the last selected keys for the current selection to be able to track items across pages
this._lastPageSelectedKeys = this._selection.getSelection().map(item => item.key as string);
this._lastPageSelectedKeys = this._selection.getSelection().map(item => item.key as string);

// This is WebKit only, so defensively code and fallback to "scrollIntoView"
if ((this._searchWebPartRef as any).scrollIntoViewIfNeeded) {
if ((this._searchWebPartRef as any).scrollIntoViewIfNeeded) {
(this._searchWebPartRef as any).scrollIntoViewIfNeeded(false);
} else {
} else {
// Scroll to the top of the component
this._searchWebPartRef.scrollIntoView(true);
}
}
}

await this.getDataFromDataSource(this.props.dataContext.pageNumber);
Expand All @@ -226,7 +226,7 @@ export default class SearchResultsContainer extends React.Component<ISearchResul
// Reset already selected items
this._selection.setItems(this.state.data.items, true);
}

}

/**
Expand Down Expand Up @@ -337,7 +337,7 @@ export default class SearchResultsContainer extends React.Component<ISearchResul
let webUrl = ObjectHelper.byPath(item, "SPWebUrl");
let uniqueId = ObjectHelper.byPath(item, "NormUniqueID");
const itemFileType = ObjectHelper.byPath(item, slots[BuiltinTemplateSlots.FileType]);
if( webUrl && uniqueId && itemFileType && itemFileType.toUpperCase() !== "ASPX") {
if (webUrl && uniqueId && itemFileType && itemFileType.toUpperCase() !== "ASPX") {
item.AutoPreviewUrl = `${webUrl}/_layouts/15/viewer.aspx?sourcedoc={${uniqueId}}`;
} else if (pathProperty && pathProperty.indexOf("?") === -1 && !isContainer) {
item.AutoPreviewUrl = pathProperty + "?web=1";
Expand All @@ -355,9 +355,9 @@ export default class SearchResultsContainer extends React.Component<ISearchResul
data.items = data.items.map(item => {

let contentClass = ObjectHelper.byPath(item, BuiltinTemplateSlots.ContentClass);

if (!isEmpty(contentClass) && (contentClass.toLocaleLowerCase() == "sts_site" || contentClass.toLocaleLowerCase() == "sts_web")) {
item[AutoCalculatedDataSourceFields.AutoPreviewImageUrl] = ObjectHelper.byPath(item, "SiteLogo");
item[AutoCalculatedDataSourceFields.AutoPreviewImageUrl] = ObjectHelper.byPath(item, "SiteLogo");
}
else {
let siteId = ObjectHelper.byPath(item, slots[BuiltinTemplateSlots.SiteId]);
Expand All @@ -368,30 +368,38 @@ export default class SearchResultsContainer extends React.Component<ISearchResul
let isFolder = ObjectHelper.byPath(item, slots[BuiltinTemplateSlots.IsFolder]);
const isContainerType = isFolder === "true" || isFolder === "1" || (isFolder && isFolder.indexOf('0x0120') !== -1);

if (siteId && listId && itemId && !isContainerType) {
// SP item logic
siteId = this.getGuidFromString(siteId);
listId = this.getGuidFromString(listId);
itemId = this.getGuidFromString(itemId);

if (webId) {
siteId = siteId + "," + this.getGuidFromString(webId); // add web id if present, needed for sub-sites
}

const itemFileType = ObjectHelper.byPath(item, slots[BuiltinTemplateSlots.FileType]);

if (itemFileType && validPreviewExt.indexOf(itemFileType.toUpperCase()) !== -1) {
// Can lead to 404 errors but it is a trade of for performances. We take a guess with this url instead of batching calls for all items and process only 200.
item[AutoCalculatedDataSourceFields.AutoPreviewImageUrl] = `${this.props.pageContext.site.absoluteUrl}/_api/v2.1/sites/${siteId}/lists/${listId}/items/${itemId}/driveItem/thumbnails/0/large/content?preferNoRedirect=true`;
}
} else {
// Graph items logic
const driveId = ObjectHelper.byPath(item, slots[BuiltinTemplateSlots.DriveId]);
//GET /drives/{drive-id}/items/{item-id}/thumbnails
if (driveId && siteId && itemId) {
item[AutoCalculatedDataSourceFields.AutoPreviewImageUrl] = `${this.props.pageContext.site.absoluteUrl}/_api/v2.1/sites/${siteId}/drives/${driveId}/items/${itemId}/thumbnails/thumbnails/0/large/content?preferNoRedirect=true`;
let thumbNailUrl = ObjectHelper.byPath(item, "PictureThumbnailURL");
if (!isEmpty(thumbNailUrl)) {
if (thumbNailUrl.indexOf("/content?") !== -1 && thumbNailUrl.indexOf("closestavailablesize") === -1 && thumbNailUrl.indexOf("extendCacheMaxAge") === -1) {
thumbNailUrl = `${thumbNailUrl},closestavailablesize,extendCacheMaxAge`;
}
item[AutoCalculatedDataSourceFields.AutoPreviewImageUrl] = thumbNailUrl;
}
else
if (siteId && listId && itemId && !isContainerType) {
// SP item logic
siteId = this.getGuidFromString(siteId);
listId = this.getGuidFromString(listId);
itemId = this.getGuidFromString(itemId);

if (webId) {
siteId = siteId + "," + this.getGuidFromString(webId); // add web id if present, needed for sub-sites
}

const itemFileType = ObjectHelper.byPath(item, slots[BuiltinTemplateSlots.FileType]);

if (itemFileType && validPreviewExt.indexOf(itemFileType.toUpperCase()) !== -1) {
// Can lead to 404 errors but it is a trade of for performances. We take a guess with this url instead of batching calls for all items and process only 200.
item[AutoCalculatedDataSourceFields.AutoPreviewImageUrl] = `${this.props.pageContext.site.absoluteUrl}/_api/v2.1/sites/${siteId}/lists/${listId}/items/${itemId}/driveItem/thumbnails/0/c400x999/content?prefer=noredirect,closestavailablesize,extendCacheMaxAge`;
}
} else {
// Graph items logic
const driveId = ObjectHelper.byPath(item, slots[BuiltinTemplateSlots.DriveId]);
//GET /drives/{drive-id}/items/{item-id}/thumbnails
if (driveId && siteId && itemId) {
item[AutoCalculatedDataSourceFields.AutoPreviewImageUrl] = `${this.props.pageContext.site.absoluteUrl}/_api/v2.1/sites/${siteId}/drives/${driveId}/items/${itemId}/thumbnails/thumbnails/0/c400x999/content?prefer=noredirect,closestavailablesize,extendCacheMaxAge`;
}
}
}

if (!this.isOnlineDomain(item[AutoCalculatedDataSourceFields.AutoPreviewImageUrl])) {
Expand Down Expand Up @@ -522,7 +530,7 @@ export default class SearchResultsContainer extends React.Component<ISearchResul
selectedVertical: this.props.dataContext.verticals.selectedVertical
},
inputQueryText: this.props.dataContext.inputQueryText,
originalInputQueryText: this.props.dataContext.originalInputQueryText,
originalInputQueryText: this.props.dataContext.originalInputQueryText,
// The available template slots
slots: this.convertTemplateSlotsToHashtable(this.props.properties.templateSlots),
// The current page context
Expand Down Expand Up @@ -596,20 +604,20 @@ export default class SearchResultsContainer extends React.Component<ISearchResul
// When page is updated, the selection changed is fired clearing all previous selection
// We need to ensure the state is not updated during this phase
if (this.props.dataContext.pageNumber === this._lastPageNumber) {
const currentSelectedItems = this._selection.getSelection();
const currentPageSelectionKeys = currentSelectedItems.map(item => item.key as string);
this.props.onItemSelected(currentSelectedItems);
// Update curent selected keys and values
this.setState({
selectedItemKeys: [...this._lastPageSelectedKeys,...currentPageSelectionKeys]
}, () => {
this.forceUpdate();
});

const currentSelectedItems = this._selection.getSelection();

const currentPageSelectionKeys = currentSelectedItems.map(item => item.key as string);

this.props.onItemSelected(currentSelectedItems);

// Update curent selected keys and values
this.setState({
selectedItemKeys: [...this._lastPageSelectedKeys, ...currentPageSelectionKeys]
}, () => {
this.forceUpdate();
});
}
}

}
}

0 comments on commit bf680f2

Please sign in to comment.