Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion docs/documentation/docs/controls/FilePicker.md
Original file line number Diff line number Diff line change
@@ -107,8 +107,10 @@ The FilePicker component can be configured with the following properties:
| includePageLibraries | boolean | no | Specifies if Site Pages library to be visible on Sites tab |
| allowExternalLinks | boolean | no | Specifies if external links should be allowed. |
| checkIfFileExists | boolean | no | When using file links, this property allows the user to choose if the control should check if the link point to a file that exists or not. |
| tabOrder | FilePickerTab[]| no | Defines a custom display order for the tabs. Tabs not listed will follow their default order. |
| defaultSelectedTab | FilePickerTab | no | Sets the default selected tab. If not specified, the first visible tab is used. |

interface `IFilePickerResult`
Interface `IFilePickerResult`

Provides options for carousel buttons location.

@@ -120,4 +122,20 @@ Provides options for carousel buttons location.
| fileSize | number | Size of the result (in bytes). Set only for file upload |
| downloadFileContent | () => Promise<File> | Function allows to download file content. Returns File object. |

Enum `FilePickerTab`

Represents the available tabs in the File Picker component. Each tab corresponds to a different source from which users can select files.

| Name | Description |
|-----------------|-------------------------------------------------------|
| Recent | Displays recently used files. |
| StockImages | Shows stock image selection. |
| Web | Allows searching files from the web. |
| OrgAssets | Displays organizational assets. |
| OneDrive | Allows file selection from OneDrive. |
| Site | Enables browsing site files. |
| Upload | Provides option to upload local files. |
| Link | Lets the user add a file via a URL. |
| MultipleUpload | Supports uploading multiple files at once. |

![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/filePicker/FilePicker)
121 changes: 72 additions & 49 deletions src/controls/filePicker/FilePicker.tsx
Original file line number Diff line number Diff line change
@@ -36,6 +36,7 @@ import { StockImages } from "./StockImagesTab/StockImages";
import UploadFilePickerTab from "./UploadFilePickerTab/UploadFilePickerTab";
import MultipleUploadFilePickerTab from "./MultipleUploadFilePickerTab/MultipleUploadFilePickerTab";
import WebSearchTab from "./WebSearchTab/WebSearchTab";
import { FilePickerTab } from "./FilePickerTab";


export class FilePicker extends React.Component<
@@ -89,7 +90,7 @@ export class FilePicker extends React.Component<

