Skip to content

Commit 44f2589

Browse files
author
Piotr Siatka
committed
Fix bugs. Remove usage of PnP.
1 parent 35160ca commit 44f2589

File tree

7 files changed

+58
-59
lines changed

7 files changed

+58
-59
lines changed

src/common/utilities/GeneralHelper.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,12 @@ export class GeneralHelper {
242242
}
243243

244244
public static getFileNameWithoutExtension(itemUrl : string) {
245-
const tokens = itemUrl.split("/");
245+
const urlTokens = itemUrl.split("?");
246+
const url = urlTokens[0];
247+
const tokens = url.split("/");
246248
const fileNameWithExtension = tokens[tokens.length - 1];
247249
const fileNameTokens = fileNameWithExtension.split(".");
248-
const fileName = fileNameTokens[fileNameTokens.length - 1];
250+
const fileName = fileNameTokens[0];
249251

250252
return fileName;
251253
}

src/controls/filePicker/FilePicker.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ export class FilePicker extends React.Component<IFilePickerProps, IFilePickerSta
102102
{
103103
this.state.selectedTab === "keyLink" &&
104104
<LinkFilePickerTab
105+
fileSearchService={this.fileSearchService}
105106
allowExternalTenantLinks={true}
106107
{...linkTabProps}
107108
/>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { IFilePickerTab } from "../FilePicker.types";
2+
import { FilesSearchService } from "../../../services/FilesSearchService";
23

34
export interface ILinkFilePickerTabProps extends IFilePickerTab {
45
allowExternalTenantLinks: boolean;
6+
fileSearchService: FilesSearchService;
57
}

src/controls/filePicker/LinkFilePickerTab/LinkFilePickerTab.tsx

Lines changed: 30 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ import { ILinkFilePickerTabProps, ILinkFilePickerTabState } from '.';
1010
import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/components/Button';
1111
import { TextField } from 'office-ui-fabric-react/lib/TextField';
1212

13-
// PnP
14-
//TODO: Remove pnp
15-
import { FetchClient } from "@pnp/common";
16-
1713
// Localized strings
1814
import * as strings from 'ControlStrings';
1915
import { GeneralHelper } from '../../../Utilities';
@@ -50,9 +46,11 @@ export default class LinkFilePickerTab extends React.Component<ILinkFilePickerTa
5046
validateOnFocusOut={false}
5147
validateOnLoad={true}
5248
value={fileUrl}
53-
onChanged={(_event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => this._handleChange(newValue)}
49+
onChanged={(newValue: string) => this._handleChange(newValue)}
5450
/>
51+
5552
</div>
53+
5654
<div className={styles.actionButtonsContainer}>
5755
<div className={styles.actionButtons}>
5856
<PrimaryButton
@@ -68,12 +66,12 @@ export default class LinkFilePickerTab extends React.Component<ILinkFilePickerTa
6866
/**
6967
* Called as user types in a new value
7068
*/
71-
private _handleChange = (fileUrl?: string) => {
72-
const filePickerResult: IFilePickerResult = {
69+
private _handleChange = (fileUrl: string) => {
70+
const filePickerResult: IFilePickerResult = fileUrl && this._isUrl(fileUrl) ? {
7371
file: null,
7472
fileAbsoluteUrl: fileUrl,
7573
fileTitle: GeneralHelper.getFileNameWithoutExtension(fileUrl)
76-
}
74+
} : null;
7775
this.setState({
7876
filePickerResult
7977
});
@@ -83,55 +81,30 @@ export default class LinkFilePickerTab extends React.Component<ILinkFilePickerTa
8381
* Verifies the url that was typed in
8482
* @param value
8583
*/
86-
private _getErrorMessagePromise(value: string): Promise<string> {
87-
return new Promise(resolve => {
88-
89-
// DOn't give an error for blank or placeholder value, but don't make it a valid entry either
90-
if (value === undefined || value === 'https://') {
91-
this.setState({ isValid: false });
92-
resolve('');
93-
return;
94-
}
95-
96-
// Make sure that user is typing a valid URL format
97-
if (!this._isUrl(value)) {
98-
this.setState({ isValid: false });
99-
resolve('');
100-
return;
101-
}
102-
103-
// If we don't allow external links, verify that we're in the same domain
104-
if (!this.props.allowExternalTenantLinks && !this._isSameDomain(value)) {
105-
this.setState({ isValid: false });
106-
resolve(strings.NoExternalLinksValidationMessage);
107-
return;
108-
}
109-
110-
// Verify the file exists by actually getting the item
111-
try {
112-
const client = new FetchClient();
113-
client.fetch(value, { method: "HEAD" }).then((response) => {
114-
if (!response.ok) {
115-
this.setState({ isValid: false });
116-
resolve(strings.CantValidateValidationMessage);
117-
return;
118-
}
119-
// the file exists
120-
this.setState({ isValid: true });
121-
resolve('');
122-
}, () => {
123-
this.setState({ isValid: false });
124-
resolve(strings.CantValidateValidationMessage);
125-
}).catch(() => {
126-
this.setState({ isValid: false });
127-
resolve(strings.CantValidateValidationMessage);
128-
});
129-
} catch (error) {
130-
console.log("Error verifying file", error);
131-
this.setState({ isValid: false });
132-
resolve(strings.CantValidateValidationMessage);
133-
}
134-
});
84+
private _getErrorMessagePromise = async (value: string): Promise<string> => {
85+
// DOn't give an error for blank or placeholder value, but don't make it a valid entry either
86+
if (value === undefined || value === 'https://') {
87+
this.setState({ isValid: false });
88+
return '';
89+
}
90+
91+
// Make sure that user is typing a valid URL format
92+
if (!this._isUrl(value)) {
93+
this.setState({ isValid: false });
94+
return '';
95+
}
96+
97+
// If we don't allow external links, verify that we're in the same domain
98+
if (!this.props.allowExternalTenantLinks && !this._isSameDomain(value)) {
99+
this.setState({ isValid: false });
100+
return strings.NoExternalLinksValidationMessage;
101+
}
102+
103+
const fileExists = await this.props.fileSearchService.fetchFile(value);
104+
this.setState({ isValid: fileExists });
105+
106+
const strResult = fileExists ? '' : strings.ProvidedValueIsInvalid;
107+
return strResult;
135108
}
136109

137110
/**

src/loc/en-us.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ define([], () => {
266266
ModifiedField: "Date Modified",
267267
NameField: "Name",
268268
No: "No",
269+
ProvidedValueIsInvalid: "Provided value is invalid",
269270
NoExternalLinksValidationMessage: "We only support linking to files in your own organization.",
270271
NoImageValidationMessage: "This isn't a link to a file type we support. You can only link to an image.",
271272
NoRecentFiles: "No recent files",

src/loc/mystrings.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ declare interface IControlStrings {
241241
NameField: string;
242242
No: string;
243243
NoExternalLinksValidationMessage: string;
244+
ProvidedValueIsInvalid: string,
244245
NoImageValidationMessage: string;
245246
NoRecentFiles: string;
246247
NoRecentFilesDescription: string;

src/services/FilesSearchService.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,25 @@ export class FilesSearchService {
2222
this.bingAPIKey = bingAPIKey;
2323
}
2424

25+
public fetchFile = async (fileUrl: string): Promise<boolean> => {
26+
try {
27+
const fetchFileResult = await this.context.httpClient.fetch(fileUrl, SPHttpClient.configurations.v1, {
28+
headers: new Headers(),
29+
method: 'HEAD',
30+
mode: 'cors'
31+
});
32+
33+
if (!fetchFileResult || !fetchFileResult.ok) {
34+
throw new Error(`Something went wrong when executing search query. Status='${fetchFileResult.status}'`);
35+
}
36+
37+
return true;
38+
} catch (err) {
39+
console.error(`[BingFilesService.fetchFile]: Err='${err.message}'`);
40+
return false;
41+
}
42+
}
43+
2544
public executeRecentSearch = async (accepts?: string) => {
2645
try {
2746
const webId = this.context.pageContext.web.id.toString();

0 commit comments

Comments
 (0)