Skip to content

Commit e6fea5e

Browse files
author
Piotr Siatka
committed
Refactor DocumentLibraryBrowser layout.
Fix bugs.
1 parent 44f2589 commit e6fea5e

File tree

21 files changed

+292
-384
lines changed

21 files changed

+292
-384
lines changed

src/common/utilities/GeneralHelper.ts

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import * as _ from '@microsoft/sp-lodash-subset';
66

77
import * as strings from 'ControlStrings';
88

9+
export const IMG_SUPPORTED_EXTENSIONS = ".gif,.jpg,.jpeg,.bmp,.dib,.tif,.tiff,.ico,.png,.jxr,.svg";
10+
911
/**
1012
* Helper with general methods to simplify some routines
1113
*/
@@ -241,15 +243,56 @@ export class GeneralHelper {
241243
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + strings.SizeUnit[i];
242244
}
243245

246+
/**
247+
* Returns file name without extension.
248+
*/
244249
public static getFileNameWithoutExtension(itemUrl : string) {
250+
const fileNameWithExtension = GeneralHelper.getFileNameFromUrl(itemUrl);
251+
const fileNameTokens = fileNameWithExtension.split(".");
252+
const fileName = fileNameTokens[0];
253+
254+
return fileName;
255+
}
256+
257+
/**
258+
* Returns file name with the extension
259+
*/
260+
public static getFileNameFromUrl(itemUrl : string) {
245261
const urlTokens = itemUrl.split("?");
246262
const url = urlTokens[0];
247263
const tokens = url.split("/");
248264
const fileNameWithExtension = tokens[tokens.length - 1];
249-
const fileNameTokens = fileNameWithExtension.split(".");
250-
const fileName = fileNameTokens[0];
251265

252-
return fileName;
266+
return fileNameWithExtension;
267+
}
268+
269+
public static isImage(fileName: string): boolean {
270+
const acceptableExtensions: string[] = IMG_SUPPORTED_EXTENSIONS.split(",");
271+
// const IMG_SUPPORTED_EXTENSIONS = ".gif,.jpg,.jpeg,.bmp,.dib,.tif,.tiff,.ico,.png,.jxr,.svg"
272+
273+
const thisExtension: string = GeneralHelper.getFileExtension(fileName);
274+
return acceptableExtensions.indexOf(thisExtension) > -1;
275+
}
276+
277+
/**
278+
* Returns extension of the file
279+
*/
280+
public static getFileExtension(fileName): string {
281+
282+
// Split the URL on the dots
283+
const splitFileName = fileName.toLowerCase().split('.');
284+
285+
// Take the last value
286+
let extensionValue = splitFileName.pop();
287+
288+
// Check if there are query string params in place
289+
if (extensionValue.indexOf('?') !== -1) {
290+
// Split the string on the question mark and return the first part
291+
const querySplit = extensionValue.split('?');
292+
extensionValue = querySplit[0];
293+
}
294+
295+
return `.${extensionValue}`;
253296
}
254297