this.setState({
organisationAssetsEnabled: orgAssetsEnabled,
selectedTab: this.getDefaultSelectedTabKey(this.props, orgAssetsEnabled),
selectedTab: this._getDefaultSelectedTabKey(this.props, orgAssetsEnabled),
});
if (!!this.props.context && !!this.props.webAbsoluteUrl) {
const { title, id } = await this.fileBrowserService.getSiteTitleAndId();
@@ -190,7 +191,7 @@ export class FilePicker extends React.Component<
/>
</div>
<div className={styles.tabsContainer}>
{this.state.selectedTab === "keyLink" && (
{this.state.selectedTab === FilePickerTab.Link && (
<LinkFilePickerTab
fileSearchService={this.fileSearchService}
renderCustomLinkTabContent={
@@ -201,7 +202,7 @@ export class FilePicker extends React.Component<
{...linkTabProps}
/>
)}
{this.state.selectedTab === "keyUpload" && (
{this.state.selectedTab === FilePickerTab.Upload && (
<UploadFilePickerTab
renderCustomUploadTabContent={
this.props.renderCustomUploadTabContent
@@ -210,7 +211,7 @@ export class FilePicker extends React.Component<
onChange={this._handleOnChange}
/>
)}
{this.state.selectedTab === "keyMultipleUpload" && (
{this.state.selectedTab === FilePickerTab.MultipleUpload && (
<MultipleUploadFilePickerTab
renderCustomMultipleUploadTabContent={
this.props.renderCustomMultipleUploadTabContent
@@ -219,7 +220,7 @@ export class FilePicker extends React.Component<
onChange={this._handleOnChange}
/>
)}
{this.state.selectedTab === "keySite" && (
{this.state.selectedTab === FilePickerTab.Site && (
<SiteFilePickerTab
fileBrowserService={this.fileBrowserService}
includePageLibraries={this.props.includePageLibraries}
@@ -230,37 +231,37 @@ export class FilePicker extends React.Component<
{...linkTabProps}
/>
)}
{this.state.selectedTab === "keyOrgAssets" && (
{this.state.selectedTab === FilePickerTab.OrgAssets && (
<SiteFilePickerTab
breadcrumbFirstNode={{
isCurrentItem: true,
text: strings.OrgAssetsTabLabel,
key: "keyOrgAssets",
key: FilePickerTab.OrgAssets,
}}
fileBrowserService={this.orgAssetsService}
webTitle={this.state.webTitle}
{...linkTabProps}
/>
)}
{this.state.selectedTab === "keyWeb" && (
{this.state.selectedTab === FilePickerTab.Web && (
<WebSearchTab
bingSearchService={this.fileSearchService}
{...linkTabProps}
/>
)}
{this.state.selectedTab === "keyOneDrive" && (
{this.state.selectedTab === FilePickerTab.OneDrive && (
<OneDriveFilesTab
oneDriveService={this.oneDriveService}
{...linkTabProps}
/>
)}
{this.state.selectedTab === "keyRecent" && (
{this.state.selectedTab === FilePickerTab.Recent && (
<RecentFilesTab
fileSearchService={this.fileSearchService}
{...linkTabProps}
/>
)}
{this.state.selectedTab === "keyStockImages" && (
{this.state.selectedTab === FilePickerTab.StockImages && (
<StockImages
language={
this.props.context.pageContext.cultureInfo.currentCultureName
@@ -294,7 +295,7 @@ export class FilePicker extends React.Component<
private _handleOpenPanel = (): void => {
this.setState({
panelOpen: true,
selectedTab: this.getDefaultSelectedTabKey(
selectedTab: this._getDefaultSelectedTabKey(
this.props,
this.state.organisationAssetsEnabled
),
@@ -344,29 +345,29 @@ export class FilePicker extends React.Component<
*/
private _getNavPanelOptions = (): INavLinkGroup[] => {
const addUrl = this.props.storeLastActiveTab !== false;
const links = [];
let links = [];

if (!this.props.hideRecentTab) {
links.push({
name: strings.RecentLinkLabel,
url: addUrl ? "#recent" : undefined,
icon: "Recent",
key: "keyRecent",
key: FilePickerTab.Recent,
});
}
if (!this.props.hideStockImages) {
links.push({
name: strings.StockImagesLinkLabel,
url: addUrl ? "#stockImages" : undefined,
key: "keyStockImages",
key: FilePickerTab.StockImages,
icon: "ImageSearch",
});
}
if (this.props.bingAPIKey && !this.props.hideWebSearchTab) {
links.push({
name: strings.WebSearchLinkLabel,
url: addUrl ? "#search" : undefined,
key: "keyWeb",
key: FilePickerTab.Web,
icon: "Search",
});
}
@@ -378,85 +379,107 @@ export class FilePicker extends React.Component<
name: strings.OrgAssetsLinkLabel,
url: addUrl ? "#orgAssets" : undefined,
icon: "FabricFolderConfirm",
key: "keyOrgAssets",
key: FilePickerTab.OrgAssets,
});
}
if (!this.props.hideOneDriveTab) {
links.push({
name: "OneDrive",
url: addUrl ? "#onedrive" : undefined,
key: "keyOneDrive",
key: FilePickerTab.OneDrive,
icon: "OneDrive",
});
}
if (!this.props.hideSiteFilesTab) {
links.push({
name: strings.SiteLinkLabel,
url: addUrl ? "#globe" : undefined,
key: "keySite",
key: FilePickerTab.Site,
icon: "Globe",
});
}
if (!this.props.hideLocalUploadTab) {
links.push({
name: strings.UploadLinkLabel,
url: addUrl ? "#upload" : undefined,
key: "keyUpload",
key: FilePickerTab.Upload,
icon: "System",
});
}
if (!this.props.hideLocalMultipleUploadTab) {
links.push({
name: strings.UploadLinkLabel + " " + strings.OneDriveRootFolderName,
url: addUrl ? "#Multipleupload" : undefined,
key: "keyMultipleUpload",
key: FilePickerTab.MultipleUpload,
icon: "BulkUpload",
});
}
if (!this.props.hideLinkUploadTab) {
links.push({
name: strings.FromLinkLinkLabel,
url: addUrl ? "#link" : undefined,
key: "keyLink",
key: FilePickerTab.Link,
icon: "Link",
});
}

if(this.props.tabOrder) {
links = this._getTabOrder(links);
}

const groups: INavLinkGroup[] = [{ links }];
return groups;
}

private getDefaultSelectedTabKey = (
/**
* Sorts navigation tabs based on the tabOrder prop
*/
private _getTabOrder = (links): INavLink[] => {
const sortedKeys = [
...this.props.tabOrder,
...links.map(l => l.key).filter(key => !this.props.tabOrder.includes(key)),
];

links.sort((a, b) => {
return sortedKeys.indexOf(a.key) - sortedKeys.indexOf(b.key);
});

return links;
};

/**
* Returns the default selected tab key
*/
private _getDefaultSelectedTabKey = (
props: IFilePickerProps,
orgAssetsEnabled: boolean
): string => {
if (!props.hideRecentTab) {
return "keyRecent";
}
if (!props.hideStockImages) {
return "keyStockImages";
}
if (props.bingAPIKey && !props.hideWebSearchTab) {
return "keyWeb";
}
if (!props.hideOrganisationalAssetTab && orgAssetsEnabled) {
return "keyOrgAssets";
}
if (!props.hideOneDriveTab) {
return "keyOneDrive";
}
if (!props.hideSiteFilesTab) {
return "keySite";
}
if (!props.hideLocalUploadTab) {
return "keyUpload";
}
if (!props.hideLinkUploadTab) {
return "keyLink";
}
if (!props.hideLocalMultipleUploadTab) {
return "keyMultipleUpload";
const tabsConfig = [
{ isTabVisible: !props.hideRecentTab, tabKey: FilePickerTab.Recent },
{ isTabVisible: !props.hideStockImages, tabKey: FilePickerTab.StockImages },
{ isTabVisible: props.bingAPIKey && !props.hideWebSearchTab, tabKey: FilePickerTab.Web },
{ isTabVisible: !props.hideOrganisationalAssetTab && orgAssetsEnabled, tabKey: FilePickerTab.OrgAssets },
{ isTabVisible: !props.hideOneDriveTab, tabKey: FilePickerTab.OneDrive },
{ isTabVisible: !props.hideSiteFilesTab, tabKey: FilePickerTab.Site },
{ isTabVisible: !props.hideLocalUploadTab, tabKey: FilePickerTab.Upload },
{ isTabVisible: !props.hideLinkUploadTab, tabKey: FilePickerTab.Link },
{ isTabVisible: !props.hideLocalMultipleUploadTab, tabKey: FilePickerTab.MultipleUpload }
];

const visibleTabs = tabsConfig.filter(tab => tab.isTabVisible);
const visibleTabKeys = visibleTabs.map(tab => tab.tabKey);

// If defaultSelectedTab is provided and is visible, then return tabKey
if(this.props.defaultSelectedTab && visibleTabKeys.includes(this.props.defaultSelectedTab)) {
return this.props.defaultSelectedTab;
}

// If no valid default tab is provided, find the first visible tab in the order
if (this.props.tabOrder) {
const visibleTabSet = new Set(visibleTabKeys);
return this.props.tabOrder.find(key => visibleTabSet.has(key));
} else {
return visibleTabKeys[0]; // first visible tab from default order
}
}
}
11 changes: 11 additions & 0 deletions src/controls/filePicker/FilePickerTab.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export enum FilePickerTab {
Recent = "keyRecent",
StockImages = "keyStockImages",
Web = "keyWeb",
OrgAssets = "keyOrgAssets",
OneDrive = "keyOneDrive",
Site = "keySite",
Upload = "keyUpload",
Link = "keyLink",
MultipleUpload = "keyMultipleUpload"
}
11 changes: 11 additions & 0 deletions src/controls/filePicker/IFilePickerProps.ts
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ import { IIconProps } from "@fluentui/react/lib/Icon";
import { BaseComponentContext } from '@microsoft/sp-component-base';

import { IFilePickerResult } from "./FilePicker.types";
import { FilePickerTab } from "./FilePickerTab";

export interface IFilePickerProps {
/**
@@ -175,4 +176,14 @@ export interface IFilePickerProps {
* Specifies if file check should be done
*/
checkIfFileExists?: boolean;
/**
* Specifies tab order
* Default [FilePickerTab.Recent, FilePickerTab.StockImages, FilePickerTab.Web, FilePickerTab.OrgAssets, FilePickerTab.OneDrive, FilePickerTab.Site, FilePickerTab.Upload, FilePickerTab.Link, FilePickerTab.MultipleUpload]
*/
tabOrder?: FilePickerTab[];
/**
* Specifies default selected tab
* One of the values from the FilePickerTab enum: Recent, StockImages, Web, OrgAssets, OneDrive, Site, Upload, Link, or MultipleUpload.
*/
defaultSelectedTab?: FilePickerTab;
}
1 change: 1 addition & 0 deletions src/controls/filePicker/index.ts
Original file line number Diff line number Diff line change
@@ -2,3 +2,4 @@ export * from "./FilePicker";
export * from "./FilePicker.types";
export * from "./IFilePickerProps";
export * from "./IFilePickerState";
export * from "./FilePickerTab";