Skip to content

Commit f2383f6

Browse files
Merge branch 'feature/filepicker-multiselect' of https://github.com/MonalisaBaltatescu/sp-dev-fx-controls-react into MonalisaBaltatescu-feature/filepicker-multiselect
2 parents b6535f2 + b058c63 commit f2383f6

File tree

13 files changed

+74
-107
lines changed

13 files changed

+74
-107
lines changed

src/controls/filePicker/OneDriveFilesTab/IOneDriveFilesTabState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { OneDriveFilesBreadcrumbItem } from "./OneDriveFilesTab.types";
22
import { IFilePickerResult } from "../FilePicker.types";
33

44
export interface IOneDriveFilesTabState {
5-
filePickerResult: IFilePickerResult;
5+
filePickerResults: IFilePickerResult[];
66
libraryAbsolutePath: string;
77
libraryUrl: string;
88
folderPath: string;

src/controls/filePicker/OneDriveFilesTab/OneDriveFilesTab.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export class OneDriveFilesTab extends React.Component<IOneDriveFilesTabProps, IO
1818
super(props);
1919

2020
this.state = {
21-
filePickerResult: null,
21+
filePickerResults: [],
2222
libraryAbsolutePath: undefined,
2323
libraryUrl: '/Documents',
2424
folderPath: undefined,
@@ -66,12 +66,12 @@ export class OneDriveFilesTab extends React.Component<IOneDriveFilesTabProps, IO
6666
return (
6767
<div className={styles.tabContainer}>
6868
<div className={styles.tabHeaderContainer}>
69-
<Breadcrumb items={this.state.breadcrumbItems} /*onRenderItem={this.renderBreadcrumbItem}*/ className={styles.breadcrumbNav}/>
69+
<Breadcrumb items={this.state.breadcrumbItems} /*onRenderItem={this.renderBreadcrumbItem}*/ className={styles.breadcrumbNav} />
7070
</div>
7171
<div className={styles.tabFiles}>
7272
{this.state.libraryAbsolutePath !== undefined &&
7373
<FileBrowser
74-
onChange={(filePickerResult: IFilePickerResult) => this._handleSelectionChange(filePickerResult)}
74+
onChange={(filePickerResults: IFilePickerResult[]) => this._handleSelectionChange(filePickerResults)}
7575
onOpenFolder={(folder: IFile) => this._handleOpenFolder(folder, true)}
7676
fileBrowserService={this.props.oneDriveService}
7777
libraryUrl={this.state.libraryUrl}
@@ -81,7 +81,7 @@ export class OneDriveFilesTab extends React.Component<IOneDriveFilesTabProps, IO
8181
<div className={styles.actionButtonsContainer}>
8282
<div className={styles.actionButtons}>
8383
<PrimaryButton
84-
disabled={!this.state.filePickerResult}
84+
disabled={this.state.filePickerResults && !this.state.filePickerResults.length}
8585
onClick={() => this._handleSave()} className={styles.actionButton}>{strings.OpenButtonLabel}</PrimaryButton>
8686
<DefaultButton onClick={() => this._handleClose()} className={styles.actionButton}>{strings.CancelButtonLabel}</DefaultButton>
8787
</div>
@@ -124,27 +124,26 @@ export class OneDriveFilesTab extends React.Component<IOneDriveFilesTabProps, IO
124124

125125
this.setState({
126126
breadcrumbItems,
127-
filePickerResult: undefined
127+
filePickerResults: []
128128
});
129129
}
130130

131131
/**
132132
* Is called when user selects a different file
133133
*/
134-
private _handleSelectionChange = (filePickerResult: IFilePickerResult) => {
135-
if (filePickerResult) {
134+
private _handleSelectionChange = (filePickerResults: IFilePickerResult[]) => {
135+
filePickerResults.map((filePickerResult: IFilePickerResult) => {
136136
filePickerResult.downloadFileContent = () => { return this.props.oneDriveService.downloadSPFileContent(filePickerResult.spItemUrl, filePickerResult.fileName); };
137-
}
138-
this.setState({
139-
filePickerResult
140137
});
138+
139+
this.setState({ filePickerResults });
141140
}
142141

143142
/**
144143
* Called when user saves
145144
*/
146145
private _handleSave = () => {
147-
this.props.onSave([this.state.filePickerResult]);
146+
this.props.onSave(this.state.filePickerResults);
148147
}
149148

150149
/**

src/controls/filePicker/RecentFilesTab/IRecentFilesTabState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ import { IRecentFile } from "../../../services/FilesSearchService.types";
44
export interface IRecentFilesTabState {
55
results: IRecentFile[];
66
isLoading: boolean;
7-
filePickerResult: IFilePickerResult;
7+
filePickerResults: IFilePickerResult[];
88
}

src/controls/filePicker/RecentFilesTab/RecentFilesTab.module.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@
136136
opacity: 1;
137137
}
138138
}
139-
140139
.itemTileNamePlate {
141140
position: absolute;
142141
bottom: 0;

src/controls/filePicker/RecentFilesTab/RecentFilesTab.tsx

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,13 @@ export default class RecentFilesTab extends React.Component<IRecentFilesTabProps
3939
constructor(props: IRecentFilesTabProps) {
4040
super(props);
4141

42-
this._selection = new Selection({
43-
selectionMode: SelectionMode.single,
44-
onSelectionChanged: this._onSelectionChanged
45-
});
42+
this._selection = null;
4643

4744

4845
this.state = {
4946
isLoading: true,
5047
results: [],
51-
filePickerResult: null
48+
filePickerResults: []
5249
};
5350
}
5451

@@ -57,6 +54,10 @@ export default class RecentFilesTab extends React.Component<IRecentFilesTabProps
5754
*/
5855
public async componentDidMount() {
5956
const recentFilesResult = await this.props.fileSearchService.executeRecentSearch(this.props.accepts);
57+
this._selection = new Selection({
58+
selectionMode: SelectionMode.multiple,
59+
onSelectionChanged: this._onSelectionChanged
60+
});
6061
this._selection.setItems(recentFilesResult, true);
6162

6263
this.setState({
@@ -85,7 +86,7 @@ export default class RecentFilesTab extends React.Component<IRecentFilesTabProps
8586
<div className={styles.actionButtonsContainer}>
8687
<div className={styles.actionButtons}>
8788
<PrimaryButton
88-
disabled={!this.state.filePickerResult}
89+
disabled={this.state.filePickerResults && !this.state.filePickerResults.length}
8990
onClick={() => this._handleSave()}
9091
className={styles.actionButton}
9192
>{strings.OpenButtonLabel}</PrimaryButton>
@@ -97,28 +98,20 @@ export default class RecentFilesTab extends React.Component<IRecentFilesTabProps
9798
}
9899

99100
private _onSelectionChanged = () => {
101+
let filePickerResults: IFilePickerResult[] = [];
100102
// Get the selected item
101-
const selectedItems = this._selection.getSelection();
102-
if (selectedItems && selectedItems.length > 0) {
103-
//Get the selected key
104-
const selectedKey: IRecentFile = selectedItems[0] as IRecentFile;
105-
const filePickerResult: IFilePickerResult = {
103+
this._selection.getSelection().map((selectedKey: IRecentFile) => {
104+
if(!selectedKey.isFolder && selectedKey.fileUrl)
105+
filePickerResults.push({
106106
fileAbsoluteUrl: selectedKey.fileUrl,
107107
fileName: GeneralHelper.getFileNameFromUrl(selectedKey.fileUrl),
108108
fileNameWithoutExtension: GeneralHelper.getFileNameWithoutExtension(selectedKey.fileUrl),
109109
downloadFileContent: () => { return this.props.fileSearchService.downloadSPFileContent(selectedKey.fileUrl, GeneralHelper.getFileNameFromUrl(selectedKey.fileUrl)); }
110-
};
111-
112-
// Save the selected file
113-
this.setState({
114-
filePickerResult
115110
});
116-
} else {
117-
// Remove any selected file
118-
this.setState({
119-
filePickerResult: undefined
120-
});
121-
}
111+
});
112+
113+
this.setState({ filePickerResults });
114+
122115
if (this._listElem) {
123116
// Force the list to update to show the selection check
124117
this._listElem.forceUpdate();
@@ -168,7 +161,8 @@ export default class RecentFilesTab extends React.Component<IRecentFilesTabProps
168161
return <span className={styles.recentGridList} role="grid">
169162
<FocusZone>
170163
<SelectionZone selection={this._selection}
171-
onItemInvoked={(item: IRecentFile) => this._handleItemInvoked(item)}>
164+
selectionMode={SelectionMode.multiple}
165+
onItemInvoked={(item: any) => this._handleItemInvoked(item)}>
172166
<List
173167
ref={this._linkElement}
174168
items={this.state.results}
@@ -188,8 +182,8 @@ export default class RecentFilesTab extends React.Component<IRecentFilesTabProps
188182
private _onRenderCell = (item: IRecentFile, index: number | undefined): JSX.Element => {
189183
let isSelected: boolean = false;
190184

191-
if (this._selection && index !== undefined) {
192-
isSelected = this._selection.isIndexSelected(index);
185+
if (this._selection) {
186+
isSelected = this._selection.isKeySelected(item.key);
193187
}
194188

195189
return (
@@ -242,14 +236,16 @@ export default class RecentFilesTab extends React.Component<IRecentFilesTabProps
242236
* Gets called what a file is selected.
243237
*/
244238
private _handleItemInvoked = (item: IRecentFile) => {
245-
this._selection.setKeySelected(item.key, true, true);
239+
if(!item.isFolder) {
240+
this._selection.toggleKeySelected(item.key);
241+
}
246242
}
247243

248244
/**
249245
* Gets called when it is time to save the currently selected item
250246
*/
251247
private _handleSave = () => {
252-
this.props.onSave([this.state.filePickerResult]);
248+
this.props.onSave(this.state.filePickerResults);
253249
}
254250

255251
/**

src/controls/filePicker/SiteFilePickerTab/ISiteFilePickerTabState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { IFilePickerResult , FilePickerBreadcrumbItem} from "../FilePicker.types";
22

33
export interface ISiteFilePickerTabState {
4-
filePickerResult: IFilePickerResult;
4+
filePickerResults: IFilePickerResult[];
55
libraryAbsolutePath: string;
66
libraryUrl: string;
77
libraryPath: string;

src/controls/filePicker/SiteFilePickerTab/SiteFilePickerTab.tsx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export default class SiteFilePickerTab extends React.Component<ISiteFilePickerTa
4646
breadcrumbItems[breadcrumbItems.length - 1].isCurrentItem = true;
4747

4848
this.state = {
49-
filePickerResult: null,
49+
filePickerResults: [],
5050
libraryAbsolutePath: folderAbsPath || undefined,
5151
libraryUrl: libraryServRelUrl || urlCombine(props.context.pageContext.web.serverRelativeUrl, '/Shared%20Documents'),
5252
libraryPath: folderServRelPath,
@@ -175,7 +175,7 @@ export default class SiteFilePickerTab extends React.Component<ISiteFilePickerTa
175175
onOpenLibrary={(selectedLibrary: ILibrary) => this._handleOpenLibrary(selectedLibrary, true)} />}
176176
{this.state.libraryAbsolutePath !== undefined &&
177177
<FileBrowser
178-
onChange={(filePickerResult: IFilePickerResult) => this._handleSelectionChange(filePickerResult)}
178+
onChange={(filePickerResults: IFilePickerResult[]) => this._handleSelectionChange(filePickerResults)}
179179
onOpenFolder={(folder: IFile) => this._handleOpenFolder(folder, true)}
180180
fileBrowserService={this.props.fileBrowserService}
181181
libraryUrl={this.state.libraryUrl}
@@ -185,7 +185,7 @@ export default class SiteFilePickerTab extends React.Component<ISiteFilePickerTa
185185
<div className={styles.actionButtonsContainer}>
186186
<div className={styles.actionButtons}>
187187
<PrimaryButton
188-
disabled={!this.state.filePickerResult}
188+
disabled={this.state.filePickerResults && !this.state.filePickerResults.length}
189189
onClick={() => this._handleSave()} className={styles.actionButton}>{strings.OpenButtonLabel}</PrimaryButton>
190190
<DefaultButton onClick={() => this._handleClose()} className={styles.actionButton}>{strings.CancelButtonLabel}</DefaultButton>
191191
</div>
@@ -233,28 +233,26 @@ export default class SiteFilePickerTab extends React.Component<ISiteFilePickerTa
233233

234234
this.setState({
235235
breadcrumbItems,
236-
filePickerResult: undefined
236+
filePickerResults: undefined
237237
});
238238
}
239239

240240
/**
241241
* Is called when user selects a different file
242242
*/
243-
private _handleSelectionChange = (filePickerResult: IFilePickerResult) => {
244-
if (filePickerResult) {
243+
private _handleSelectionChange = (filePickerResults: IFilePickerResult[]) => {
244+
filePickerResults.map((filePickerResult: IFilePickerResult) => {
245245
filePickerResult.downloadFileContent = () => { return this.props.fileBrowserService.downloadSPFileContent(filePickerResult.fileAbsoluteUrl, filePickerResult.fileName); };
246-
}
247-
// this.props.fileBrowserService
248-
this.setState({
249-
filePickerResult
250246
});
247+
// this.props.fileBrowserService
248+
this.setState({ filePickerResults });
251249
}
252250

253251
/**
254252
* Called when user saves
255253
*/
256254
private _handleSave = () => {
257-
this.props.onSave([this.state.filePickerResult]);
255+
this.props.onSave(this.state.filePickerResults);
258256
}
259257

260258
/**
@@ -283,7 +281,7 @@ export default class SiteFilePickerTab extends React.Component<ISiteFilePickerTa
283281
}
284282

285283
this.setState({
286-
filePickerResult: null,
284+
filePickerResults: null,
287285
libraryPath: folder.serverRelativeUrl,
288286
folderName: folder.name,
289287
libraryAbsolutePath: folder.absoluteUrl,

0 commit comments

Comments
 (0)