255298
private static _getEncodedChar(c): string {

src/controls/filePicker/FilePicker.types.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
import { WebPartContext } from "@microsoft/sp-webpart-base";
2+
import { IBreadcrumbItem } from "office-ui-fabric-react/lib/Breadcrumb";
3+
import { IFile, ILibrary } from "../../services/FileBrowserService.types";
4+
5+
export interface FilePickerBreadcrumbItem extends IBreadcrumbItem {
6+
libraryData?: ILibrary;
7+
folderData?: IFile;
8+
}
29

310
export interface IFilePickerTab {
411
context: WebPartContext;
@@ -8,7 +15,8 @@ export interface IFilePickerTab {
815
}
916

1017
export interface IFilePickerResult {
11-
fileTitle: string;
18+
fileName: string;
19+
fileNameWithoutExtension: string;
1220
fileAbsoluteUrl: string;
1321
file: File;
1422
}

src/controls/filePicker/LinkFilePickerTab/LinkFilePickerTab.module.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,14 @@
33
.linkTextField {
44
max-width: 640px;
55
}
6+
7+
.localTabSinglePreview {
8+
margin-bottom: 20px;
9+
}
10+
11+
.localTabSinglePreviewImage {
12+
display: block;
13+
max-width: 100%;
14+
max-height: 220px;
15+
image-orientation: from-image;
16+
}

src/controls/filePicker/LinkFilePickerTab/LinkFilePickerTab.tsx

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export default class LinkFilePickerTab extends React.Component<ILinkFilePickerTa
4848
value={fileUrl}
4949
onChanged={(newValue: string) => this._handleChange(newValue)}
5050
/>
51-
5251
</div>
5352

5453
<div className={styles.actionButtonsContainer}>
@@ -70,7 +69,8 @@ export default class LinkFilePickerTab extends React.Component<ILinkFilePickerTa
7069
const filePickerResult: IFilePickerResult = fileUrl && this._isUrl(fileUrl) ? {
7170
file: null,
7271
fileAbsoluteUrl: fileUrl,
73-
fileTitle: GeneralHelper.getFileNameWithoutExtension(fileUrl)
72+
fileName: GeneralHelper.getFileNameFromUrl(fileUrl),
73+
fileNameWithoutExtension: GeneralHelper.getFileNameWithoutExtension(fileUrl)
7474
} : null;
7575
this.setState({
7676
filePickerResult
@@ -134,39 +134,6 @@ export default class LinkFilePickerTab extends React.Component<ILinkFilePickerTa
134134
}
135135
}
136136

137-
/**
138-
* Verifies that file ends with an image extension.
139-
* Should really check the content type instead.
140-
*/
141-
private _isImage = (fileName: string): boolean => {
142-
const acceptableExtensions: string[] = this.props.accepts.toLowerCase().split(",");
143-
// ".gif,.jpg,.jpeg,.bmp,.dib,.tif,.tiff,.ico,.png,.jxr,.svg"
144-
145-
const thisExtension: string = this._getFileExtension(fileName);
146-
return acceptableExtensions.indexOf(thisExtension) > -1;
147-
}
148-
149-
/**
150-
* Inspired from the code in PnP controls
151-
*/
152-
private _getFileExtension = (fileName): string => {
153-
154-
// Split the URL on the dots
155-
const splitFileName = fileName.toLowerCase().split('.');
156-
157-
// Take the last value
158-
let extensionValue = splitFileName.pop();
159-
160-
// Check if there are query string params in place
161-
if (extensionValue.indexOf('?') !== -1) {
162-
// Split the string on the question mark and return the first part
163-
const querySplit = extensionValue.split('?');
164-
extensionValue = querySplit[0];
165-
}
166-
167-
return `.${extensionValue}`;
168-
}
169-
170137
private _isSameDomain = (fileUrl: string): boolean => {
171138
const siteUrl: string = this.props.context.pageContext.web.absoluteUrl;
172139
return GeneralHelper.getAbsoluteDomainUrl(siteUrl) === GeneralHelper.getAbsoluteDomainUrl(fileUrl);

src/controls/filePicker/RecentFilesTab/RecentFilesTab.tsx

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import * as strings from 'ControlStrings';
2323
// PnP
2424
import { Placeholder } from '../../../Placeholder';
2525
import { IRecentFile } from '../../../services/FilesSearchService.types';
26+
import { IFilePickerResult } from '../FilePicker.types';
27+
import { GeneralHelper } from '../../../Utilities';
2628

2729
/**
2830
* Rows per page
@@ -44,36 +46,10 @@ export default class RecentFilesTab extends React.Component<IRecentFilesTabProps
4446
constructor(props: IRecentFilesTabProps) {
4547
super(props);
4648

47-
this._selection = new Selection(
48-
{
49-
selectionMode: SelectionMode.single,
50-
onSelectionChanged: () => {
51-
// Get the selected item
52-
const selectedItems = this._selection.getSelection();
53-
if (selectedItems && selectedItems.length > 0) {
54-
//Get the selected key
55-
const selectedKey: IRecentFile = selectedItems[0] as IRecentFile;
56-
57-
// Save the selected file
58-
this.setState({
59-
filePickerResult: {
60-
file: null,
61-
fileAbsoluteUrl: selectedKey.fileUrl,
62-
fileTitle: selectedKey.name
63-
}
64-
});
65-
} else {
66-
// Remove any selected file
67-
this.setState({
68-
filePickerResult: undefined
69-
});
70-
}
71-
if (this._listElem) {
72-
// Force the list to update to show the selection check
73-
this._listElem.forceUpdate();
74-
}
75-
}
76-
});
49+
this._selection = new Selection({
50+
selectionMode: SelectionMode.single,
51+
onSelectionChanged: this._onSelectionChanged
52+
});
7753

7854

7955
this.state = {
@@ -127,6 +103,34 @@ export default class RecentFilesTab extends React.Component<IRecentFilesTabProps
127103
);
128104
}
129105

106+
private _onSelectionChanged = () => {
107+
// Get the selected item
108+
const selectedItems = this._selection.getSelection();
109+
if (selectedItems && selectedItems.length > 0) {
110+
//Get the selected key
111+
const selectedKey: IRecentFile = selectedItems[0] as IRecentFile;
112+
const filePickerResult: IFilePickerResult = {
113+
file: null,
114+
fileAbsoluteUrl: selectedKey.fileUrl,
115+
fileName: GeneralHelper.getFileNameFromUrl(selectedKey.fileUrl),
116+
fileNameWithoutExtension: GeneralHelper.getFileNameWithoutExtension(selectedKey.fileUrl)
117+
};
118+
// Save the selected file
119+
this.setState({
120+
filePickerResult
121+
});
122+
} else {
123+
// Remove any selected file
124+
this.setState({
125+
filePickerResult: undefined
126+
});
127+
}
128+
if (this._listElem) {
129+
// Force the list to update to show the selection check
130+
this._listElem.forceUpdate();
131+
}
132+
}
133+
130134
/**
131135
* Calculates how many items there should be in the page
132136
*/
@@ -211,13 +215,13 @@ export default class RecentFilesTab extends React.Component<IRecentFilesTabProps
211215
width: this._columnWidth,
212216
height: this._rowHeight
213217
}}
214-
>
218+
>
215219
<div className={styles.itemTileContent}>
216220
<div className={styles.itemTileFile}>
217221
<div className={styles.itemTileFileContainer}>
218222
<div className={styles.itemTileThumbnail}>
219223
{/* <div className={styles.image}> */}
220-
<Image src={item.fileUrl} width={this._columnWidth} height={this._rowHeight} imageFit={ImageFit.cover} />
224+
<Image src={item.fileUrl} width={this._columnWidth} height={this._rowHeight} imageFit={ImageFit.cover} />
221225
{/* </div> */}
222226
</div>
223227
<div className={styles.itemTileCheckCircle}
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import { IBreadcrumbItem } from "office-ui-fabric-react/lib/Breadcrumb";
2-
import { SiteFilePickerBreadcrumbItem } from ".";
3-
import { IFilePickerResult } from "../FilePicker.types";
1+
import { IFilePickerResult , FilePickerBreadcrumbItem} from "../FilePicker.types";
42

53
export interface ISiteFilePickerTabState {
64
filePickerResult: IFilePickerResult;
@@ -9,5 +7,5 @@ export interface ISiteFilePickerTabState {
97
libraryPath: string;
108
folderName: string;
119

12-
breadcrumbItems: SiteFilePickerBreadcrumbItem[];
10+
breadcrumbItems: FilePickerBreadcrumbItem[];
1311
}

src/controls/filePicker/SiteFilePickerTab/SiteFilePickerTab.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { findIndex } from '@microsoft/sp-lodash-subset';
55
import styles from './SiteFilePickerTab.module.scss';
66

77
// Custom picker interface
8-
import { ISiteFilePickerTabProps, ISiteFilePickerTabState, SiteFilePickerBreadcrumbItem } from '.';
8+
import { ISiteFilePickerTabProps, ISiteFilePickerTabState } from '.';
99
import { DocumentLibraryBrowser, FileBrowser } from '../controls';
1010

1111
// Office Fabric
@@ -16,14 +16,14 @@ import { Breadcrumb, IBreadcrumbItem } from 'office-ui-fabric-react/lib/Breadcru
1616
import * as strings from 'ControlStrings';
1717
import { IFile, ILibrary } from '../../../services/FileBrowserService.types';
1818
import { Link } from 'office-ui-fabric-react/lib/Link';
19-
import { IFilePickerResult } from '../FilePicker.types';
19+
import { IFilePickerResult, FilePickerBreadcrumbItem } from '../FilePicker.types';
2020

2121
export default class SiteFilePickerTab extends React.Component<ISiteFilePickerTabProps, ISiteFilePickerTabState> {
2222
constructor(props: ISiteFilePickerTabProps) {
2323
super(props);
2424

2525
// Add current site to the breadcrumb or the provided node
26-
const breadcrumbSiteNode: SiteFilePickerBreadcrumbItem = this.props.breadcrumbFirstNode ? this.props. breadcrumbFirstNode : {
26+
const breadcrumbSiteNode: FilePickerBreadcrumbItem = this.props.breadcrumbFirstNode ? this.props. breadcrumbFirstNode : {
2727
isCurrentItem: true,
2828
text: props.context.pageContext.web.title,
2929
key: props.context.pageContext.web.id.toString()
@@ -81,7 +81,7 @@ export default class SiteFilePickerTab extends React.Component<ISiteFilePickerTa
8181
/**
8282
* Handles breadcrump item click
8383
*/
84-
private onBreadcrumpItemClick = (node: SiteFilePickerBreadcrumbItem) => {
84+
private onBreadcrumpItemClick = (node: FilePickerBreadcrumbItem) => {
8585
let { breadcrumbItems } = this.state;
8686
let breadcrumbClickedItemIndx = 0;
8787
// Site node clicked
@@ -146,7 +146,7 @@ export default class SiteFilePickerTab extends React.Component<ISiteFilePickerTa
146146

147147
if (addBreadcrumbNode) {
148148
breadcrumbItems.map(item => item.isCurrentItem = false);
149-
const breadcrumbNode: SiteFilePickerBreadcrumbItem = {
149+
const breadcrumbNode: FilePickerBreadcrumbItem = {
150150
folderData: folder,
151151
isCurrentItem: true,
152152
text: folder.name,
@@ -172,7 +172,7 @@ export default class SiteFilePickerTab extends React.Component<ISiteFilePickerTa
172172
const { breadcrumbItems } = this.state;
173173
if (addBreadcrumbNode) {
174174
breadcrumbItems.map(item => item.isCurrentItem = false);
175-
const breadcrumbNode: SiteFilePickerBreadcrumbItem = {
175+
const breadcrumbNode: FilePickerBreadcrumbItem = {
176176
libraryData: library,
177177
isCurrentItem: true,
178178
text: library.title,

src/controls/filePicker/SiteFilePickerTab/SiteFilePickerTab.types.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
export * from './SiteFilePickerTab';
22
export * from './ISiteFilePickerTabProps';
33
export * from './ISiteFilePickerTabState';
4-
5-
export * from './SiteFilePickerTab.types';

src/controls/filePicker/UploadFilePickerTab/IUploadFilePickerTabState.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ import { IFilePickerResult } from "../FilePicker.types";
22

33
export interface IUploadFilePickerTabState {
44
filePickerResult: IFilePickerResult;
5+
filePreview?: string;
56
}

0 commit comments

Comments
 (0)