- {this.props.label && (
+ {!this.props.hidden && this.props.label && (
)}
- {this.props.buttonIcon || this.props.buttonIconProps ? (
+ {!this.props.hidden && (this.props.buttonIcon || this.props.buttonIconProps) ? (
) : (
+ !this.props.hidden &&
)}
@@ -208,6 +199,15 @@ export class FilePicker extends React.Component<
onChange={this._handleOnChange}
/>
)}
+ {this.state.selectedTab === "keyMultipleUpload" && (
+
+ )}
{this.state.selectedTab === "keySite" && (
{
+ private _handleSave = (filePickerResult: IFilePickerResult[]) => {
this.props.onSave(filePickerResult);
this.setState({
panelOpen: false,
});
}
- private _handleOnChange = (filePickerResult: IFilePickerResult) => {
+ private _handleOnChange = (filePickerResult: IFilePickerResult[]) => {
if (this.props.onChange) {
this.props.onChange(filePickerResult);
}
@@ -389,6 +389,14 @@ export class FilePicker extends React.Component<
icon: "System",
});
}
+ if (!this.props.hideLocalMultipleUploadTab) {
+ links.push({
+ name: strings.UploadLinkLabel + " " + strings.OneDriveRootFolderName,
+ url: addUrl ? "#Multipleupload" : undefined,
+ key: "keyMultipleUpload",
+ icon: "BulkUpload",
+ });
+ }
if (!this.props.hideLinkUploadTab) {
links.push({
name: strings.FromLinkLinkLabel,
@@ -430,5 +438,9 @@ export class FilePicker extends React.Component<
if (!props.hideLinkUploadTab) {
return "keyLink";
}
+ if (!props.hideLocalMultipleUploadTab) {
+ return "keyMultipleUpload";
+ }
+
}
}
diff --git a/src/controls/filePicker/FilePicker.types.ts b/src/controls/filePicker/FilePicker.types.ts
index 5e4066ff0..6dad4a3fd 100644
--- a/src/controls/filePicker/FilePicker.types.ts
+++ b/src/controls/filePicker/FilePicker.types.ts
@@ -10,7 +10,7 @@ export interface FilePickerBreadcrumbItem extends IBreadcrumbItem {
export interface IFilePickerTab {
context: BaseComponentContext;
accepts: string[];
- onSave: (value: IFilePickerResult) => void;
+ onSave: (value: IFilePickerResult[]) => void;
onClose: () => void;
}
diff --git a/src/controls/filePicker/IFilePickerProps.ts b/src/controls/filePicker/IFilePickerProps.ts
index 7ad94d53c..d5002eac8 100644
--- a/src/controls/filePicker/IFilePickerProps.ts
+++ b/src/controls/filePicker/IFilePickerProps.ts
@@ -18,21 +18,21 @@ export interface IFilePickerProps {
* Specifies the icon to be used to display Icon Button.
*/
buttonIcon?: string;
- /**
- * Specifies props for icon to be used to display Icon Button.
- */
+ /**
+ * Specifies props for icon to be used to display Icon Button.
+ */
buttonIconProps?: IIconProps;
/**
* Handler when the file has been selected
*/
- onSave:(filePickerResult: IFilePickerResult)=>void;
+ onSave: (filePickerResult: IFilePickerResult[]) => void;
/**
* Handler when file has been changed.
*/
- onChange?: (filePickerResult: IFilePickerResult) => void;
+ onChange?: (filePickerResult: IFilePickerResult[]) => void;
/**
* Current context.
@@ -69,6 +69,11 @@ export interface IFilePickerProps {
*/
disabled?: boolean;
+ /**
+ * Specifies if the picker button is hidden (if hidden, panel visibility can still be controlled with isPanelOpen)
+ */
+ hidden?: boolean;
+
/**
* Number of itmes to obtain when executing REST queries. Default 100.
*/
@@ -109,6 +114,11 @@ export interface IFilePickerProps {
*/
hideLocalUploadTab?: boolean;
+ /**
+ * Specifies if LocalMultipleUploadTab should be hidden.
+ */
+ hideLocalMultipleUploadTab?: boolean;
+
/**
* Specifies if LinkUploadTab should be hidden.
*/
@@ -137,6 +147,11 @@ export interface IFilePickerProps {
*/
renderCustomUploadTabContent?: (filePickerResult: IFilePickerResult) => JSX.Element | null;
+ /**
+ * Optional additional renderer for Multiple Upload tab
+ */
+ renderCustomMultipleUploadTabContent?: (filePickerResult: IFilePickerResult[]) => JSX.Element | null;
+
/**
* Specifies if Site Pages library to be visible on Sites tab
*/
diff --git a/src/controls/filePicker/LinkFilePickerTab/LinkFilePickerTab.tsx b/src/controls/filePicker/LinkFilePickerTab/LinkFilePickerTab.tsx
index f7ec74486..44c0088ba 100644
--- a/src/controls/filePicker/LinkFilePickerTab/LinkFilePickerTab.tsx
+++ b/src/controls/filePicker/LinkFilePickerTab/LinkFilePickerTab.tsx
@@ -109,7 +109,7 @@ export default class LinkFilePickerTab extends React.Component {
- this.props.onSave(this.state.filePickerResult);
+ this.props.onSave([this.state.filePickerResult]);
}
/**
diff --git a/src/controls/filePicker/MultipleUploadFilePickerTab/IMultipleUploadFilePickerTabProps.ts b/src/controls/filePicker/MultipleUploadFilePickerTab/IMultipleUploadFilePickerTabProps.ts
new file mode 100644
index 000000000..e9c7433e7
--- /dev/null
+++ b/src/controls/filePicker/MultipleUploadFilePickerTab/IMultipleUploadFilePickerTabProps.ts
@@ -0,0 +1,6 @@
+import { IFilePickerResult, IFilePickerTab } from "../FilePicker.types";
+
+export interface IMultipleUploadFilePickerTabProps extends IFilePickerTab {
+ onChange: (value: IFilePickerResult[]) => void;
+ renderCustomMultipleUploadTabContent: (filePickerResult: IFilePickerResult[]) => JSX.Element | null;
+}
diff --git a/src/controls/filePicker/MultipleUploadFilePickerTab/IMultipleUploadFilePickerTabState.ts b/src/controls/filePicker/MultipleUploadFilePickerTab/IMultipleUploadFilePickerTabState.ts
new file mode 100644
index 000000000..629e611ec
--- /dev/null
+++ b/src/controls/filePicker/MultipleUploadFilePickerTab/IMultipleUploadFilePickerTabState.ts
@@ -0,0 +1,6 @@
+import { IFilePickerResult } from "../FilePicker.types";
+
+export interface IMultipleUploadFilePickerTabState {
+ filePickerResult: IFilePickerResult[];
+ filePreview?: string;
+}
diff --git a/src/controls/filePicker/MultipleUploadFilePickerTab/MultipleUploadFilePickerTab.module.scss b/src/controls/filePicker/MultipleUploadFilePickerTab/MultipleUploadFilePickerTab.module.scss
new file mode 100644
index 000000000..06f0cd6fe
--- /dev/null
+++ b/src/controls/filePicker/MultipleUploadFilePickerTab/MultipleUploadFilePickerTab.module.scss
@@ -0,0 +1,39 @@
+@import "../FilePicker.module.scss";
+
+.localTabSinglePreview {
+ margin-bottom: 20px;
+ display: inline-block;
+ text-align: center;
+}
+
+.localTabSinglePreviewImage {
+ display: block;
+ max-width: 100%;
+ max-height: 220px;
+ image-orientation: from-image;
+}
+
+.localTabFilename {
+ color: $ms-color-neutralPrimary;
+}
+
+.localTabLabel {
+ color: $ms-color-themePrimary;
+ cursor: pointer;
+}
+
+.localTabInput {
+ width: 0.1px;
+ height: 0.1px;
+ opacity: 0;
+ overflow: hidden;
+ position: absolute;
+ z-index: -1;
+}
+
+.localTabDragDropFile {
+ // width: 100%;
+ border: 1px black dashed;
+ text-align: center;
+ padding: 75px;
+}
diff --git a/src/controls/filePicker/MultipleUploadFilePickerTab/MultipleUploadFilePickerTab.tsx b/src/controls/filePicker/MultipleUploadFilePickerTab/MultipleUploadFilePickerTab.tsx
new file mode 100644
index 000000000..543088bd8
--- /dev/null
+++ b/src/controls/filePicker/MultipleUploadFilePickerTab/MultipleUploadFilePickerTab.tsx
@@ -0,0 +1,134 @@
+import * as React from 'react';
+
+import { IMultipleUploadFilePickerTabProps } from './IMultipleUploadFilePickerTabProps';
+import { IMultipleUploadFilePickerTabState } from './IMultipleUploadFilePickerTabState';
+import { IFilePickerResult } from '../FilePicker.types';
+import { GeneralHelper } from '../../../common/utilities/GeneralHelper';
+import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/components/Button';
+import { css } from 'office-ui-fabric-react/lib/Utilities';
+import { DragDropFiles } from '../../dragDropFiles/DragDropFiles';
+
+import * as strings from 'ControlStrings';
+import styles from './MultipleUploadFilePickerTab.module.scss';
+
+
+
+export default class MultipleUploadFilePickerTab extends React.Component {
+ constructor(props: IMultipleUploadFilePickerTabProps) {
+ super(props);
+ this.state = {
+ filePickerResult: undefined
+ };
+ }
+
+ private displayFileNames = (filesResult: IFilePickerResult[]) => {
+ const result = [];
+ for (var i = 0; i < filesResult.length; i++) {
+ result.push({filesResult[i].fileName}
);
+ }
+ return result;
+ }
+
+ public render(): React.ReactElement {
+ const { filePickerResult } = this.state;
+ const acceptedFilesExtensions = this.props.accepts ? this.props.accepts.join(",") : null;
+
+ return (
+
+
+
{strings.UploadLinkLabel + " " + strings.OneDriveRootFolderName}
+
+
+
+
+ ) => this._handleFileUploadExplorer(event)}
+ />
+
+
+
+
+
+ {(filePickerResult) ? this.displayFileNames(filePickerResult) : ""}
+
+
+ {this.props.renderCustomMultipleUploadTabContent && this.props.renderCustomMultipleUploadTabContent(this.state.filePickerResult)}
+
+
+
+
this._handleSave()} className={styles.actionButton}>{strings.ListItemAttachmentslPlaceHolderButtonLabel + " " + strings.OneDriveRootFolderName}
+
this._handleClose()} className={styles.actionButton}>{strings.CancelButtonLabel}
+
+
+
+ );
+ }
+
+ /**
+ * Gets called when files are uploaded via drag and drop
+ */
+ private _handleFileUpload = (files: File[]) => {
+ if (files.length < 1) {
+ return;
+ } else {
+
+ const filePickerResultsArray: IFilePickerResult[] = [];
+ for (var i = 0; i < files.length; i++) {
+ const file: File = files[i];
+ const filePickerResult: IFilePickerResult = {
+ fileAbsoluteUrl: null,
+ fileName: file.name,
+ fileSize: file.size,
+ fileNameWithoutExtension: GeneralHelper.getFileNameWithoutExtension(file.name),
+ downloadFileContent: () => { return Promise.resolve(file); }
+ };
+ filePickerResultsArray.push(filePickerResult);
+ }
+
+ this.setState({
+ filePickerResult: filePickerResultsArray
+ });
+
+ this.props.onChange(filePickerResultsArray);
+ }
+ }
+
+ /**
+ * Gets called when files are uploaded via file explorer
+ */
+ private _handleFileUploadExplorer = (event: React.ChangeEvent) => {
+ if (!event || event.target.files.length < 1) {
+ return;
+ } else {
+ const files: File[] = [];
+ for (var i = 0; i < event.target.files.length; i++) {
+ const file: File = event.target.files.item(i);
+ files.push(file);
+ }
+ this._handleFileUpload(files);
+ }
+ }
+
+ /**
+ * Saves base64 encoded image back to property pane file picker
+ */
+ private _handleSave = () => {
+ this.props.onSave(this.state.filePickerResult);
+ }
+
+ /**
+ * Closes tab without saving
+ */
+ private _handleClose = () => {
+ this.props.onClose();
+ }
+}
diff --git a/src/controls/filePicker/MultipleUploadFilePickerTab/index.ts b/src/controls/filePicker/MultipleUploadFilePickerTab/index.ts
new file mode 100644
index 000000000..950701211
--- /dev/null
+++ b/src/controls/filePicker/MultipleUploadFilePickerTab/index.ts
@@ -0,0 +1,3 @@
+export * from './MultipleUploadFilePickerTab';
+export * from './IMultipleUploadFilePickerTabProps';
+export * from './IMultipleUploadFilePickerTabState';
diff --git a/src/controls/filePicker/OneDriveFilesTab/OneDriveFilesTab.tsx b/src/controls/filePicker/OneDriveFilesTab/OneDriveFilesTab.tsx
index dfc78023e..ebeb512fa 100644
--- a/src/controls/filePicker/OneDriveFilesTab/OneDriveFilesTab.tsx
+++ b/src/controls/filePicker/OneDriveFilesTab/OneDriveFilesTab.tsx
@@ -143,7 +143,7 @@ export class OneDriveFilesTab extends React.Component {
- this.props.onSave(this.state.filePickerResult);
+ this.props.onSave([this.state.filePickerResult]);
}
/**
diff --git a/src/controls/filePicker/RecentFilesTab/RecentFilesTab.tsx b/src/controls/filePicker/RecentFilesTab/RecentFilesTab.tsx
index 13b2f26c9..1fcc564c5 100644
--- a/src/controls/filePicker/RecentFilesTab/RecentFilesTab.tsx
+++ b/src/controls/filePicker/RecentFilesTab/RecentFilesTab.tsx
@@ -249,7 +249,7 @@ export default class RecentFilesTab extends React.Component {
- this.props.onSave(this.state.filePickerResult);
+ this.props.onSave([this.state.filePickerResult]);
}
/**
diff --git a/src/controls/filePicker/SiteFilePickerTab/SiteFilePickerTab.tsx b/src/controls/filePicker/SiteFilePickerTab/SiteFilePickerTab.tsx
index bab1b683e..220099cbe 100644
--- a/src/controls/filePicker/SiteFilePickerTab/SiteFilePickerTab.tsx
+++ b/src/controls/filePicker/SiteFilePickerTab/SiteFilePickerTab.tsx
@@ -129,7 +129,7 @@ export default class SiteFilePickerTab extends React.Component {
- this.props.onSave(this.state.filePickerResult);
+ this.props.onSave([this.state.filePickerResult]);
}
/**
diff --git a/src/controls/filePicker/StockImagesTab/StockImages.tsx b/src/controls/filePicker/StockImagesTab/StockImages.tsx
index dd816c5a1..c86362668 100644
--- a/src/controls/filePicker/StockImagesTab/StockImages.tsx
+++ b/src/controls/filePicker/StockImagesTab/StockImages.tsx
@@ -18,7 +18,7 @@ export class StockImages extends React.Component {
const { language } = this.props;
const themesColor = `&themecolors=${encodeURIComponent(this.getCurrentThemeConfiguration())}`;
- const contentPickerUrl = `https://hubblecontent.osi.office.net/contentsvc/external/m365contentpicker/index.html?p=3&app=1001&aud=prod&channel=devmain&setlang=${language}&msel=0&env=prod&premium=1${themesColor}`;
+ const contentPickerUrl = `https://hubblecontent.osi.office.net/contentsvc/m365contentpicker/index.html?p=3&app=1001&aud=prod&channel=devmain&setlang=${language}&msel=0&env=prod&premium=1${themesColor}`;
return (
@@ -61,7 +61,7 @@ export class StockImages extends React.Component
{
};
}
- this.props.onSave(filePickerResult);
+ this.props.onSave([filePickerResult]);
}
/**
diff --git a/src/controls/filePicker/UploadFilePickerTab/IUploadFilePickerTabProps.ts b/src/controls/filePicker/UploadFilePickerTab/IUploadFilePickerTabProps.ts
index c572f449a..e7aea6304 100644
--- a/src/controls/filePicker/UploadFilePickerTab/IUploadFilePickerTabProps.ts
+++ b/src/controls/filePicker/UploadFilePickerTab/IUploadFilePickerTabProps.ts
@@ -1,6 +1,6 @@
import { IFilePickerResult, IFilePickerTab } from "../FilePicker.types";
export interface IUploadFilePickerTabProps extends IFilePickerTab {
- onChange: (value: IFilePickerResult) => void;
+ onChange: (value: IFilePickerResult[]) => void;
renderCustomUploadTabContent: (filePickerResult: IFilePickerResult) => JSX.Element | null;
}
diff --git a/src/controls/filePicker/UploadFilePickerTab/UploadFilePickerTab.tsx b/src/controls/filePicker/UploadFilePickerTab/UploadFilePickerTab.tsx
index 093ee6ec1..4588c5861 100644
--- a/src/controls/filePicker/UploadFilePickerTab/UploadFilePickerTab.tsx
+++ b/src/controls/filePicker/UploadFilePickerTab/UploadFilePickerTab.tsx
@@ -104,14 +104,14 @@ export default class UploadFilePickerTab extends React.Component {
- this.props.onSave(this.state.filePickerResult);
+ this.props.onSave([this.state.filePickerResult]);
}
/**
diff --git a/src/controls/filePicker/WebSearchTab/WebSearchTab.tsx b/src/controls/filePicker/WebSearchTab/WebSearchTab.tsx
index 69135a7d5..7d7cd5b16 100644
--- a/src/controls/filePicker/WebSearchTab/WebSearchTab.tsx
+++ b/src/controls/filePicker/WebSearchTab/WebSearchTab.tsx
@@ -448,7 +448,7 @@ export default class WebSearchTab extends React.Component {
- this.props.onSave(this.state.filePickerResult);
+ this.props.onSave([this.state.filePickerResult]);
}
/**
diff --git a/src/controls/filePicker/controls/FileBrowser/FileBrowser.tsx b/src/controls/filePicker/controls/FileBrowser/FileBrowser.tsx
index c000a72ed..ee8a76e21 100644
--- a/src/controls/filePicker/controls/FileBrowser/FileBrowser.tsx
+++ b/src/controls/filePicker/controls/FileBrowser/FileBrowser.tsx
@@ -185,7 +185,7 @@ export class FileBrowser extends React.Component { this._loadNextDataRequest(); return null; }}
/>) :
( any[];
}
export interface IListViewState {
@@ -87,8 +92,6 @@ export interface IListViewState {
groups?: IGroup[];
- dragStatus?: boolean;
-
}
export interface IGrouping {
diff --git a/src/controls/listView/ListView.tsx b/src/controls/listView/ListView.tsx
index 5e606f956..025e3f5fd 100644
--- a/src/controls/listView/ListView.tsx
+++ b/src/controls/listView/ListView.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import styles from './ListView.DragDrop.module.scss';
+
import { ScrollablePane, ScrollbarVisibility } from 'office-ui-fabric-react/lib/ScrollablePane';
import { Sticky, StickyPositionType } from 'office-ui-fabric-react/lib/Sticky';
import { IRenderFunction } from 'office-ui-fabric-react/lib/Utilities';
@@ -12,7 +12,7 @@ import { FileTypeIcon, IconType } from '../fileTypeIcon/index';
import * as strings from 'ControlStrings';
import { IGroupsItems } from './IListView';
import * as telemetry from '../../common/telemetry';
-import { Icon } from 'office-ui-fabric-react/lib/Icon';
+import { DragDropFiles } from "../dragDropFiles";
import filter from 'lodash/filter';
import omit from 'lodash/omit';
@@ -58,8 +58,6 @@ export class ListView extends React.Component {
private originalItems: any[];
private originalGroups: IGroup[];
private originalColumns: IColumn[];
- private dragCounter = 0;
- private dropRef = React.createRef();
constructor(props: IListViewProps) {
super(props);
@@ -74,8 +72,7 @@ export class ListView extends React.Component {
// Initialize state
this.state = {
- filterValue: this.props.defaultFilter,
- dragStatus: false
+ filterValue: this.props.defaultFilter
};
if (this.props.selection) {
@@ -94,17 +91,6 @@ export class ListView extends React.Component {
this._processProperties(this.props);
}
- public componentWillUnmount(): void {
- const { dragDropFiles } = this.props;
- if (dragDropFiles) {
- let divDropArea = this.dropRef.current;
- divDropArea.removeEventListener('dragenter', this.handleonDragEnter);
- divDropArea.removeEventListener('dragleave', this.handleonDragLeave);
- divDropArea.removeEventListener('dragover', this.handleonDragOver);
- divDropArea.removeEventListener('drop', this.handleonDrop);
- }
- }
-
/**
* Lifecycle hook when component did update after state or property changes
* @param prevProps
@@ -287,15 +273,6 @@ export class ListView extends React.Component {
// Update the current component state with the new values
this.setState(tempState);
}
-
- // Add EventListeners for drag zone area
- if (dragDropFiles) {
- let divDropArea = this.dropRef.current;
- divDropArea.addEventListener('dragenter', this.handleonDragEnter);
- divDropArea.addEventListener('dragleave', this.handleonDragLeave);
- divDropArea.addEventListener('dragover', this.handleonDragOver);
- divDropArea.addEventListener('drop', this.handleonDrop);
- }
}
/**
@@ -483,6 +460,9 @@ export class ListView extends React.Component {
* @param descending
*/
private _sortItems(items: any[], columnName: string, descending = false): any[] {
+ if (this.props.sortItems) {
+ return this.props.sortItems(items, columnName, descending);
+ }
// Sort the items
const ascItems = sortBy(items, [columnName]);
const sortedItems = descending ? ascItems.reverse() : ascItems;
@@ -572,52 +552,6 @@ export class ListView extends React.Component {
return modifiedProps;
}
- /**
- * Stop listeners from onDragOver event.
- * @param e
- */
- private handleonDragOver = (e) => {
- e.preventDefault();
- e.stopPropagation();
- }
- /**
- * Stop listeners from onDragEnter event, enable drag and drop view.
- * @param e
- */
- private handleonDragEnter = (e) => {
- e.preventDefault();
- e.stopPropagation();
- this.dragCounter++;
- if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
- this.setState({ dragStatus: true });
- }
- }
- /**
- * Stop listeners from ondragenter event, disable drag and drop view.
- * @param e
- */
- private handleonDragLeave = (e) => {
- e.preventDefault();
- e.stopPropagation();
- this.dragCounter--;
- if (this.dragCounter === 0) {
- this.setState({ dragStatus: false });
- }
- }
- /**
- * Stop listeners from onDrop event and load files to property onDrop.
- * @param e
- */
- private handleonDrop = (e) => {
- e.preventDefault();
- e.stopPropagation();
- this.setState({ dragStatus: false });
- if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
- this.props.onDrop(e.dataTransfer.files);
- e.dataTransfer.clearData();
- this.dragCounter = 0;
- }
- }
/**
* Custom render of header
* @param props
@@ -647,7 +581,7 @@ export class ListView extends React.Component {
let groupProps: IGroupRenderProps = {};
let { showFilter, filterPlaceHolder, dragDropFiles, stickyHeader, selectionMode, compact } = this.props;
- let { filterValue, items, dragStatus, columns, groups } = this.state;
+ let { filterValue, items, columns, groups } = this.state;
// Check if selection mode is single selection,
// if that is the case, disable the selection on grouping headers
@@ -662,16 +596,15 @@ export class ListView extends React.Component {
return (
-
- {(dragStatus && dragDropFiles) &&
-
-
-
-
{strings.UploadFileHeader}
-
-
- }
+
{
+ this.props.onDrop(files);
+ } : []
+ } >
{
showFilter &&
@@ -697,7 +630,7 @@ export class ListView extends React.Component {
}
}}
/>}
-
+
);
}
diff --git a/src/controls/pagination/Pagination.tsx b/src/controls/pagination/Pagination.tsx
index 1c7a843ca..e0e93a985 100644
--- a/src/controls/pagination/Pagination.tsx
+++ b/src/controls/pagination/Pagination.tsx
@@ -3,6 +3,7 @@ import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button'
import styles from "./Pagination.module.scss";
import { isEqual } from "lodash";
import * as telemetry from '../../common/telemetry';
+import { Stack } from "office-ui-fabric-react/lib/Stack";
export interface IPaginationProps {
/**
@@ -78,6 +79,7 @@ export class Pagination extends React.Component {
return (
+
{!this.props.hideFirstPageJump &&
}
+
);
}
diff --git a/src/controls/peoplepicker/PeoplePickerComponent.tsx b/src/controls/peoplepicker/PeoplePickerComponent.tsx
index da2999197..05d75c6ff 100644
--- a/src/controls/peoplepicker/PeoplePickerComponent.tsx
+++ b/src/controls/peoplepicker/PeoplePickerComponent.tsx
@@ -189,6 +189,10 @@ export class PeoplePicker extends React.Component {
const quill = this.getEditor();
if (quill) {
const range = quill.getSelection();
- const formats = quill.getFormat(range);
+ if (range) {
+ const formats = quill.getFormat(range);
- if (!isEqual(formats, this.state.formats)) {
- console.log(`current format: ${formats.list}`);
- newState.formats = formats;
+ if (!isEqual(formats, this.state.formats)) {
+ console.log(`current format: ${formats.list}`);
+ newState.formats = formats;
+ }
}
}
diff --git a/src/controls/sitePicker/ISitePicker.ts b/src/controls/sitePicker/ISitePicker.ts
new file mode 100644
index 000000000..94d7f496f
--- /dev/null
+++ b/src/controls/sitePicker/ISitePicker.ts
@@ -0,0 +1,99 @@
+import { BaseComponentContext } from '@microsoft/sp-component-base';
+
+export interface ISite {
+ /**
+ * ID of the site
+ */
+ id?: string;
+ /**
+ * Title
+ */
+ title?: string;
+ /**
+ * Base URL
+ */
+ url?: string;
+
+ /**
+ * ID of the web
+ */
+ webId?: string;
+
+ /**
+ * ID of the hub site
+ */
+ hubSiteId?: string;
+}
+
+export interface ISitePickerProps {
+ /**
+ * Site picker label
+ */
+ label?: string;
+ /**
+ * Specify if the control needs to be disabled
+ */
+ disabled?: boolean;
+ /**
+ * Web Part context
+ */
+ context: BaseComponentContext;
+ /**
+ * Intial data to load in the 'Selected sites' area (optional)
+ */
+ initialSites?: ISite[];
+ /**
+ * Define if you want to allow multi site selection. True by default.
+ */
+ multiSelect?: boolean;
+ /**
+ * Defines what entities are available for selection: site collections, sites, hub sites.
+ */
+ mode?: 'site' | 'web' | 'hub';
+
+ /**
+ * Specifies if the options should be limited by the current site collections. Taken into consideration if selectionMode is set to 'web'
+ */
+ limitToCurrentSiteCollection?: boolean;
+
+ /**
+ * Specifies if search box is displayed for the component. Default: true
+ */
+ allowSearch?: boolean;
+
+ /**
+ * Specifices if the list is sorted by title or url. Default: title
+ */
+ orderBy?: 'title' | 'url';
+
+ /**
+ * Specifies if the list is sorted in descending order. Default: false
+ */
+ isDesc?: boolean;
+
+ /**
+ * Selection change handler
+ */
+ onChange: (selectedSites: ISite[]) => void;
+
+ /**
+ * Input placeholder text. Displayed until option is selected.
+ */
+ placeholder?: string;
+
+ /**
+ * Search input placeholder text. Displayed until search text is entered.
+ */
+ searchPlaceholder?: string;
+
+ /**
+ * The list will be filtered after users stop typing for `deferredSearchTime` milliseconds.
+ * Default value is 200.
+ */
+ deferredSearchTime?: number;
+
+ /**
+ * If provided, additional class name to provide on the dropdown element.
+ */
+ className?: string;
+}
diff --git a/src/controls/sitePicker/SitePicker.tsx b/src/controls/sitePicker/SitePicker.tsx
new file mode 100644
index 000000000..588ffc505
--- /dev/null
+++ b/src/controls/sitePicker/SitePicker.tsx
@@ -0,0 +1,271 @@
+import * as React from 'react';
+import { mergeStyleSets } from 'office-ui-fabric-react/lib/Styling';
+import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
+import { ISite, ISitePickerProps } from './ISitePicker';
+import { getAllSites, getHubSites } from '../../services/SPSitesService';
+import { IDropdownOption, Dropdown } from 'office-ui-fabric-react/lib/Dropdown';
+import { ISelectableOption, SelectableOptionMenuItemType } from 'office-ui-fabric-react/lib/utilities/selectableOption/SelectableOption.types';
+import orderBy from 'lodash/orderBy';
+import findIndex from 'lodash/findIndex';
+import { SearchBox } from 'office-ui-fabric-react/lib/SearchBox';
+import { toRelativeUrl } from '../../common/utilities/GeneralHelper';
+import { Async } from '@uifabric/utilities/lib/Async';
+import * as telemetry from '../../common/telemetry';
+
+const styles = mergeStyleSets({
+ loadingSpinnerContainer: {
+ width: '100%',
+ textAlign: 'center',
+ marginTop: '8px'
+ },
+ searchBox: {
+ margin: '4px 0'
+ },
+ siteOption: {
+ display: 'flex',
+ whiteSpace: 'nowrap',
+ alignItems: 'center'
+ },
+ siteOptionCheckbox: {
+ display: 'inline-block',
+ marginRight: '4px'
+ },
+ siteOptionContent: {
+ display: 'flex',
+ flexDirection: 'column',
+ minWidth: '0',
+ padding: '4px 0'
+ },
+ siteOptionTitle: {
+ lineHeight: '18px',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis'
+ },
+ siteOptionUrl: {
+ fontSize: '12px',
+ lineHeight: '14px',
+ fontWeight: '300',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis'
+ }
+});
+
+const async = new Async();
+
+export const SitePicker: React.FunctionComponent = (props: React.PropsWithChildren) => {
+
+ const {
+ label,
+ disabled,
+ context,
+ initialSites,
+ multiSelect,
+ mode,
+ limitToCurrentSiteCollection,
+ allowSearch,
+ orderBy: propOrderBy,
+ isDesc,
+ onChange,
+ placeholder,
+ searchPlaceholder,
+ deferredSearchTime,
+ className
+ } = props;
+
+ const [isLoading, setIsLoading] = React.useState();
+ const [selectedSites, setSelectedSites] = React.useState();
+ const [allSites, setAllSites] = React.useState();
+ const [filteredSites, setFilteredSites] = React.useState();
+ const [searchQuery, setSearchQuery] = React.useState();
+
+ const onSearchChange = React.useCallback((e, newSearchQuery: string) => {
+ if (!allSites) {
+ return;
+ }
+
+ const loweredNewSearchQuery = newSearchQuery.toLowerCase();
+ const newFilteredSites = allSites.filter(s => s.title && s.title.toLowerCase().indexOf(loweredNewSearchQuery) !== -1);
+
+ setSearchQuery(newSearchQuery);
+ setFilteredSites(newFilteredSites);
+ }, [allSites]);
+
+ const onSelectionChange = React.useCallback((e, item: IDropdownOption, index: number) => {
+ let newSelectedSites: ISite[] = [];
+
+ if (multiSelect !== false) {
+ newSelectedSites = selectedSites ? [...selectedSites] : [];
+ const existingIndex = findIndex(newSelectedSites, s => s.url === item.key);
+
+ if (existingIndex >= 0) {
+ newSelectedSites.splice(existingIndex, 1);
+ }
+ else {
+ newSelectedSites.push({
+ ...item.data!
+ });
+ }
+ }
+ else {
+ newSelectedSites = [{
+ ...item.data!
+ }];
+ }
+
+ if (onChange) {
+ onChange(newSelectedSites);
+ }
+
+ setSelectedSites(newSelectedSites);
+
+ }, [selectedSites, multiSelect, onChange]);
+
+ const getOptions = React.useCallback((): IDropdownOption[] => {
+
+ if (!allSites) {
+ return [{
+ key: 'spinner',
+ text: '',
+ itemType: SelectableOptionMenuItemType.Header
+ }];
+ }
+
+ const result: IDropdownOption[] = [];
+
+ if (allowSearch !== false) {
+ result.push({
+ key: 'search',
+ text: '',
+ itemType: SelectableOptionMenuItemType.Header
+ });
+ }
+
+ const selectedSitesIds: string[] = selectedSites ? selectedSites.map(s => s.url!) : [];
+
+ if (filteredSites) {
+ filteredSites.forEach(s => {
+ result.push({
+ key: s.url,
+ text: s.title,
+ data: s,
+ selected: selectedSitesIds.indexOf(s.url) !== -1
+ });
+ });
+ }
+
+ return result;
+ }, [allowSearch, selectedSites, filteredSites, allSites]);
+
+ const onRenderOption = (option?: ISelectableOption, defaultRender?: (props?: ISelectableOption) => JSX.Element | null): JSX.Element | null => {
+ if (!props) {
+ return null;
+ }
+
+ if (option.itemType === SelectableOptionMenuItemType.Header) {
+ if (option.key === 'search') {
+ return ;
+ }
+ else if (option.key === 'spinner') {
+ //
+ // This happens when the dropdown is opened for the first time.
+ // That's when we want to load the sites
+ //
+ setIsLoading(true);
+
+ return
+
+
;
+ }
+ }
+ // {multiSelect !== false && }
+ return
+
+ {option.text}
+ {toRelativeUrl(option.data!.url)}
+
+
;
+ };
+
+ React.useEffect(() => {
+ telemetry.track('ReactSitePicker');
+ }, []);
+
+
+ React.useEffect(() => {
+ if (!initialSites) {
+ return;
+ }
+
+ setSelectedSites(sites => {
+ if (!sites) { // we want to set the state one time only
+ return initialSites;
+ }
+
+ return sites;
+ });
+ }, [initialSites]);
+
+ React.useEffect(() => {
+ if (!context || !isLoading) {
+ return;
+ }
+
+ setSearchQuery('');
+ setFilteredSites([]);
+
+ let promise: Promise;
+ if (mode === 'hub') {
+ promise = getHubSites(context);
+ }
+ else {
+ promise = getAllSites(context, mode !== 'site', limitToCurrentSiteCollection);
+ }
+
+ promise.then(sites => {
+ const copy = orderBy(sites, [propOrderBy || 'title'], [isDesc ? 'desc' : 'asc']);
+ setAllSites(copy);
+ setIsLoading(false);
+ });
+
+ }, [context, isLoading, mode, limitToCurrentSiteCollection]);
+
+ React.useEffect(() => {
+ setAllSites(sites => {
+ if (!sites) {
+ return sites;
+ }
+
+ const copy = orderBy(sites, [propOrderBy || 'title'], [isDesc ? 'desc' : 'asc']);
+ return copy;
+ });
+ }, [propOrderBy, isDesc]);
+
+ React.useEffect(() => {
+ if (!allSites) {
+ return;
+ }
+ setFilteredSites([...allSites]);
+ }, [allSites]);
+
+ return (
+ <>
+ s.url) : undefined}
+ disabled={disabled}
+ multiSelect={multiSelect !== false}
+ onRenderOption={onRenderOption}
+ onChange={onSelectionChange}
+ notifyOnReselect={true}
+ className={className}
+ />
+ >
+ );
+};
diff --git a/src/controls/sitePicker/index.ts b/src/controls/sitePicker/index.ts
new file mode 100644
index 000000000..5f4714234
--- /dev/null
+++ b/src/controls/sitePicker/index.ts
@@ -0,0 +1,2 @@
+export * from './ISitePicker';
+export * from './SitePicker';
diff --git a/src/controls/taxonomyPicker/TaxonomyPicker.tsx b/src/controls/taxonomyPicker/TaxonomyPicker.tsx
index 890d319ac..c179271fc 100644
--- a/src/controls/taxonomyPicker/TaxonomyPicker.tsx
+++ b/src/controls/taxonomyPicker/TaxonomyPicker.tsx
@@ -454,6 +454,10 @@ export class TaxonomyPicker extends React.Component {
if (selectedChildren) {
this.selectAllChildren(item, selectedItems);
}
+ else {
+ if (item.children) {
+ selectedItems.push(...this.getSelectedItems(item.children, selectedKeys, selectedChildren));
+ }
+ }
}
else {
if (item.children) {
@@ -138,7 +143,7 @@ export class TreeView extends React.Component {
// Add the checked term
selectedItems.push(item);
- if (this.props.selectChildrenIfParentSelected) {
+ if (this.checkIfChildrenShouldBeSelected(SelectChildrenMode.Select)) {
this.selectAllChildren(item, selectedItems);
}
@@ -163,7 +168,7 @@ export class TreeView extends React.Component {
let unselectArray: string[] = [];
unselectArray.push(item.key);
- if (this.props.selectChildrenIfParentSelected) {
+ if (this.checkIfChildrenShouldBeSelected(SelectChildrenMode.Unselect)) {
this.unSelectChildren(item, unselectArray);
}
@@ -181,14 +186,30 @@ export class TreeView extends React.Component {
}
}
+ private checkIfChildrenShouldBeSelected(testMode: SelectChildrenMode) {
+ let selectChildrenMode = SelectChildrenMode.None;
+ if (this.props.selectChildrenMode) {
+ selectChildrenMode = this.props.selectChildrenMode;
+ }
+ else {
+ if (this.props.selectChildrenIfParentSelected) {
+ selectChildrenMode = SelectChildrenMode.All;
+ }
+ }
+
+ if ((selectChildrenMode & testMode) === testMode) {
+ return true;
+ }
+ return false;
+ }
+
public componentDidMount() {
const {
items,
- defaultSelectedKeys,
- selectChildrenIfParentSelected
+ defaultSelectedKeys
} = this.props;
if (defaultSelectedKeys) {
- const selectedItems = this.getSelectedItems(items, defaultSelectedKeys, selectChildrenIfParentSelected);
+ const selectedItems = this.getSelectedItems(items, defaultSelectedKeys, this.checkIfChildrenShouldBeSelected(SelectChildrenMode.Mount));
this.setState({
activeItems: selectedItems
});
@@ -198,11 +219,10 @@ export class TreeView extends React.Component {
public componentWillReceiveProps(nextProps: ITreeViewProps): void {
const {
items,
- defaultSelectedKeys,
- selectChildrenIfParentSelected,
+ defaultSelectedKeys
} = nextProps;
if (defaultSelectedKeys) {
- const selectedItems = !defaultSelectedKeys ? [] : this.getSelectedItems(items, defaultSelectedKeys, selectChildrenIfParentSelected);
+ const selectedItems = this.getSelectedItems(items, defaultSelectedKeys, this.checkIfChildrenShouldBeSelected(SelectChildrenMode.Update));
this.setState({
activeItems: selectedItems
});
diff --git a/src/hooks/index.ts b/src/hooks/index.ts
new file mode 100644
index 000000000..07047eb51
--- /dev/null
+++ b/src/hooks/index.ts
@@ -0,0 +1 @@
+export * from './useTeams';
diff --git a/src/hooks/useTeams.ts b/src/hooks/useTeams.ts
new file mode 100644
index 000000000..2538c07a4
--- /dev/null
+++ b/src/hooks/useTeams.ts
@@ -0,0 +1,89 @@
+
+import React from "react";
+import { ServiceScope } from "@microsoft/sp-core-library";
+import { MSGraphClient, MSGraphClientFactory } from "@microsoft/sp-http";
+import { PageContext } from "@microsoft/sp-page-context";
+import { ITeam } from "./../common/model/ITeam";
+import { ITeamChannel } from "./../common/model/ITeamChannel";
+import { ITeamMenber } from "../common/model/ITeamMember";
+
+export const useTeams = (serviceScope: ServiceScope) => {
+ let _pageContext = React.useRef();
+ let _msgGraphClient = React.useRef();
+
+ const init = React.useCallback(async () => {
+
+ _pageContext.current = serviceScope.consume(PageContext.serviceKey);
+ _msgGraphClient.current = await serviceScope
+ .consume(MSGraphClientFactory.serviceKey)
+ .getClient();
+
+ }, [serviceScope]);
+
+ const getMyTeams = React.useCallback(async (filter?: string): Promise<
+ ITeam[]
+ > => {
+ await init();
+ if (!_msgGraphClient.current) return;
+ const teamsResults = await _msgGraphClient.current
+ .api(`/me/joinedTeams`)
+ .filter(
+ filter ? `startswith(toupper(displayName),toupper('${filter}'))` : ""
+ )
+ .select("id,displayName")
+ .get();
+ return teamsResults.value as ITeam[];
+ }, [_msgGraphClient.current]);
+
+ const getTeamChannels = React.useCallback(
+ async (teamId: string, filter?: string): Promise => {
+ await init();
+ if (!_msgGraphClient.current) return;
+ const teamsChannelResults = await _msgGraphClient.current
+ .api(`/teams/${teamId}/channels`)
+ .filter(
+ filter ? `startswith(toupper(displayName),toupper('${filter}'))` : ""
+ )
+ .get();
+
+ return teamsChannelResults.value as ITeamChannel[];
+ },
+ [_msgGraphClient.current]
+ );
+
+ const getTeamMembers = React.useCallback(async (teamId: string): Promise<
+ ITeamMenber[]
+ > => {
+ await init();
+ if (!_msgGraphClient.current) return;
+ const usersResults = await _msgGraphClient.current
+ .api(`/teams/${teamId}/members`)
+ .get();
+
+ return usersResults.value;
+ }, [_msgGraphClient.current]);
+
+ const getTeamOwners = React.useCallback(async (teamId: string): Promise<
+ ITeamMenber[]
+ > => {
+ await init();
+ if (!_msgGraphClient.current) return;
+ const usersResults = await _msgGraphClient.current
+ .api(`/teams/${teamId}/members`)
+ .filter(
+ "microsoft.graph.aadUserConversationMember/roles/any(c:c eq 'owner')"
+ )
+ .get();
+ return usersResults?.value as ITeamMenber[];
+ }, [_msgGraphClient.current]);
+
+
+
+ return {
+ init,
+ getMyTeams,
+ getTeamChannels,
+ getTeamMembers,
+ getTeamOwners
+ };
+};
diff --git a/src/loc/bg-bg.ts b/src/loc/bg-bg.ts
index 360da32ea..08057d88a 100644
--- a/src/loc/bg-bg.ts
+++ b/src/loc/bg-bg.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Сайт за хляб",
"ListViewGroupEmptyLabel": "Празни",
"WebPartTitlePlaceholder": "Заглавие на уеб част",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Избрани",
"SelectIcon": "Избор на икона"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/ca-es.ts b/src/loc/ca-es.ts
index 4795cd218..26b4ccaab 100644
--- a/src/loc/ca-es.ts
+++ b/src/loc/ca-es.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Lloc web d'engruna",
"ListViewGroupEmptyLabel": "Buit",
"WebPartTitlePlaceholder": "Títol de l'element web",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Seleccionat",
"SelectIcon": "Seleccionar icona"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/da-dk.ts b/src/loc/da-dk.ts
index 9f70c62ed..44e39f110 100644
--- a/src/loc/da-dk.ts
+++ b/src/loc/da-dk.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Hjemmeside breadcrumb",
"ListViewGroupEmptyLabel": "Tom",
"WebPartTitlePlaceholder": "Titel på webdel",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Valgt",
"SelectIcon": "Vælg ikon"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/de-de.ts b/src/loc/de-de.ts
index 388d706d6..7a4929e5b 100644
--- a/src/loc/de-de.ts
+++ b/src/loc/de-de.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Website Brotkrume",
"ListViewGroupEmptyLabel": "Leer",
"WebPartTitlePlaceholder": "Webpart Titel",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Ausgewählt",
"SelectIcon": "Icon auswählen"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/el-gr.ts b/src/loc/el-gr.ts
index 0de673506..02c15571c 100644
--- a/src/loc/el-gr.ts
+++ b/src/loc/el-gr.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Περιήγηση σε ιστότοπους",
"ListViewGroupEmptyLabel": "Κενό",
"WebPartTitlePlaceholder": "Τίτλος τμήματος Web",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Επιλεγμένα",
"SelectIcon": "Επιλογή εικονιδίου"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/en-us.ts b/src/loc/en-us.ts
index f7f2e5027..7bef81fd7 100644
--- a/src/loc/en-us.ts
+++ b/src/loc/en-us.ts
@@ -354,6 +354,20 @@ define([], () => {
CollectionDataItemMissingFields: "Fields collection is empty!",
InvalidUrlError: "The provided URL is not valid",
CollectionDataSearch: "Search",
+MyTeamsLoadingMessage: "loading your teams",
+MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+
+MyTeamsNoTeamsMessage: "You don't have any teams",
+MyTeamsTeamChannelPublicMessage: "Public Channels",
+MyTeamsTeamChannelTypeMessage: "Private Channels",
+TeamChannelPickerFontIconFavoriteText: "Favorite",
+TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+TeamPickerButtonRemoveTitle: "remove",
+TeamPickernoResultsFoundText: "No Teams found",
+TeamPickerSugestionsHeaderText: "Suggested Teams",
+TeamsChannelPickerButtonRemoveTitle: "remove",
+TeamsChannelPickerNoresultsFoundText: "No channels found",
ViewMore: "View more"
};
diff --git a/src/loc/es-es.ts b/src/loc/es-es.ts
index 922da1ada..80a70f096 100644
--- a/src/loc/es-es.ts
+++ b/src/loc/es-es.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Ruta de navegación del sitio web",
"ListViewGroupEmptyLabel": "Vacío",
"WebPartTitlePlaceholder": "Título del elemento web",
diff --git a/src/loc/et-ee.ts b/src/loc/et-ee.ts
index cd691ad12..6049a17ed 100644
--- a/src/loc/et-ee.ts
+++ b/src/loc/et-ee.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Veebilehe laius",
"ListViewGroupEmptyLabel": "Tühi",
"WebPartTitlePlaceholder": "Veebiosa tiitel",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Valitud",
"SelectIcon": "Vali ikoon"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/eu-es.ts b/src/loc/eu-es.ts
index f59081c29..4fb4f9389 100644
--- a/src/loc/eu-es.ts
+++ b/src/loc/eu-es.ts
@@ -265,6 +265,12 @@ define([], () => {
Loading: "Loading...",
ModifiedByField: "Modified By",
ModifiedField: "Date Modified",
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
NameField: "Name",
No: "No",
ProvidedValueIsInvalid: "Provided value is invalid",
@@ -324,6 +330,14 @@ define([], () => {
WebSearchLinkLabel: "Web search",
Yes: "Yes",
SelectedLabel: "Hautatuta",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
SelectIcon: "Hautatu ikonoa"
};
});
diff --git a/src/loc/fi-fi.ts b/src/loc/fi-fi.ts
index 771a758af..bf85cb13f 100644
--- a/src/loc/fi-fi.ts
+++ b/src/loc/fi-fi.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Sivuston navigointi polku",
"ListViewGroupEmptyLabel": "Tyhjä",
"WebPartTitlePlaceholder": "WWW-osan otsikko",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Valittu",
"SelectIcon": "Valitse kuvake"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/fr-ca.ts b/src/loc/fr-ca.ts
index dbb031da0..131072470 100644
--- a/src/loc/fr-ca.ts
+++ b/src/loc/fr-ca.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Fil d'Ariane",
"ListViewGroupEmptyLabel": "Vide",
"WebPartTitlePlaceholder": "Titre du composant WebPart",
diff --git a/src/loc/fr-fr.ts b/src/loc/fr-fr.ts
index dbb031da0..131072470 100644
--- a/src/loc/fr-fr.ts
+++ b/src/loc/fr-fr.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Fil d'Ariane",
"ListViewGroupEmptyLabel": "Vide",
"WebPartTitlePlaceholder": "Titre du composant WebPart",
diff --git a/src/loc/it-it.ts b/src/loc/it-it.ts
index 693958145..83ca7744d 100644
--- a/src/loc/it-it.ts
+++ b/src/loc/it-it.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Pangrattato del sito web",
"ListViewGroupEmptyLabel": "Vuoto",
"WebPartTitlePlaceholder": "Titolo web part",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Selezionato",
"SelectIcon": "Seleziona icona"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/ja-jp.ts b/src/loc/ja-jp.ts
index f6633f413..a86b5f4b8 100644
--- a/src/loc/ja-jp.ts
+++ b/src/loc/ja-jp.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "ウェブサイトの階層リンク",
"ListViewGroupEmptyLabel": "空",
"WebPartTitlePlaceholder": "Web パーツのタイトル",
diff --git a/src/loc/lt-lt.ts b/src/loc/lt-lt.ts
index 7b30ca751..e1a824b25 100644
--- a/src/loc/lt-lt.ts
+++ b/src/loc/lt-lt.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Svetainės navigacijos grandinė",
"ListViewGroupEmptyLabel": "Nenurodyta",
"WebPartTitlePlaceholder": "Puslapio dalies antraštė",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Pasirinkta",
"SelectIcon": "Rinktis piktogramą"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/lv-lv.ts b/src/loc/lv-lv.ts
index 89e4ce514..8c585f5cf 100644
--- a/src/loc/lv-lv.ts
+++ b/src/loc/lv-lv.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Website atpakaļceļa",
"ListViewGroupEmptyLabel": "Tukša",
"WebPartTitlePlaceholder": "Web daļas nosaukums",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Atlasīts",
"SelectIcon": "Atlasīt ikonu"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/mystrings.d.ts b/src/loc/mystrings.d.ts
index 66f71964a..7357ef819 100644
--- a/src/loc/mystrings.d.ts
+++ b/src/loc/mystrings.d.ts
@@ -1,4 +1,21 @@
declare interface IControlStrings {
+ MyTeamsMessageError:string;
+ MyTeamsNoTeamsMessage:string;
+ MyTeamsLoadingMessage:string;
+ MyTeamsLoadingMessage: string;
+ MyTeamsTeamChannelPublicMessage: string;
+ MyTeamsTeamChannelTypeMessage: string;
+
+ TeamPickerButtonRemoveTitle: string;
+ TeamPickerSugestionsHeaderText: string;
+ TeamPickernoResultsFoundText: string;
+
+ TeamChannelPickerSugestionHeaderText: string;
+ TeamsChannelPickerNoresultsFoundText: string;
+ TeamChannelPickerFontIconPrivateChannelTitle: string;
+ TeamChannelPickerFontIconFavoriteText: string;
+ TeamsChannelPickerButtonRemoveTitle: string;
+
PeoplePickerGroupNotFound: string;
ListViewFilterLabel: string;
@@ -9,7 +26,6 @@ declare interface IControlStrings {
genericNoResultsFoundText: string;
peoplePickerLoadingText: string;
-
SiteBreadcrumbLabel: string;
ListViewGroupEmptyLabel: string;
WebPartTitlePlaceholder: string;
@@ -353,9 +369,11 @@ declare interface IDateTimeStrings {
L_RelativeDateTime_XDaysFutureIntervals: string;
L_RelativeDateTime_XDaysIntervals: string;
L_RelativeDateTime_Today: string;
+
+
}
-declare module 'ControlStrings' {
+declare module "ControlStrings" {
const strings: IControlStrings;
export = strings;
}
diff --git a/src/loc/nb-no.ts b/src/loc/nb-no.ts
index 61cf9859f..8244477d0 100644
--- a/src/loc/nb-no.ts
+++ b/src/loc/nb-no.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Brødsmule på nettstedet",
"ListViewGroupEmptyLabel": "Tom",
"WebPartTitlePlaceholder": "Webdel-tittel",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Valgt",
"SelectIcon": "Velg ikon"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/nl-nl.ts b/src/loc/nl-nl.ts
index cefa2e272..4b4734f20 100644
--- a/src/loc/nl-nl.ts
+++ b/src/loc/nl-nl.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Website broodkruimelpad",
"ListViewGroupEmptyLabel": "Leeg",
"WebPartTitlePlaceholder": "Webonderdeel titel",
@@ -316,4 +330,4 @@ define([], () => {
"SelectedLabel": "Geselecteerd",
"SelectIcon": "Selecteer pictogram"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/pl-pl.ts b/src/loc/pl-pl.ts
index a1876f863..4b6cfaab0 100644
--- a/src/loc/pl-pl.ts
+++ b/src/loc/pl-pl.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Strona nawigacyjnej",
"ListViewGroupEmptyLabel": "Pusty",
"WebPartTitlePlaceholder": "Tytuł składnika Web Part",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Wybrany",
"SelectIcon": "Wybierz ikonę"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/pt-pt.ts b/src/loc/pt-pt.ts
index 5e0dd80fc..651270b54 100644
--- a/src/loc/pt-pt.ts
+++ b/src/loc/pt-pt.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+MyTeamsLoadingMessage: "loading your teams",
+MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+MyTeamsNoTeamsMessage: "Neste momento não tens nenhum Team",
+MyTeamsMessageDontHaveTeams: "Neste momento não tens nenhum Team",
+MyTeamsTeamChannelPublicMessage: "Public Channels",
+MyTeamsTeamChannelTypeMessage: "Private Channels",
+TeamChannelPickerFontIconFavoriteText: "Favorite",
+TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+TeamPickerButtonRemoveTitle: "remove",
+TeamPickernoResultsFoundText: "No Teams found",
+TeamPickerSugestionsHeaderText: "Suggested Teams",
+TeamsChannelPickerButtonRemoveTitle: "remove",
+TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Site pãora",
"ListViewGroupEmptyLabel": "Vazio",
"WebPartTitlePlaceholder": "Título da parte da Web",
@@ -313,5 +327,6 @@ define([], () => {
"Yes": "Sim",
"SelectedLabel": "Selecionado",
"SelectIcon": "Selecionar ícone"
+
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/ro-ro.ts b/src/loc/ro-ro.ts
index 3d9f98189..13e7537c0 100644
--- a/src/loc/ro-ro.ts
+++ b/src/loc/ro-ro.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Site-ul breadcrumb",
"ListViewGroupEmptyLabel": "Gol",
"WebPartTitlePlaceholder": "Titlu parte Web",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Selectat",
"SelectIcon": "Selectare pictogramă"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/ru-ru.ts b/src/loc/ru-ru.ts
index cee73e140..12988c5de 100644
--- a/src/loc/ru-ru.ts
+++ b/src/loc/ru-ru.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Цепочка навигации сайта",
"ListViewGroupEmptyLabel": "Не назначено",
"WebPartTitlePlaceholder": "Заголовок веб-части",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Выбранный",
"SelectIcon": "Выбрать значок"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/sk-sk.ts b/src/loc/sk-sk.ts
index 7d81628fd..ea1fecb1d 100644
--- a/src/loc/sk-sk.ts
+++ b/src/loc/sk-sk.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Menu",
"ListViewGroupEmptyLabel": "Prázdne",
"WebPartTitlePlaceholder": "Názov webovej časti",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Zvolené",
"SelectIcon": "Vybrať ikonu"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/sr-latn-rs.ts b/src/loc/sr-latn-rs.ts
index 4e10dbdca..aba67e8f1 100644
--- a/src/loc/sr-latn-rs.ts
+++ b/src/loc/sr-latn-rs.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Putanja Veb lokacije",
"ListViewGroupEmptyLabel": "Prazna",
"WebPartTitlePlaceholder": "Naslov Web Part modula",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Izabrano",
"SelectIcon": "Izaberite ikonu"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/sv-se.ts b/src/loc/sv-se.ts
index 8d5ec9109..5e408b396 100644
--- a/src/loc/sv-se.ts
+++ b/src/loc/sv-se.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Brödsmulemeny",
"ListViewGroupEmptyLabel": "Tom",
"WebPartTitlePlaceholder": "Webbdelstitel",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Vald",
"SelectIcon": "Välj ikon"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/tr-tr.ts b/src/loc/tr-tr.ts
index e6c699064..3848adf7a 100644
--- a/src/loc/tr-tr.ts
+++ b/src/loc/tr-tr.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Web sitesi kırıntısı",
"ListViewGroupEmptyLabel": "Boş",
"WebPartTitlePlaceholder": "Web parçası başlığı",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Seçili",
"SelectIcon": "Simge seç"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/vi-vn.ts b/src/loc/vi-vn.ts
index 16433b435..b484c9918 100644
--- a/src/loc/vi-vn.ts
+++ b/src/loc/vi-vn.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "Trang web mẩu bánh mì",
"ListViewGroupEmptyLabel": "Rỗng",
"WebPartTitlePlaceholder": "Web phần tiêu đề",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "Đã chọn",
"SelectIcon": "Chọn biểu tượng"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/zh-cn.ts b/src/loc/zh-cn.ts
index 8cec60ee1..5c4b4fffe 100644
--- a/src/loc/zh-cn.ts
+++ b/src/loc/zh-cn.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "网站痕迹",
"ListViewGroupEmptyLabel": "空",
"WebPartTitlePlaceholder": "Web 部件标题",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "所选",
"SelectIcon": "选择图标"
};
-});
\ No newline at end of file
+});
diff --git a/src/loc/zh-tw.ts b/src/loc/zh-tw.ts
index 0210867de..e7cb6c868 100644
--- a/src/loc/zh-tw.ts
+++ b/src/loc/zh-tw.ts
@@ -2,6 +2,20 @@ declare var define: any;
define([], () => {
return {
+ MyTeamsLoadingMessage: "loading your teams",
+ MyTeamsMessageDontHaveTeams: "You don't have any teams",
+ MyTeamsMessageError: "Something went wrong while loading your teams, please try later or refresh browser",
+ MyTeamsNoTeamsMessage: "You don't have any teams",
+ MyTeamsTeamChannelPublicMessage: "Public Channels",
+ MyTeamsTeamChannelTypeMessage: "Private Channels",
+ TeamChannelPickerFontIconFavoriteText: "Favorite",
+ TeamChannelPickerFontIconPrivateChannelTitle: "Private Channel",
+ TeamChannelPickerSugestionHeaderText: "Suggested Team Channels",
+ TeamPickerButtonRemoveTitle: "remove",
+ TeamPickernoResultsFoundText: "No Teams found",
+ TeamPickerSugestionsHeaderText: "Suggested Teams",
+ TeamsChannelPickerButtonRemoveTitle: "remove",
+ TeamsChannelPickerNoresultsFoundText: "No channels found",
"SiteBreadcrumbLabel": "網站痕跡",
"ListViewGroupEmptyLabel": "空",
"WebPartTitlePlaceholder": "Web 組件標題",
@@ -314,4 +328,4 @@ define([], () => {
"SelectedLabel": "已選取",
"SelectIcon": "選取圖示"
};
-});
\ No newline at end of file
+});
diff --git a/src/services/SPService.ts b/src/services/SPService.ts
index 7968c784a..ed4a98673 100644
--- a/src/services/SPService.ts
+++ b/src/services/SPService.ts
@@ -246,7 +246,9 @@ export default class SPService implements ISPService {
public async addAttachment(listId: string, itemId: number, fileName: string, file: File, webUrl?: string): Promise {
try {
// Remove special characters in FileName
- fileName = fileName.replace(/[^\.\w\s\&\-]/gi, '');
+ //Updating the escape characters for filename as per the doucmentations
+ //https://support.microsoft.com/en-us/kb/905231
+ fileName = fileName.replace(/[\~\#\%\&\*\{\}\\\:\<\>\?\/\+\|]/gi, '');
// Check if attachment exists
const fileExists = await this.checkAttachmentExists(listId, itemId, fileName, webUrl);
// Delete attachment if it exists
diff --git a/src/services/SPSitesService.ts b/src/services/SPSitesService.ts
new file mode 100644
index 000000000..d88860ee5
--- /dev/null
+++ b/src/services/SPSitesService.ts
@@ -0,0 +1,93 @@
+import { BaseComponentContext } from '@microsoft/sp-component-base';
+import { ISite } from '../controls/sitePicker/ISitePicker';
+import { SPHttpClient } from '@microsoft/sp-http';
+
+const getAllSitesInternal = async (ctx: BaseComponentContext, queryText: string): Promise => {
+ let startRow = 0;
+ let rowLimit = 500;
+ let totalRows = 0;
+ const values: any[] = [];
+
+ //
+ // getting all sites
+ //
+ do {
+ let userRequestUrl: string = `${ctx.pageContext.web.absoluteUrl}/_api/search/query?querytext='${queryText}'&selectproperties='SiteId,SiteID,WebId,DepartmentId,Title,Path'&rowlimit=${rowLimit}&startrow=${startRow}`;
+ let searchResponse = await ctx.spHttpClient.get(userRequestUrl, SPHttpClient.configurations.v1);
+ let sitesResponse = await searchResponse.json();
+ let relevantResults = sitesResponse.PrimaryQueryResult.RelevantResults;
+
+ values.push(...relevantResults.Table.Rows);
+ totalRows = relevantResults.TotalRows;
+ startRow += rowLimit;
+
+ } while (values.length < totalRows);
+
+ // Do the call against the SP REST API search endpoint
+
+ let res: ISite[] = [];
+ res = values.map(element => {
+ const site: ISite = {} as ISite;
+ element.Cells.forEach(cell => {
+ switch (cell.Key) {
+ case 'Title':
+ site.title = cell.Value;
+ break;
+ case 'Path':
+ site.url = cell.Value;
+ break;
+ case 'SiteId':
+ case 'SiteID':
+ site.id = cell.Value;
+ break;
+ case 'WebId':
+ site.webId = cell.Value;
+ break;
+ case 'DepartmentId':
+ if (cell.Value) {
+ if (cell.Value.indexOf('{') === 0) {
+ site.hubSiteId = cell.Value.slice(1, -1);
+ }
+ else {
+ site.hubSiteId = cell.Value;
+ }
+ }
+ break;
+ }
+ });
+
+ return site;
+ });
+ return res;
+};
+
+export const getAllSites = async (ctx: BaseComponentContext, includeWebs: boolean, currentSiteCollectionOnly: boolean): Promise => {
+
+ let rootUrl: string = ctx.pageContext.web.absoluteUrl;
+ if (ctx.pageContext.web.serverRelativeUrl !== '/' && (!includeWebs || !currentSiteCollectionOnly)) {
+ rootUrl = ctx.pageContext.web.absoluteUrl.replace(ctx.pageContext.web.serverRelativeUrl, '');
+ }
+
+ const queryText = `contentclass:STS_Site${includeWebs ? ' contentclass:STS_Web' : ''} Path:${rootUrl}*`;
+
+ return getAllSitesInternal(ctx, queryText);
+};
+
+export const getHubSites = async (ctx: BaseComponentContext): Promise => {
+ const hubSites: ISite[] = [];
+
+ const requestUrl = `${ctx.pageContext.site.absoluteUrl}/_api/HubSites?$select=SiteId,ID,SiteUrl,Title`;
+ const response = await ctx.spHttpClient.get(requestUrl, SPHttpClient.configurations.v1);
+ const json = await response.json();
+
+ json.value.forEach(v => {
+ hubSites.push({
+ title: v.Title,
+ id: v.SiteId,
+ hubSiteId: v.ID,
+ url: v.SiteUrl
+ });
+ });
+
+ return hubSites;
+};
diff --git a/src/webparts/controlsTest/ControlsTestWebPart.manifest.json b/src/webparts/controlsTest/ControlsTestWebPart.manifest.json
index 7a1596be2..86bceaa13 100644
--- a/src/webparts/controlsTest/ControlsTestWebPart.manifest.json
+++ b/src/webparts/controlsTest/ControlsTestWebPart.manifest.json
@@ -6,6 +6,7 @@
"version": "*",
"manifestVersion": 2,
"requiresCustomScript": false,
+ "supportsThemeVariants": true,
"supportedHosts": ["SharePointWebPart"],
"preconfiguredEntries": [{
"groupId": "45165954-80f9-44c1-9967-cd38ae92a33b",
diff --git a/src/webparts/controlsTest/ControlsTestWebPart.ts b/src/webparts/controlsTest/ControlsTestWebPart.ts
index 5331d05a4..4741f51b4 100644
--- a/src/webparts/controlsTest/ControlsTestWebPart.ts
+++ b/src/webparts/controlsTest/ControlsTestWebPart.ts
@@ -13,16 +13,67 @@ import * as strings from 'ControlsTestWebPartStrings';
import ControlsTest from './components/ControlsTest';
import { IControlsTestProps } from './components/IControlsTestProps';
import { IControlsTestWebPartProps } from './IControlsTestWebPartProps';
-
+import {
+ IReadonlyTheme,
+ ThemeChangedEventArgs,
+ ThemeProvider,
+} from "@microsoft/sp-component-base";
/**
* Web part to test the React controls
*/
export default class ControlsTestWebPart extends BaseClientSideWebPart {
+ private _themeProvider: ThemeProvider;
+ private _themeVariant: IReadonlyTheme | undefined;
+ protected async onInit(): Promise {
+
+
+ this._themeProvider = this.context.serviceScope.consume(
+ ThemeProvider.serviceKey
+ );
+ // If it exists, get the theme variant
+ this._themeVariant = this._themeProvider.tryGetTheme();
+ // Register a handler to be notified if the theme variant changes
+ this._themeProvider.themeChangedEvent.add(
+ this,
+ this._handleThemeChangedEvent
+ );
+
+ if (this.context.sdks.microsoftTeams) {
+ // in teams ?
+ const context = this.context.sdks.microsoftTeams!.context;
+ this._applyTheme(context.theme || "default");
+ this.context.sdks.microsoftTeams.teamsJs.registerOnThemeChangeHandler(
+ this._applyTheme
+ );
+ }
+ return Promise.resolve();
+ }
+
+ /**
+ * Update the current theme variant reference and re-render.
+ *
+ * @param args The new theme
+ */
+ private _handleThemeChangedEvent(args: ThemeChangedEventArgs): void {
+ this._themeVariant = args.theme;
+
+ this.render();
+ }
+
+ // Apply btheme id in Teams
+ private _applyTheme = (theme: string): void => {
+ this.context.domElement.setAttribute("data-theme", theme);
+ document.body.setAttribute("data-theme", theme);
+ }
+
+
public render(): void {
const element: React.ReactElement = React.createElement(
ControlsTest,
{
+
+ themeVariant: this._themeVariant,
context: this.context,
description: this.properties.description,
title: this.properties.title,
diff --git a/src/webparts/controlsTest/components/ControlsTest.tsx b/src/webparts/controlsTest/components/ControlsTest.tsx
index 89f3e9165..3cf1c7cd5 100644
--- a/src/webparts/controlsTest/components/ControlsTest.tsx
+++ b/src/webparts/controlsTest/components/ControlsTest.tsx
@@ -1,9 +1,16 @@
import * as React from "react";
-
+import {
+ ITag,
+} from "office-ui-fabric-react/lib/Pickers";
+import {
+ Stack,
+} from "office-ui-fabric-react/lib/Stack";
import {
Text,
+} from "office-ui-fabric-react/lib/Text";
+import {
TextField
-} from "office-ui-fabric-react";
+} from "office-ui-fabric-react/lib/TextField";
import {
DefaultButton,
PrimaryButton
@@ -162,6 +169,13 @@ import {
IControlsTestProps,
IControlsTestState
} from "./IControlsTestProps";
+import { MyTeams } from "../../../controls/MyTeams";
+import { TeamPicker } from "../../../TeamPicker";
+import { TeamChannelPicker } from "../../../TeamChannelPicker";
+import { DragDropFiles } from "../../../DragDropFiles";
+import { SitePicker } from "../../../controls/sitePicker/SitePicker";
+
+
// Used to render document card
/**
@@ -244,6 +258,13 @@ export default class ControlsTest extends React.Component {
+ alert(`TeamId: ${teamsId}\n ChannelId: ${channelId}\n`);
+ console.log("TeamsId", teamsId);
+ console.log("ChannelId", channelId);
+ }
+
/**
* Static array for carousel control example.
*/
@@ -416,7 +437,10 @@ export default class ControlsTest extends React.Component {
for (var i = 0; i < files.length; i++) {
- console.log(files[i].name);
+ console.log("File name: " + files[i].name);
+ console.log("Folder Path: " + files[i].fullPath);
}
}
@@ -620,11 +645,14 @@ export default class ControlsTest extends React.Component {
- this.setState({ filePickerResult });
- if (filePickerResult) {
- const fileResultContent = await filePickerResult.downloadFileContent();
- console.log(fileResultContent);
+ private _onFilePickerSave = async (filePickerResult: IFilePickerResult[]) => {
+ this.setState({ filePickerResult: filePickerResult });
+ if (filePickerResult && filePickerResult.length > 0) {
+ for (var i = 0; i < filePickerResult.length; i++) {
+ const item = filePickerResult[i];
+ const fileResultContent = await item.downloadFileContent();
+ console.log(fileResultContent);
+ }
}
}
@@ -819,6 +847,48 @@ export default class ControlsTest extends React.ComponentSee all
} />
+
+
+
+
+ {
+ this.setState({ selectedTeamChannels: [] });
+ this.setState({ selectedTeam: tagList });
+ console.log(tagList);
+ }}
+ />
+ {this.state?.selectedTeam && this.state?.selectedTeam.length > 0 && (
+ <>
+ {
+ this.setState({ selectedTeamChannels: tagList });
+ console.log(tagList);
+ }}
+ />
+ >
+ )}
+
+
@@ -1105,7 +1175,14 @@ export default class ControlsTest extends React.Component
+ placeholder={'Select a SharePoint principal (User or Group)'}
+ onGetErrorMessage={async (items: any[]) => {
+ if (!items || items.length < 2) {
+ return 'error';
+ }
+ return '';
+ }} />
+
+
+ Drag and Drop Files
+
+ Drag files or folder with files here...}
+ buttonLabel='Configure'
+ hideButton={this.props.displayMode === DisplayMode.Read}
+ onConfigure={this._onConfigure} />
+
+
+
+
+
+ Site picker tester:
+ { console.log(sites); }}
+ placeholder={'Select sites'}
+ searchPlaceholder={'Filter sites'} />
+
+
List picker tester:
{ console.log(filePickerResult.fileName); }}
+ onChange={(filePickerResult: IFilePickerResult[]) => { console.log(filePickerResult); }}
context={this.props.context}
hideRecentTab={false}
includePageLibraries={true}
@@ -1495,10 +1604,10 @@ export default class ControlsTest extends React.Component
- FileName: {this.state.filePickerResult.fileName}
+ FileName: {this.state.filePickerResult[0].fileName}
- File size: {this.state.filePickerResult.fileSize}
+ File size: {this.state.filePickerResult[0].fileSize}
}
@@ -1512,7 +1621,7 @@ export default class ControlsTest extends React.Component { console.log(filePickerResult.fileName); }}
+ onChange={(filePickerResult: IFilePickerResult[]) => { console.log(filePickerResult); }}
context={this.props.context}
hideRecentTab={false}
renderCustomUploadTabContent={() => (
diff --git a/src/webparts/controlsTest/components/ControlsTest_SingleComponent.tsx b/src/webparts/controlsTest/components/ControlsTest_SingleComponent.tsx
index 4be61bf09..2fa0e10e8 100644
--- a/src/webparts/controlsTest/components/ControlsTest_SingleComponent.tsx
+++ b/src/webparts/controlsTest/components/ControlsTest_SingleComponent.tsx
@@ -132,7 +132,10 @@ export default class ControlsTest extends React.Component {
- this.setState({ filePickerResult });
- if (filePickerResult) {
- const fileResultContent = await filePickerResult.downloadFileContent();
- console.log(fileResultContent);
+ private _onFilePickerSave = async (filePickerResult: IFilePickerResult[]) => {
+ this.setState({ filePickerResult: filePickerResult });
+ if (filePickerResult && filePickerResult.length > 0) {
+ for (var i = 0; i < filePickerResult.length; i++) {
+ const item = filePickerResult[i];
+ const fileResultContent = await item.downloadFileContent();
+ console.log(fileResultContent);
+ }
}
}
diff --git a/src/webparts/controlsTest/components/IControlsTestProps.ts b/src/webparts/controlsTest/components/IControlsTestProps.ts
index 7d31b75fb..e4efa26f8 100644
--- a/src/webparts/controlsTest/components/IControlsTestProps.ts
+++ b/src/webparts/controlsTest/components/IControlsTestProps.ts
@@ -3,7 +3,11 @@ import { ImageSize } from '../../../FileTypeIcon';
import { DisplayMode } from '@microsoft/sp-core-library';
import { IProgressAction } from '../../../Progress';
import { IFilePickerResult } from '../../../FilePicker';
+import { ITag } from 'office-ui-fabric-react';
+import {
+ IReadonlyTheme,
+} from "@microsoft/sp-component-base";
export interface IControlsTestProps {
context: WebPartContext;
description: string;
@@ -11,6 +15,7 @@ export interface IControlsTestProps {
displayMode: DisplayMode;
updateProperty: (value: string) => void;
totalPages?: number;
+ themeVariant?: IReadonlyTheme;
}
export interface IControlsTestState {
@@ -29,10 +34,13 @@ export interface IControlsTestState {
canMovePrev: boolean;
canMoveNext: boolean;
comboBoxListItemPickerListId: string;
- filePickerResult?: IFilePickerResult;
+ filePickerResult?: IFilePickerResult[];
treeViewSelectedKeys?: string[];
showAnimatedDialog?: boolean;
showCustomisedAnimatedDialog?: boolean;
showSuccessDialog?: boolean;
showErrorDialog?: boolean;
+ selectedTeam:ITag[];
+ selectedTeamChannels:ITag[];
+
}
diff --git a/tests/controls/documentLibraryBrowser/DocumentLibraryBrowser.test.tsx b/tests/controls/documentLibraryBrowser/DocumentLibraryBrowser.test.tsx
new file mode 100644
index 000000000..32a134236
--- /dev/null
+++ b/tests/controls/documentLibraryBrowser/DocumentLibraryBrowser.test.tsx
@@ -0,0 +1,94 @@
+///
+
+import * as React from "react";
+import { mount, configure } from "enzyme";
+import * as Adapter from 'enzyme-adapter-react-16';
+import { DocumentLibraryBrowser } from "../../../src/controls/filePicker/controls/DocumentLibraryBrowser/DocumentLibraryBrowser";
+import { MockFileBrowserService } from "../../mock/services/MockFileBrowserService";
+import { assert } from "chai";
+import { ILibrary } from "../../../src/services/FileBrowserService.types";
+
+configure({ adapter: new Adapter() });
+
+describe("", ()=>{
+ test("should load initial data", async ()=>{
+ let browserService = new MockFileBrowserService();
+ browserService.getSiteMediaLibrariesResult = [{
+ title: "Test library title",
+ absoluteUrl: "https://test.sharepoint.com/sites/test-site/TestLibrary",
+ serverRelativeUrl: "/sites/test-site/TestLibrary",
+ webRelativeUrl: "/sites/test-site/TestLibrary",
+ iconPath: "/sites/test-site/Assets/icon.png"
+ }]
+ let documentLibraryBrowser = mount({
+
+ }}
+ />);
+ assert.equal(documentLibraryBrowser.getDOMNode().tagName, "SPINNER");
+
+ await documentLibraryBrowser.instance().componentDidMount();
+ documentLibraryBrowser.update();
+
+ assert.equal(documentLibraryBrowser.getDOMNode().tagName, "DIV");
+ assert.deepEqual(documentLibraryBrowser.instance().state.lists,browserService.getSiteMediaLibrariesResult);
+ });
+ test("should render library title", async ()=>{
+ let browserService = new MockFileBrowserService();
+ browserService.getSiteMediaLibrariesResult = [{
+ title: "Test library title",
+ absoluteUrl: "https://test.sharepoint.com/sites/test-site/TestLibrary",
+ serverRelativeUrl: "/sites/test-site/TestLibrary",
+ webRelativeUrl: "/sites/test-site/TestLibrary",
+ iconPath: "/sites/test-site/Assets/icon.png"
+ }]
+ let documentLibraryBrowser = mount({
+
+ }}
+ />);
+ //@ts-ignore
+ let libraryTitle = documentLibraryBrowser.instance()._onRenderLibraryTile(browserService.getSiteMediaLibrariesResult[0],0);
+ let iconControl = libraryTitle.props.children.props.children.props.children[0];
+ let buttonControl = libraryTitle.props.children.props.children.props.children[1];
+ assert.equal(iconControl.type,"Image");
+ assert.equal(buttonControl.type,"DefaultButton");
+ });
+ test("should call onOpenLibrary", async ()=>{
+ let asserted = false;
+ let browserService = new MockFileBrowserService();
+ browserService.getSiteMediaLibrariesResult = [{
+ title: "Test library title",
+ absoluteUrl: "https://test.sharepoint.com/sites/test-site/TestLibrary",
+ serverRelativeUrl: "/sites/test-site/TestLibrary",
+ webRelativeUrl: "/sites/test-site/TestLibrary",
+ iconPath: "/sites/test-site/Assets/icon.png"
+ }]
+ let documentLibraryBrowser = mount({
+ asserted = true;
+ assert.deepEqual(selectedLibrary,browserService.getSiteMediaLibrariesResult[0]);
+ }}
+ />);
+ //@ts-ignore
+ documentLibraryBrowser.instance()._handleOpenLibrary(browserService.getSiteMediaLibrariesResult[0]);
+ assert.isTrue(asserted);
+ });
+ test("should _getItemCountForPage 0", async ()=>{
+ let browserService = new MockFileBrowserService();
+ let documentLibraryBrowser = mount({
+ }}
+ />);
+ //@ts-ignore
+ documentLibraryBrowser.instance()._columnsCount = 4;
+ //@ts-ignore
+ assert.equal(documentLibraryBrowser.instance()._getItemCountForPage(0,{
+ width: 1000
+ }),12);
+ });
+});
\ No newline at end of file
diff --git a/tests/controls/filePicker/SiteFilePickerTab.test.tsx b/tests/controls/filePicker/SiteFilePickerTab.test.tsx
new file mode 100644
index 000000000..eacac8797
--- /dev/null
+++ b/tests/controls/filePicker/SiteFilePickerTab.test.tsx
@@ -0,0 +1,52 @@
+///
+import * as React from "react";
+import { mount, configure } from "enzyme";
+import * as Adapter from 'enzyme-adapter-react-16';
+import { MockFileBrowserService } from "../../mock/services/MockFileBrowserService";
+import SiteFilePickerTab from "../../../src/controls/filePicker/SiteFilePickerTab/SiteFilePickerTab";
+import { assert } from "chai";
+
+configure({ adapter: new Adapter() });
+
+jest.mock("office-ui-fabric-react/lib/Utilities",()=>({
+ IRenderFunction:{
+
+ },
+ IRectangle:{
+
+ },
+ css: ()=>{
+
+ }
+}))
+
+describe("", ()=>{
+ test("should load initial data", async ()=>{
+ let browserService = new MockFileBrowserService();
+ browserService.getSiteMediaLibrariesResult = [{
+ title: "Test library title",
+ absoluteUrl: "https://test.sharepoint.com/sites/test-site/TestLibrary",
+ serverRelativeUrl: "/sites/test-site/TestLibrary",
+ webRelativeUrl: "/sites/test-site/TestLibrary",
+ iconPath: "/sites/test-site/Assets/icon.png"
+ }];
+ let spContext = {
+ pageContext:{
+ web:{
+ title: "Test Web",
+ id: "test-web-id",
+ serverRelativeUrl: "/sites/test-web"
+ }
+ }
+ }
+ let siteFilePicker = mount({}}
+ onClose={()=>{}}
+ />)
+
+ assert.isOk(siteFilePicker);
+ });
+});
\ No newline at end of file
diff --git a/tests/mock/services/MockFileBrowserService.ts b/tests/mock/services/MockFileBrowserService.ts
new file mode 100644
index 000000000..3e386751f
--- /dev/null
+++ b/tests/mock/services/MockFileBrowserService.ts
@@ -0,0 +1,22 @@
+import { FilesQueryResult, IFile, ILibrary } from "../../../src/services/FileBrowserService.types";
+
+export class MockFileBrowserService {
+ public getListItemsResult: FilesQueryResult;
+ public getFileThumbnailUrlResultMap: Map = new Map();
+ public getSiteMediaLibrariesResult: ILibrary[] = [];
+ constructor() {
+
+ }
+ public getListItems = (listUrl: string, folderPath: string, acceptedFilesExtensions?: string[], nextPageQueryStringParams?: string): Promise => {
+ return Promise.resolve(this.getListItemsResult);
+ }
+ public getFileThumbnailUrl = (file: IFile, thumbnailWidth: number, thumbnailHeight: number): string => {
+ return this.getFileThumbnailUrlResultMap.get(file.name);
+ }
+ public getSiteMediaLibraries = (includePageLibraries: boolean = false) => {
+ return Promise.resolve(this.getSiteMediaLibrariesResult);
+ }
+ public downloadSPFileContent = (absoluteFileUrl: string, fileName: string): Promise => {
+ return Promise.resolve(new File([], "test.file"));
+ }
+}
\ No newline at end of file
diff --git a/tests/services/SPService.test.ts b/tests/services/SPService.test.ts
index c62558c83..eafc3b4ea 100644
--- a/tests/services/SPService.test.ts
+++ b/tests/services/SPService.test.ts
@@ -205,4 +205,33 @@ describe("SPService", () => {
assert.isNull(libs);
});
+ test.each([[
+ "test filter",
+ "TestFieldName",
+ undefined,
+ undefined,
+ "https://test.sharepoint.com/sites/test-site/_api/web/lists('test-list-id')/items?$select=Id,TestFieldName&$filter=startswith(TestFieldName,'test%20filter')&$orderby=undefined"
+ ]
+ ])("getListItems %j", async (filterText, columnName, field, keyColumnName, expectedApi) => {
+ let calledApi;
+ let ctx = {
+ pageContext: {
+ web: {
+ absoluteUrl: "https://test.sharepoint.com/sites/test-site"
+ }
+ },
+ spHttpClient: {
+ get: (apiUrl: string,) => {
+ calledApi = apiUrl;
+ return Promise.resolve({
+ ok: true,
+ json: () => Promise.resolve([])
+ });
+ }
+ }
+ }
+ let spService = new SPService(ctx as any);
+ let items = await spService.getListItems(filterText, "test-list-id", columnName, field, keyColumnName);
+ assert.equal(calledApi, expectedApi);
+ });
});
\ No newline at end of file
diff --git a/tests/setup.js b/tests/setup.js
index 993f04d4c..ed5edb141 100644
--- a/tests/setup.js
+++ b/tests/setup.js
@@ -1,14 +1,21 @@
jest.mock("@microsoft/sp-http", () => {
- return {
- SPHttpClient: {
- configurations: {
- v1: 1
- }
- },
- HttpClient: {
- configurations: {
- v1: 1
- }
+ return {
+ SPHttpClient: {
+ configurations: {
+ v1: 1
}
+ },
+ HttpClient: {
+ configurations: {
+ v1: 1
+ }
+ }
+ }
+});
+jest.mock("@microsoft/decorators", () => {
+ return {
+ __decorate: (control) => {
+ return control;
}
- });
\ No newline at end of file
+ }
+})
\ No newline at end of file