Skip to content

Commit 6e7a8ad

Browse files
author
Piotr Siatka
committed
Fix bugs. Add tiles layout.
1 parent ff4f1de commit 6e7a8ad

25 files changed

+2104
-150
lines changed

src/controls/filePicker/OneDriveFilesTab/OneDriveFilesTab.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,22 @@ export class OneDriveFilesTab extends React.Component<IOneDriveFilesTabProps, IO
3434
const oneDriveFolderData: IFile = {
3535
isFolder: true,
3636
modified: null,
37-
absoluteRef: libraryAbsolutePath,
38-
fileLeafRef: libraryTitle,
39-
docIcon: "",
40-
fileRef: "",
37+
absoluteUrl: libraryAbsolutePath,
38+
name: libraryTitle,
39+
fileIcon: "",
40+
serverRelativeUrl: folderPath,
41+
spItemUrl: "",
42+
supportsThumbnail: false,
43+
fileType: ""
4144
};
4245

4346
const breadcrumbItems = this.state.breadcrumbItems;
4447
// Add OneDrive folder as a first node
4548
const breadcrumbNode: OneDriveFilesBreadcrumbItem = {
4649
folderData: oneDriveFolderData,
4750
isCurrentItem: true,
48-
text: oneDriveFolderData.fileLeafRef,
49-
key: oneDriveFolderData.absoluteRef
51+
text: oneDriveFolderData.name,
52+
key: oneDriveFolderData.absoluteUrl
5053
};
5154
breadcrumbNode.onClick = () => { this.onBreadcrumpItemClick(breadcrumbNode); };
5255
breadcrumbItems.push(breadcrumbNode);
@@ -110,7 +113,7 @@ export class OneDriveFilesTab extends React.Component<IOneDriveFilesTabProps, IO
110113
else if (node.folderData != null) {
111114
this._handleOpenFolder(node.folderData, false);
112115
// select which node has been clicked
113-
breadcrumbClickedItemIndx = findIndex(breadcrumbItems, item => item.folderData && item.folderData.absoluteRef === node.key);
116+
breadcrumbClickedItemIndx = findIndex(breadcrumbItems, item => item.folderData && item.folderData.absoluteUrl === node.key);
114117
}
115118

116119
// Trim nodes array
@@ -158,17 +161,17 @@ export class OneDriveFilesTab extends React.Component<IOneDriveFilesTabProps, IO
158161
const breadcrumbNode: OneDriveFilesBreadcrumbItem = {
159162
folderData: folder,
160163
isCurrentItem: true,
161-
text: folder.fileLeafRef,
162-
key: folder.absoluteRef
164+
text: folder.name,
165+
key: folder.absoluteUrl
163166
};
164167
breadcrumbNode.onClick = () => { this.onBreadcrumpItemClick(breadcrumbNode); };
165168
breadcrumbItems.push(breadcrumbNode);
166169
}
167170

168171
this.setState({
169-
folderPath: folder.fileRef,
170-
folderName: folder.fileLeafRef,
171-
libraryAbsolutePath: folder.absoluteRef,
172+
folderPath: folder.serverRelativeUrl,
173+
folderName: folder.name,
174+
libraryAbsolutePath: folder.absoluteUrl,
172175
breadcrumbItems
173176
});
174177
}

src/controls/filePicker/SiteFilePickerTab/SiteFilePickerTab.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export default class SiteFilePickerTab extends React.Component<ISiteFilePickerTa
8888
else if (node.folderData != null) {
8989
this._handleOpenFolder(node.folderData, false);
9090
// select which node has been clicked
91-
breadcrumbClickedItemIndx = findIndex(breadcrumbItems, item => item.folderData && item.folderData.absoluteRef === node.key);
91+
breadcrumbClickedItemIndx = findIndex(breadcrumbItems, item => item.folderData && item.folderData.absoluteUrl === node.key);
9292
}
9393
// Check if it is library node
9494
else if (node.libraryData != null) {
@@ -141,17 +141,18 @@ export default class SiteFilePickerTab extends React.Component<ISiteFilePickerTa
141141
const breadcrumbNode: SiteFilePickerBreadcrumbItem = {
142142
folderData: folder,
143143
isCurrentItem: true,
144-
text: folder.fileLeafRef,
145-
key: folder.absoluteRef
144+
text: folder.name,
145+
key: folder.absoluteUrl
146146
};
147147
breadcrumbNode.onClick = () => { this.onBreadcrumpItemClick(breadcrumbNode); };
148148
breadcrumbItems.push(breadcrumbNode);
149149
}
150150

151151
this.setState({
152-
libraryPath: folder.fileRef,
153-
folderName: folder.fileLeafRef,
154-
libraryAbsolutePath: folder.absoluteRef,
152+
fileUrl: null,
153+
libraryPath: folder.serverRelativeUrl,
154+
folderName: folder.name,
155+
libraryAbsolutePath: folder.absoluteUrl,
155156
breadcrumbItems
156157
});
157158
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
@import "../TilesList/TilesList.module.scss";
2+
3+
.odItemTile2Image {
4+
display: inline-block;
5+
}
6+
7+
.odImageFrame2 {
8+
display: block;
9+
position: relative;
10+
overflow: hidden;
11+
}
12+
13+
.odImageFrame2Image {
14+
position: absolute;
15+
top: 0;
16+
left: 0;
17+
bottom: 0;
18+
right: 0;
19+
}
20+
21+
.odImageFrame {
22+
display: block;
23+
position: absolute;
24+
top: 0;
25+
left: 0;
26+
bottom: 0;
27+
right: 0;
28+
}
29+
30+
.odImageStack {
31+
display: block;
32+
position: absolute;
33+
top: 0;
34+
left: 0;
35+
bottom: 0;
36+
right: 0;
37+
overflow: hidden;
38+
}
39+
40+
.odImageStackTile {
41+
display: block;
42+
position: absolute;
43+
top: 0;
44+
left: 0;
45+
bottom: 0;
46+
right: 0;
47+
//opacity: 0;
48+
}
49+
50+
.odImageTile {
51+
display: block;
52+
position: absolute;
53+
top: 0;
54+
left: 0;
55+
right: 0;
56+
bottom: 0;
57+
overflow: hidden;
58+
}
59+
60+
.odImageTile {
61+
display: block;
62+
position: absolute;
63+
top: 0;
64+
left: 0;
65+
right: 0;
66+
bottom: 0;
67+
overflow: hidden;
68+
}
69+
70+
.odImageTileBackground {
71+
top: 0;
72+
left: 0;
73+
bottom: 0;
74+
right: 0;
75+
width: 100%;
76+
height: 100%;
77+
margin: auto;
78+
background-size: contain;
79+
background-repeat: no-repeat;
80+
background-position: center;
81+
}
82+
83+
.odImageTileImage {
84+
display: block;
85+
opacity: 1;
86+
position: absolute;
87+
box-sizing: border-box;
88+
}
89+
90+
.odImageTileImage, a .odImageTileImage {
91+
border: none;
92+
}
93+
94+
.odImageTile img {
95+
display: block;
96+
}
97+
98+
.odItemTile2SmallIcon {
99+
position: absolute;
100+
bottom: 0;
101+
left: 0;
102+
margin: 6px;
103+
}
104+
105+
.fileTypeIcon {
106+
position: relative;
107+
display: inline-block;
108+
}
109+
110+
.fileTypeIconIcon {
111+
display: inline-block;
112+
vertical-align: middle;
113+
position: relative;
114+
overflow: hidden;
115+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import * as React from 'react';
2+
import styles from './DocumentTile.module.scss';
3+
import { css, IRenderFunction, IRectangle } from 'office-ui-fabric-react/lib/Utilities';
4+
import { Image, IImageProps, ImageFit } from 'office-ui-fabric-react/lib/Image';
5+
import * as strings from 'ControlStrings';
6+
import { Check } from 'office-ui-fabric-react/lib/Check';
7+
import { ScreenWidthMinLarge } from 'office-ui-fabric-react/lib/Styling';
8+
import { IDocumentTileProps } from './IDocumentTileProps';
9+
import { IFile } from '../../../../services/FileBrowserService.types';
10+
11+
const MAX_ASPECT_RATIO = 3;
12+
13+
export class DocumentTile extends React.Component<IDocumentTileProps> {
14+
public render(): React.ReactElement<IDocumentTileProps> {
15+
const { isSelected, index, item, pageWidth, tileDimensions } = this.props;
16+
const isLarge: boolean = pageWidth >= ScreenWidthMinLarge;
17+
18+
// Find the dimensions that are biggest
19+
let thumbnailWidth: number = tileDimensions.width;
20+
let thumbnailHeight: number = tileDimensions.height;
21+
22+
23+
if (item.dimensions) {
24+
const contentAspectRatio = item.dimensions.width / item.dimensions.height;
25+
const boundsAspectRatio = tileDimensions.width / tileDimensions.height;
26+
27+
let scale: number;
28+
29+
if (contentAspectRatio > boundsAspectRatio) {
30+
scale = tileDimensions.width / item.dimensions.width;
31+
} else {
32+
scale = tileDimensions.height / item.dimensions.height;
33+
}
34+
35+
const finalScale = Math.min(MAX_ASPECT_RATIO, scale);
36+
37+
thumbnailWidth = item.dimensions.width * finalScale;
38+
thumbnailHeight = item.dimensions.height * finalScale;
39+
}
40+
41+
// Check extension and get preview
42+
const thumbnail: string = this.props.fileBroserService.getFileThumbnailUrl(this.props.item, thumbnailWidth, thumbnailHeight);
43+
const ariaLabel: string = strings.ImageAriaLabelTemplate.replace('{0}', item.fileIcon);
44+
const itemLabel: string = strings.DocumentLabelTemplate
45+
.replace('{0}', item.name)
46+
.replace('{1}', item.modified)
47+
.replace('{2}', item.modifiedBy);
48+
49+
return (
50+
<div
51+
aria-selected={isSelected}
52+
data-is-draggable={false}
53+
role="listitem"
54+
aria-labelledby={`Tile-label${index}`}
55+
aria-describedby={`Tile-activity${index}`}
56+
className={css(styles.tile, isLarge ? styles.isLarge : styles.isSmall, styles.invokable, styles.selectable, isSelected ? styles.selected : undefined)}
57+
data-is-focusable={true}
58+
data-is-sub-focuszone={true}
59+
data-disable-click-on-enter={true}
60+
data-selection-index={index}
61+
//data-selection-invoke={true}
62+
onClick={(_event)=>this.props.onItemInvoked(item)}
63+
>
64+
<div
65+
className={styles.link}
66+
role="link"
67+
//onClick={(_event) => this.props.onItemInvoked(item)}
68+
//data-selection-invoke={true}
69+
>
70+
<span
71+
id={`Tile-label${index}`}
72+
className={styles.label}>{itemLabel}</span>
73+
<span role="presentation" className={styles.aboveNameplate}>
74+
<span role="presentation" className={styles.content}>
75+
<span role="presentation" className={styles.foreground}>
76+
<span className={styles.odItemTile2Image}>
77+
<span className={styles.odImageFrame2} style={{ width: thumbnailWidth, height: thumbnailHeight }}>
78+
<span className={styles.odImageFrame2Image}>
79+
<span className={styles.odImageFrame}>
80+
<span className={styles.odImageStack}>
81+
<span className={styles.odImageStackTile}>
82+
<span className={styles.odImageTile}>
83+
<span className={styles.odImageTileBackground}>
84+
<Image
85+
src={thumbnail}
86+
width={thumbnailWidth}
87+
height={thumbnailHeight}
88+
imageFit={ImageFit.contain}
89+
/>
90+
</span>
91+
</span>
92+
</span>
93+
</span>
94+
</span>
95+
</span>
96+
</span>
97+
</span>
98+
</span>
99+
<span className={styles.odItemTile2SmallIcon} >
100+
<div className={styles.fileTypeIcon}
101+
aria-label={ariaLabel}
102+
title={ariaLabel}>
103+
<img className={styles.fileTypeIconIcon} src={strings.ODPhotoIconUrl} style={{ width: 16, height: 16 }} />
104+
</div>
105+
</span>
106+
</span>
107+
</span>
108+
<span className={styles.namePlate}>
109+
<span className={styles.name}>
110+
<span className={css(styles.signalField, styles.compact)}>
111+
<span className={styles.signalFieldValue}>{item.name}</span>
112+
</span>
113+
</span>
114+
<span className={styles.activity} id={`Tile-activity${index}`}>
115+
<span className={css(styles.signalField, styles.compact)}>
116+
<span className={styles.signalFieldValue}>{item.modified}</span>
117+
</span>
118+
</span>
119+
</span>
120+
</div>
121+
<span role="checkbox" className={styles.check} data-selection-toggle={true} aria-checked={isSelected}>
122+
<Check checked={isSelected} />
123+
</span>
124+
</div>
125+
);
126+
}
127+
128+
129+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { IDimensions } from "../../../../services/IOneDriveService";
2+
import { IFile } from "../../../../services/FileBrowserService.types";
3+
import { FileBrowserService } from "../../../../services/FileBrowserService";
4+
5+
export interface IDocumentTileProps {
6+
fileBroserService: FileBrowserService;
7+
item: IFile;
8+
index: number;
9+
isSelected: boolean;
10+
pageWidth: number;
11+
tileDimensions: IDimensions;
12+
onItemInvoked: (item: IFile) => void;
13+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './DocumentTile';
2+
export * from './IDocumentTileProps';
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
//@import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss";
2-
// TODO: Fix styles
32
@import "../../SiteFilePickerTab/SiteFilePickerTab.module.scss";
43

0 commit comments

Comments
 (0)