diff --git a/CHANGELOG.json b/CHANGELOG.json index 2aa0924aa..b891da1f5 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -1,5 +1,21 @@ { "versions": [ + { + "version": "3.24.0", + "changes": { + "new": [], + "enhancements": [], + "fixes":[ + "`PeoplePicker`: Improving documentation page about external users search [#323](https://github.com/pnp/sp-dev-fx-controls-react/issues/323)", + "`FolderExplorer`: Updated Folder explorer control documentation to correct a typo. [#2072](https://github.com/pnp/sp-dev-fx-controls-react/pull/2072)" + ] + }, + "contributions": [ + "[Antanina Druzhkina](https://github.com/Ateina)", + "[Michaël Maillot](https://github.com/michaelmaillot)", + "[Nishkalank Bezawada](https://github.com/NishkalankBezawada)" + ] + }, { "version": "3.23.0", "changes": { @@ -44,7 +60,7 @@ "`ListItemComments`: Implement like and unlike ability to list item comments control [#1974](https://github.com/pnp/sp-dev-fx-controls-react/pull/1974)", "`ListItemComments`: Need a feature to view the list of users who liked a comment [#2003](https://github.com/pnp/sp-dev-fx-controls-react/issues/2003)", "`ListItemComments`: Clickable links [#1969](https://github.com/pnp/sp-dev-fx-controls-react/issues/1969)", - "`Polish translations`: Updates Polish translations. Closes #1991](https://github.com/pnp/sp-dev-fx-controls-react/issues/1991)", + "`Polish translations`: Updates Polish translations. Closes [#1991](https://github.com/pnp/sp-dev-fx-controls-react/issues/1991)", "`Dashboard`: Dashboard widget rowspan [#2007](https://github.com/pnp/sp-dev-fx-controls-react/pull/2007)", "`ListItemComments`: Guest user @-mentions and styling fix for ListItemComments [#1990](https://github.com/pnp/sp-dev-fx-controls-react/pull/1990)", "`GridLayout`: 1852 - Grid layout settings as parameters [#1976](https://github.com/pnp/sp-dev-fx-controls-react/pull/1976)" @@ -55,7 +71,7 @@ "`FilePicker`: Unable to browse through organization assets library when located on root site [#1784](https://github.com/pnp/sp-dev-fx-controls-react/issues/1784)", "`Calendar`: Fix - fix-typo-enableOnHover [#2021](https://github.com/pnp/sp-dev-fx-controls-react/pull/2021)", "`Dynamic Form`: Hotfix for issue 2014 [#2026](https://github.com/pnp/sp-dev-fx-controls-react/issues/2014)", - "`ListItemAttachments`: Update ListItemAttachments.tsx: let user set webUrl fix for issue 1975 [#2009](https://github.com/pnp/sp-dev-fx-controls-react/issues/1975", + "`ListItemAttachments`: Update ListItemAttachments.tsx: let user set webUrl fix for issue 1975 [#2009](https://github.com/pnp/sp-dev-fx-controls-react/issues/1975)", "`FilePicker`: Files keep loading when previewing all files in OneDrive [#2021](https://github.com/pnp/sp-dev-fx-controls-react/issues/1994)", "`ListItemAttachments`: ListItemAttachments cancel event is hanging the control [#1982](https://github.com/pnp/sp-dev-fx-controls-react/issues/1966)", "`filePicker`: FilePicker order of tabs and default tab[#1980](https://github.com/pnp/sp-dev-fx-controls-react/issues/921) ", @@ -150,7 +166,7 @@ "`ListItemPicker`: PR fixes an issue with filtering when using calculated column as columnInternalName in ListItemPicker. [#1887](https://github.com/pnp/sp-dev-fx-controls-react/pull/1887)", "`ListItemAttachments`: Fix 1858 to correct Chinese localization files #1894 [#1894](https://github.com/pnp/sp-dev-fx-controls-react/pull/1894)", "`DynamicForm`: Fixing issue 1862 - Dynamic form should hide fields that are hidden on the List Content Type [#1872](https://github.com/pnp/sp-dev-fx-controls-react/pull/1872)", - "`GridLayout`: A quick fix for #838. When compact mode the number of items rendered per page must match the number of all items. [1851](https://github.com/pnp/sp-dev-fx-controls-react/pull/1851)", + "`GridLayout`: A quick fix for #838. When compact mode the number of items rendered per page must match the number of all items. [#1851](https://github.com/pnp/sp-dev-fx-controls-react/pull/1851)", "`DynamicForm`: Always Show Required Field Validation Error In FormDisplayMode.Edit Mode [#1775](https://github.com/pnp/sp-dev-fx-controls-react/issues/1775)", "`DynamicForm`: Required Field Validation won't work [#1760](https://github.com/pnp/sp-dev-fx-controls-react/issues/1760)", "`DynamicForm`: Adds ability to render file/folder name field in DynamicForm and Field. [#1906](https://github.com/pnp/sp-dev-fx-controls-react/pull/1906)" @@ -319,7 +335,7 @@ "`TaxonomyPicker`: suggested item contains double termset name [#1597](https://github.com/pnp/sp-dev-fx-controls-react/issues/1597)", "`DynamicForm`: DynamicForm does not properly handle NULL default values for Taxonomy fields [#1267](https://github.com/pnp/sp-dev-fx-controls-react/issues/1267)", "`DynamicForm`: New items are always created with the default content type if the list has multiple content types [#1626](https://github.com/pnp/sp-dev-fx-controls-react/pull/1626)", - "`PeoplePicker`:PeoplePicker won't accept Multiple Users with the same name [#1620] (https://github.com/pnp/sp-dev-fx-controls-react/pull/1620)", + "`PeoplePicker`: PeoplePicker won't accept Multiple Users with the same name [#1620](https://github.com/pnp/sp-dev-fx-controls-react/pull/1620)", "`DynamicForm`: Dynamic Form accessed TaxonomyFieldTypeMulti without considering sub-array results [#1614](https://github.com/pnp/sp-dev-fx-controls-react/pull/1614)", "`DynamicForm`: Number validations are working, but the percentage values are not getting saved [#1601](https://github.com/pnp/sp-dev-fx-controls-react/pull/1601)", "`DynamicForm`: Number validation is preventing form save in certain circumstances, not enabled for currency fields [#1604](https://github.com/pnp/sp-dev-fx-controls-react/issues/1604)", @@ -411,7 +427,7 @@ "`DynamicForm`: DynamicForm - Fixing Required Multi Field Saving Problem [#1489](https://github.com/pnp/sp-dev-fx-controls-react/issues/1489)", "`FolderExplorer`: FolderExplorer doesn't explore folders with ' in the name [#1491](https://github.com/pnp/sp-dev-fx-controls-react/issues/1491)", "`DynamicForm`: cannot display lookup value when the source field is not Title [#1511](https://github.com/pnp/sp-dev-fx-controls-react/issues/1511)", - "`FilePicker`:Features/1478 filepicker tiles view [#1521](https://github.com/pnp/sp-dev-fx-controls-react/issues/1521)" + "`FilePicker`: Features/1478 filepicker tiles view [#1521](https://github.com/pnp/sp-dev-fx-controls-react/issues/1521)" ] }, "contributions": [ @@ -1300,7 +1316,7 @@ "`TaxonomyPicker`: browse (tree view) doesn't work with SP 2016 On-Premises [#183](https://github.com/pnp/sp-dev-fx-controls-react/issues/183)", "`FilePicker`: default tab when opened shows hidden RecentTab [#477](https://github.com/pnp/sp-dev-fx-controls-react/issues/477)", "`PeoplePicker`: The required error message not showing [#590](https://github.com/pnp/sp-dev-fx-controls-react/issues/590)", - "`ListItemAttachments`: fails in Microsoft Teams Tab SPFx applications [#582](fails in Microsoft Teams Tab SPFx applications)", + "`ListItemAttachments`: fails in Microsoft Teams Tab SPFx applications [#582](https://github.com/pnp/sp-dev-fx-controls-react/issues/582)", "`Carousel`: Changing pages doesn't work [#609](https://github.com/pnp/sp-dev-fx-controls-react/issues/609)", "`TaxonomyPicker`: no suggestions are displayed if `anchorId` is not set", "`TaxonomyPicker`: Suggestion/match does not work as expected [#604](https://github.com/pnp/sp-dev-fx-controls-react/issues/604)", diff --git a/CHANGELOG.md b/CHANGELOG.md index 136a3e4d4..824671064 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,28 @@ # Releases + + +## 3.24.0 + +### Fixes + +- `PeoplePicker`: Improving documentation page about external users search [#323](https://github.com/pnp/sp-dev-fx-controls-react/issues/323) +- `FolderExplorer`: Updated Folder explorer control documentation to correct a typo. [#2072](https://github.com/pnp/sp-dev-fx-controls-react/pull/2072) +- `ListItemComments`: Multiline comment doesn't display correctly in ListItemComments control due to missing line break [2078](https://github.com/pnp/sp-dev-fx-controls-react/issues/2078) +- `ImagePicker`: Imagepicker strings fix [2077](https://github.com/pnp/sp-dev-fx-controls-react/pull/2077) +- `TreeView`: TreeView Item - pass through imageProps of iconProps to TreeItem [#2074](https://github.com/pnp/sp-dev-fx-controls-react/issues/2074) + +### Enhancements + +- `ListItemAttachments`: Add render options for ListItemAttachments [2081](https://github.com/pnp/sp-dev-fx-controls-react/pull/2081) + +### New Control(s) + +- `GroupPicker`: New GroupPicker Control - select one or multiple M365 Groups [2085](https://github.com/pnp/sp-dev-fx-controls-react/pull/2085) + +### Contributors + +Special thanks to our contributors (in alphabetical order): [Antanina Druzhkina](https://github.com/Ateina), [Michaël Maillot](https://github.com/michaelmaillot), [Nishkalank Bezawada](https://github.com/NishkalankBezawada). +Special thanks to our contributors (in alphabetical order): [Antanina Druzhkina](https://github.com/Ateina),[wuxiaojun514](https://github.com/wuxiaojun514),[Paul Schaeflein](https://github.com/pschaeflein). ## 3.23.0 @@ -37,7 +61,7 @@ Special thanks to our contributors (in alphabetical order): [Antanina Druzhkina] - `ListItemComments`: Implement like and unlike ability to list item comments control [#1974](https://github.com/pnp/sp-dev-fx-controls-react/pull/1974) - `ListItemComments`: Need a feature to view the list of users who liked a comment [#2003](https://github.com/pnp/sp-dev-fx-controls-react/issues/2003) - `ListItemComments`: Clickable links [#1969](https://github.com/pnp/sp-dev-fx-controls-react/issues/1969) -- `Polish translations`: Updates Polish translations. Closes #1991](https://github.com/pnp/sp-dev-fx-controls-react/issues/1991) +- `Polish translations`: Updates Polish translations. Closes [#1991](https://github.com/pnp/sp-dev-fx-controls-react/issues/1991) - `Dashboard`: Dashboard widget rowspan [#2007](https://github.com/pnp/sp-dev-fx-controls-react/pull/2007) - `ListItemComments`: Guest user @-mentions and styling fix for ListItemComments [#1990](https://github.com/pnp/sp-dev-fx-controls-react/pull/1990) - `GridLayout`: 1852 - Grid layout settings as parameters [#1976](https://github.com/pnp/sp-dev-fx-controls-react/pull/1976) @@ -49,7 +73,7 @@ Special thanks to our contributors (in alphabetical order): [Antanina Druzhkina] - `FilePicker`: Unable to browse through organization assets library when located on root site [#1784](https://github.com/pnp/sp-dev-fx-controls-react/issues/1784) - `Calendar`: Fix - fix-typo-enableOnHover [#2021](https://github.com/pnp/sp-dev-fx-controls-react/pull/2021) - `Dynamic Form`: Hotfix for issue 2014 [#2026](https://github.com/pnp/sp-dev-fx-controls-react/issues/2014) -- `ListItemAttachments`: Update ListItemAttachments.tsx: let user set webUrl fix for issue 1975 [#2009](https://github.com/pnp/sp-dev-fx-controls-react/issues/1975 +- `ListItemAttachments`: Update ListItemAttachments.tsx: let user set webUrl fix for issue 1975 [#2009](https://github.com/pnp/sp-dev-fx-controls-react/issues/1975) - `FilePicker`: Files keep loading when previewing all files in OneDrive [#2021](https://github.com/pnp/sp-dev-fx-controls-react/issues/1994) - `ListItemAttachments`: ListItemAttachments cancel event is hanging the control [#1982](https://github.com/pnp/sp-dev-fx-controls-react/issues/1966) - `filePicker`: FilePicker order of tabs and default tab[#1980](https://github.com/pnp/sp-dev-fx-controls-react/issues/921) @@ -116,7 +140,7 @@ Special thanks to our contributors (in alphabetical order): [Adam Wójcik](https - `ListItemPicker`: PR fixes an issue with filtering when using calculated column as columnInternalName in ListItemPicker. [#1887](https://github.com/pnp/sp-dev-fx-controls-react/pull/1887) - `ListItemAttachments`: Fix 1858 to correct Chinese localization files #1894 [#1894](https://github.com/pnp/sp-dev-fx-controls-react/pull/1894) - `DynamicForm`: Fixing issue 1862 - Dynamic form should hide fields that are hidden on the List Content Type [#1872](https://github.com/pnp/sp-dev-fx-controls-react/pull/1872) -- `GridLayout`: A quick fix for #838. When compact mode the number of items rendered per page must match the number of all items. [1851](https://github.com/pnp/sp-dev-fx-controls-react/pull/1851) +- `GridLayout`: A quick fix for #838. When compact mode the number of items rendered per page must match the number of all items. [#1851](https://github.com/pnp/sp-dev-fx-controls-react/pull/1851) - `DynamicForm`: Always Show Required Field Validation Error In FormDisplayMode.Edit Mode [#1775](https://github.com/pnp/sp-dev-fx-controls-react/issues/1775) - `DynamicForm`: Required Field Validation won't work [#1760](https://github.com/pnp/sp-dev-fx-controls-react/issues/1760) - `DynamicForm`: Adds ability to render file/folder name field in DynamicForm and Field. [#1906](https://github.com/pnp/sp-dev-fx-controls-react/pull/1906) @@ -248,7 +272,7 @@ Special thanks to our contributor: [IRRDC](https://github.com/IRRDC). - `TaxonomyPicker`: suggested item contains double termset name [#1597](https://github.com/pnp/sp-dev-fx-controls-react/issues/1597) - `DynamicForm`: DynamicForm does not properly handle NULL default values for Taxonomy fields [#1267](https://github.com/pnp/sp-dev-fx-controls-react/issues/1267) - `DynamicForm`: New items are always created with the default content type if the list has multiple content types [#1626](https://github.com/pnp/sp-dev-fx-controls-react/pull/1626) -- `PeoplePicker`:PeoplePicker won't accept Multiple Users with the same name [#1620] (https://github.com/pnp/sp-dev-fx-controls-react/pull/1620) +- `PeoplePicker`: PeoplePicker won't accept Multiple Users with the same name [#1620](https://github.com/pnp/sp-dev-fx-controls-react/pull/1620) - `DynamicForm`: Dynamic Form accessed TaxonomyFieldTypeMulti without considering sub-array results [#1614](https://github.com/pnp/sp-dev-fx-controls-react/pull/1614) - `DynamicForm`: Number validations are working, but the percentage values are not getting saved [#1601](https://github.com/pnp/sp-dev-fx-controls-react/pull/1601) - `DynamicForm`: Number validation is preventing form save in certain circumstances, not enabled for currency fields [#1604](https://github.com/pnp/sp-dev-fx-controls-react/issues/1604) @@ -318,7 +342,7 @@ Special thanks to our contributors (in alphabetical order): [Andreas Omayrat](ht - `DynamicForm`: DynamicForm - Fixing Required Multi Field Saving Problem [#1489](https://github.com/pnp/sp-dev-fx-controls-react/issues/1489) - `FolderExplorer`: FolderExplorer doesn't explore folders with ' in the name [#1491](https://github.com/pnp/sp-dev-fx-controls-react/issues/1491) - `DynamicForm`: cannot display lookup value when the source field is not Title [#1511](https://github.com/pnp/sp-dev-fx-controls-react/issues/1511) -- `FilePicker`:Features/1478 filepicker tiles view [#1521](https://github.com/pnp/sp-dev-fx-controls-react/issues/1521) +- `FilePicker`: Features/1478 filepicker tiles view [#1521](https://github.com/pnp/sp-dev-fx-controls-react/issues/1521) ### Contributors @@ -1019,7 +1043,7 @@ Special thanks to our contributor: [Gautam Sheth](https://github.com/gautamdshet - `TaxonomyPicker`: browse (tree view) doesn't work with SP 2016 On-Premises [#183](https://github.com/pnp/sp-dev-fx-controls-react/issues/183) - `FilePicker`: default tab when opened shows hidden RecentTab [#477](https://github.com/pnp/sp-dev-fx-controls-react/issues/477) - `PeoplePicker`: The required error message not showing [#590](https://github.com/pnp/sp-dev-fx-controls-react/issues/590) -- `ListItemAttachments`: fails in Microsoft Teams Tab SPFx applications [#582](fails in Microsoft Teams Tab SPFx applications) +- `ListItemAttachments`: fails in Microsoft Teams Tab SPFx applications [#582](https://github.com/pnp/sp-dev-fx-controls-react/issues/582) - `Carousel`: Changing pages doesn't work [#609](https://github.com/pnp/sp-dev-fx-controls-react/issues/609) - `TaxonomyPicker`: no suggestions are displayed if `anchorId` is not set - `TaxonomyPicker`: Suggestion/match does not work as expected [#604](https://github.com/pnp/sp-dev-fx-controls-react/issues/604) diff --git a/docs/documentation/docs/about/release-notes.md b/docs/documentation/docs/about/release-notes.md index 136a3e4d4..dd4f34264 100644 --- a/docs/documentation/docs/about/release-notes.md +++ b/docs/documentation/docs/about/release-notes.md @@ -1,5 +1,16 @@ # Releases +## 3.24.0 + +### Fixes + +- `PeoplePicker`: Improving documentation page about external users search [#323](https://github.com/pnp/sp-dev-fx-controls-react/issues/323) +- `FolderExplorer`: Updated Folder explorer control documentation to correct a typo. [#2072](https://github.com/pnp/sp-dev-fx-controls-react/pull/2072) + +### Contributors + +Special thanks to our contributors (in alphabetical order): [Antanina Druzhkina](https://github.com/Ateina), [Michaël Maillot](https://github.com/michaelmaillot), [Nishkalank Bezawada](https://github.com/NishkalankBezawada). + ## 3.23.0 ### Enhancements @@ -37,7 +48,7 @@ Special thanks to our contributors (in alphabetical order): [Antanina Druzhkina] - `ListItemComments`: Implement like and unlike ability to list item comments control [#1974](https://github.com/pnp/sp-dev-fx-controls-react/pull/1974) - `ListItemComments`: Need a feature to view the list of users who liked a comment [#2003](https://github.com/pnp/sp-dev-fx-controls-react/issues/2003) - `ListItemComments`: Clickable links [#1969](https://github.com/pnp/sp-dev-fx-controls-react/issues/1969) -- `Polish translations`: Updates Polish translations. Closes #1991](https://github.com/pnp/sp-dev-fx-controls-react/issues/1991) +- `Polish translations`: Updates Polish translations. Closes [#1991](https://github.com/pnp/sp-dev-fx-controls-react/issues/1991) - `Dashboard`: Dashboard widget rowspan [#2007](https://github.com/pnp/sp-dev-fx-controls-react/pull/2007) - `ListItemComments`: Guest user @-mentions and styling fix for ListItemComments [#1990](https://github.com/pnp/sp-dev-fx-controls-react/pull/1990) - `GridLayout`: 1852 - Grid layout settings as parameters [#1976](https://github.com/pnp/sp-dev-fx-controls-react/pull/1976) @@ -49,7 +60,7 @@ Special thanks to our contributors (in alphabetical order): [Antanina Druzhkina] - `FilePicker`: Unable to browse through organization assets library when located on root site [#1784](https://github.com/pnp/sp-dev-fx-controls-react/issues/1784) - `Calendar`: Fix - fix-typo-enableOnHover [#2021](https://github.com/pnp/sp-dev-fx-controls-react/pull/2021) - `Dynamic Form`: Hotfix for issue 2014 [#2026](https://github.com/pnp/sp-dev-fx-controls-react/issues/2014) -- `ListItemAttachments`: Update ListItemAttachments.tsx: let user set webUrl fix for issue 1975 [#2009](https://github.com/pnp/sp-dev-fx-controls-react/issues/1975 +- `ListItemAttachments`: Update ListItemAttachments.tsx: let user set webUrl fix for issue 1975 [#2009](https://github.com/pnp/sp-dev-fx-controls-react/issues/1975) - `FilePicker`: Files keep loading when previewing all files in OneDrive [#2021](https://github.com/pnp/sp-dev-fx-controls-react/issues/1994) - `ListItemAttachments`: ListItemAttachments cancel event is hanging the control [#1982](https://github.com/pnp/sp-dev-fx-controls-react/issues/1966) - `filePicker`: FilePicker order of tabs and default tab[#1980](https://github.com/pnp/sp-dev-fx-controls-react/issues/921) @@ -116,7 +127,7 @@ Special thanks to our contributors (in alphabetical order): [Adam Wójcik](https - `ListItemPicker`: PR fixes an issue with filtering when using calculated column as columnInternalName in ListItemPicker. [#1887](https://github.com/pnp/sp-dev-fx-controls-react/pull/1887) - `ListItemAttachments`: Fix 1858 to correct Chinese localization files #1894 [#1894](https://github.com/pnp/sp-dev-fx-controls-react/pull/1894) - `DynamicForm`: Fixing issue 1862 - Dynamic form should hide fields that are hidden on the List Content Type [#1872](https://github.com/pnp/sp-dev-fx-controls-react/pull/1872) -- `GridLayout`: A quick fix for #838. When compact mode the number of items rendered per page must match the number of all items. [1851](https://github.com/pnp/sp-dev-fx-controls-react/pull/1851) +- `GridLayout`: A quick fix for #838. When compact mode the number of items rendered per page must match the number of all items. [#1851](https://github.com/pnp/sp-dev-fx-controls-react/pull/1851) - `DynamicForm`: Always Show Required Field Validation Error In FormDisplayMode.Edit Mode [#1775](https://github.com/pnp/sp-dev-fx-controls-react/issues/1775) - `DynamicForm`: Required Field Validation won't work [#1760](https://github.com/pnp/sp-dev-fx-controls-react/issues/1760) - `DynamicForm`: Adds ability to render file/folder name field in DynamicForm and Field. [#1906](https://github.com/pnp/sp-dev-fx-controls-react/pull/1906) @@ -248,7 +259,7 @@ Special thanks to our contributor: [IRRDC](https://github.com/IRRDC). - `TaxonomyPicker`: suggested item contains double termset name [#1597](https://github.com/pnp/sp-dev-fx-controls-react/issues/1597) - `DynamicForm`: DynamicForm does not properly handle NULL default values for Taxonomy fields [#1267](https://github.com/pnp/sp-dev-fx-controls-react/issues/1267) - `DynamicForm`: New items are always created with the default content type if the list has multiple content types [#1626](https://github.com/pnp/sp-dev-fx-controls-react/pull/1626) -- `PeoplePicker`:PeoplePicker won't accept Multiple Users with the same name [#1620] (https://github.com/pnp/sp-dev-fx-controls-react/pull/1620) +- `PeoplePicker`: PeoplePicker won't accept Multiple Users with the same name [#1620](https://github.com/pnp/sp-dev-fx-controls-react/pull/1620) - `DynamicForm`: Dynamic Form accessed TaxonomyFieldTypeMulti without considering sub-array results [#1614](https://github.com/pnp/sp-dev-fx-controls-react/pull/1614) - `DynamicForm`: Number validations are working, but the percentage values are not getting saved [#1601](https://github.com/pnp/sp-dev-fx-controls-react/pull/1601) - `DynamicForm`: Number validation is preventing form save in certain circumstances, not enabled for currency fields [#1604](https://github.com/pnp/sp-dev-fx-controls-react/issues/1604) @@ -318,7 +329,7 @@ Special thanks to our contributors (in alphabetical order): [Andreas Omayrat](ht - `DynamicForm`: DynamicForm - Fixing Required Multi Field Saving Problem [#1489](https://github.com/pnp/sp-dev-fx-controls-react/issues/1489) - `FolderExplorer`: FolderExplorer doesn't explore folders with ' in the name [#1491](https://github.com/pnp/sp-dev-fx-controls-react/issues/1491) - `DynamicForm`: cannot display lookup value when the source field is not Title [#1511](https://github.com/pnp/sp-dev-fx-controls-react/issues/1511) -- `FilePicker`:Features/1478 filepicker tiles view [#1521](https://github.com/pnp/sp-dev-fx-controls-react/issues/1521) +- `FilePicker`: Features/1478 filepicker tiles view [#1521](https://github.com/pnp/sp-dev-fx-controls-react/issues/1521) ### Contributors @@ -1019,7 +1030,7 @@ Special thanks to our contributor: [Gautam Sheth](https://github.com/gautamdshet - `TaxonomyPicker`: browse (tree view) doesn't work with SP 2016 On-Premises [#183](https://github.com/pnp/sp-dev-fx-controls-react/issues/183) - `FilePicker`: default tab when opened shows hidden RecentTab [#477](https://github.com/pnp/sp-dev-fx-controls-react/issues/477) - `PeoplePicker`: The required error message not showing [#590](https://github.com/pnp/sp-dev-fx-controls-react/issues/590) -- `ListItemAttachments`: fails in Microsoft Teams Tab SPFx applications [#582](fails in Microsoft Teams Tab SPFx applications) +- `ListItemAttachments`: fails in Microsoft Teams Tab SPFx applications [#582](https://github.com/pnp/sp-dev-fx-controls-react/issues/582) - `Carousel`: Changing pages doesn't work [#609](https://github.com/pnp/sp-dev-fx-controls-react/issues/609) - `TaxonomyPicker`: no suggestions are displayed if `anchorId` is not set - `TaxonomyPicker`: Suggestion/match does not work as expected [#604](https://github.com/pnp/sp-dev-fx-controls-react/issues/604) diff --git a/docs/documentation/docs/assets/GroupPicker-All.png b/docs/documentation/docs/assets/GroupPicker-All.png new file mode 100644 index 000000000..836570d1f Binary files /dev/null and b/docs/documentation/docs/assets/GroupPicker-All.png differ diff --git a/docs/documentation/docs/assets/GroupPicker-M365.png b/docs/documentation/docs/assets/GroupPicker-M365.png new file mode 100644 index 000000000..3c99eb66d Binary files /dev/null and b/docs/documentation/docs/assets/GroupPicker-M365.png differ diff --git a/docs/documentation/docs/assets/GroupPicker-MultiSelect.png b/docs/documentation/docs/assets/GroupPicker-MultiSelect.png new file mode 100644 index 000000000..45200eac0 Binary files /dev/null and b/docs/documentation/docs/assets/GroupPicker-MultiSelect.png differ diff --git a/docs/documentation/docs/assets/GroupPicker-Security.png b/docs/documentation/docs/assets/GroupPicker-Security.png new file mode 100644 index 000000000..faa01b3de Binary files /dev/null and b/docs/documentation/docs/assets/GroupPicker-Security.png differ diff --git a/docs/documentation/docs/assets/GroupPicker.png b/docs/documentation/docs/assets/GroupPicker.png new file mode 100644 index 000000000..5a3815a68 Binary files /dev/null and b/docs/documentation/docs/assets/GroupPicker.png differ diff --git a/docs/documentation/docs/assets/ListItemAttachmentsDetailsList.png b/docs/documentation/docs/assets/ListItemAttachmentsDetailsList.png new file mode 100644 index 000000000..93abdca58 Binary files /dev/null and b/docs/documentation/docs/assets/ListItemAttachmentsDetailsList.png differ diff --git a/docs/documentation/docs/assets/ListItemAttachmentsDetailsListCompact.png b/docs/documentation/docs/assets/ListItemAttachmentsDetailsListCompact.png new file mode 100644 index 000000000..e3416a61d Binary files /dev/null and b/docs/documentation/docs/assets/ListItemAttachmentsDetailsListCompact.png differ diff --git a/docs/documentation/docs/controls/FolderExplorer.md b/docs/documentation/docs/controls/FolderExplorer.md index 0811d09f8..95b0cc195 100644 --- a/docs/documentation/docs/controls/FolderExplorer.md +++ b/docs/documentation/docs/controls/FolderExplorer.md @@ -1,6 +1,6 @@ # FolderExplorer control -This control allows you to explore a folder structure by clinking on a folder to load it's sub-folders and using a breadcrumb navigation to navigate back to a previous level. +This control allows you to explore a folder structure by clicking on a folder to load it's sub-folders and using a breadcrumb navigation to navigate back to a previous level. It also allows the user to create a new folder at the current level being explored. Here is an example of the control: diff --git a/docs/documentation/docs/controls/GroupPicker.md b/docs/documentation/docs/controls/GroupPicker.md new file mode 100644 index 000000000..d95d9c4c5 --- /dev/null +++ b/docs/documentation/docs/controls/GroupPicker.md @@ -0,0 +1,74 @@ +# GroupPicker control + +This control allows you to select one or multiple Microsoft 365 groups and/or security groups using Microsoft Graph. Suggestions and selected items display a small icon indicating the group type. + +Here is an example of the control: + +![GroupPicker initial](../assets/GroupPicker.png) + +`GroupPicker` single selection mode showing all groups: + +![GroupPicker All](../assets/GroupPicker-All.png) + +`GroupPicker` single selection mode showing M365 groups: + +![GroupPicker M365](../assets/GroupPicker-M365.png) + +`GroupPicker` single selection mode showing Security groups: + +![GroupPicker Security](../assets/GroupPicker-Security.png) + +`GroupPicker` multi-selection mode: + +![GroupPicker multi selection](../assets/GroupPicker-MultiSelect.png) + +## How to use this control in your solutions + +- Check that you installed the `@pnp/spfx-controls-react` dependency. Check out the [getting started](../../#getting-started) page for more information about installing the dependency. +- Import the control into your component: + +```TypeScript +import { GroupPicker } from "@pnp/spfx-controls-react/lib/GroupPicker"; +``` + +- Use the `GroupPicker` control in your code as follows: + +```TypeScript + { + this.setState({ selectedGroups: tagList }); + }} + groupType="M365" //All, Security + themeVariant={this.props.themeVariant} + /> +``` + +## Implementation + +The `GroupPicker` control can be configured with the following properties: + +| Property | Type | Required | Description | +| ---- | ---- | ---- | ---- | +| appcontext | BaseComponentContext | yes | The context object of the SPFx loaded webpart or customizer. | +| selectedGroups | ITag[] | yes | Array with selected groups. | +| itemLimit | number | no | Number of allowed selected items. | +| multiSelect | boolean | no | Optional mode indicates if multi-choice selections is allowed. Default is `true`. | +| label | string | no | Label of the picker. | +| styles | IBasePickerStyles | no | Custom styles of the picker. | +| themeVariant | IReadonlyTheme | no | Theme variant used for SharePoint/Teams theming. | +| groupType | GroupTypeFilter | no | Filter groups by type. Allowed values: `"All"`, `"M365"`, `"Security"`. Default is `"All"`. | +| onSelectedGroups | (tagsList: ITag[]) => void | yes | Callback with groups selected. | + +## MSGraph Permissions required + +This control requires Microsoft Graph permissions for reading groups. Grant at least one of the following: + +- `Group.Read.All` +- `Directory.Read.All` + +![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/GroupPicker) diff --git a/docs/documentation/docs/controls/ListItemAttachments.md b/docs/documentation/docs/controls/ListItemAttachments.md index 7600d07f8..9a7fa6232 100644 --- a/docs/documentation/docs/controls/ListItemAttachments.md +++ b/docs/documentation/docs/controls/ListItemAttachments.md @@ -1,6 +1,6 @@ # ListItemAttachments control -This control allows you to manage list item attachments, you can add or delete associated attachments. The attachments are listed in tile view. +This control allows you to manage list item attachments, you can add or delete associated attachments. The attachments can be displayed in different modes: tiles (default), list, or compact list. Here is an example of the control: @@ -12,6 +12,10 @@ Here is an example of the control: ![ListItemAttachments Attachment Deleted ](../assets/ListItemAttachementDeletedMsg.png) +![ListItemAttachments Details List ](../assets/ListItemAttachmentsDetailsList.png) + +![ListItemAttachments Details List Compact ](../assets/ListItemAttachmentsDetailsListCompact.png) + ## How to use this control in your solutions - Check that you installed the `@pnp/spfx-controls-react` dependency. Check out the [getting started](../../#getting-started) page for more information about installing the dependency. @@ -30,6 +34,30 @@ import { ListItemAttachments } from '@pnp/spfx-controls-react/lib/ListItemAttach disabled={false} /> ``` +- You can customize the display mode of attachments. Import the `AttachmentsDisplayMode` enum and use it: + +```TypeScript +import { ListItemAttachments, AttachmentsDisplayMode } from '@pnp/spfx-controls-react/lib/ListItemAttachments'; + +// Tiles view (default) + + +// List view + + +// Compact list view + +``` + - If you want to use `ListItemAttachments` controls with new form you have to use React.createRef. Following example will add selected attachments to list item with id = 1 @@ -61,10 +89,21 @@ The `ListItemAttachments` control can be configured with the following propertie | webUrl | string | no | URL of the site. By default it uses the current site URL. | | label | string | no | Main text to display on the placeholder, next to the icon. | | description | string | no | Description text to display on the placeholder, below the main text and icon. | +| displayMode | AttachmentsDisplayMode | no | Display mode for rendering attachments. Options: `AttachmentsDisplayMode.Tiles` (default), `AttachmentsDisplayMode.DetailsList`, or `AttachmentsDisplayMode.DetailsListCompact`. | | disabled | boolean | no | Specifies if the control is disabled or not. | | openAttachmentsInNewWindow | boolean | no | Specifies if the attachment should be opened in a separate browser tab. Use this property set to `true` if you plan to use the component in Microsoft Teams. | | onAttachmentChange | (itemData: any) => void | no | Callback function invoked when attachments are added or removed. Receives the updated item data including the new ETag. This is useful when using the control within a form (like DynamicForm) that tracks ETags for optimistic concurrency control. | +enum `AttachmentsDisplayMode` + +Display mode for rendering attachments. + +| Value | Description | +| ---- | ---- | +| Tiles | Displays attachments as tiles/thumbnails using DocumentCard components. This is the default mode. | +| DetailsList | Displays attachments in a list format with file type icons, file names, and delete actions. | +| DetailsListCompact | Displays attachments in a compact list format with reduced row height and padding. | + ## Usage with DynamicForm When using `ListItemAttachments` within a `DynamicForm` or any component that uses ETags for optimistic concurrency control, you should use the `onAttachmentChange` callback to update the ETag when attachments are modified: diff --git a/docs/documentation/docs/controls/PeoplePicker.md b/docs/documentation/docs/controls/PeoplePicker.md index c69926a38..8fc490758 100644 --- a/docs/documentation/docs/controls/PeoplePicker.md +++ b/docs/documentation/docs/controls/PeoplePicker.md @@ -62,6 +62,10 @@ private _getPeoplePickerItems(items: any[]) { Sometimes, depending on how your organization is configured regarding users and groups, performing search can be tricky. As the `PeoplePicker` is using the `SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser` endpoint under the hood, there is an optional parameter called `useSubstrateSearch`. Setting this to `true` will perform a search using the Microsoft 365 Substrate, which will go through centralized stored data in order to find requested info. More details about this feature can be found [here](https://techcommunity.microsoft.com/t5/video-hub/admin-39-s-guide-to-the-microsoft-365-substrate/ba-p/3633132) and [here](https://youtu.be/uuiTR8r27Os?si=JkPyfiQggvCMj0xg&t=467). +## Enable external users search + +To enable external users search, the `allowUnvalidated` property must be set to `true`. Behind the scenes, it will include returned values from search with `EntityData.PrincipalType` set to `UNVALIDATED_EMAIL_ADDRESS`. + ## Implementation The People picker control can be configured with the following properties: diff --git a/package-lock.json b/package-lock.json index 70c227252..f27816fe7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@pnp/spfx-controls-react", - "version": "3.23.0", + "version": "3.24.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@pnp/spfx-controls-react", - "version": "3.23.0", + "version": "3.24.0", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 56bac36c7..4547f1475 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@pnp/spfx-controls-react", "description": "Reusable React controls for SharePoint Framework solutions", - "version": "3.23.0", + "version": "3.24.0", "engines": { "node": ">=22.14.0 < 23.0.0" }, diff --git a/src/GroupPicker.ts b/src/GroupPicker.ts new file mode 100644 index 000000000..b678381e5 --- /dev/null +++ b/src/GroupPicker.ts @@ -0,0 +1 @@ +export * from "./controls/groupPicker"; diff --git a/src/common/model/IGroup.ts b/src/common/model/IGroup.ts new file mode 100644 index 000000000..1ea62f44b --- /dev/null +++ b/src/common/model/IGroup.ts @@ -0,0 +1,11 @@ +export interface IGroup { + id: string; + displayName: string; + description?: string; + groupTypes?: string[]; + mailEnabled?: boolean; + mail?: string; + securityEnabled?: boolean; + visibility?: string; + resourceProvisioningOptions?: string[]; +} diff --git a/src/common/telemetry/version.ts b/src/common/telemetry/version.ts index 394528b54..8ad27f8e1 100644 --- a/src/common/telemetry/version.ts +++ b/src/common/telemetry/version.ts @@ -1 +1 @@ -export const version: string = "3.23.0"; \ No newline at end of file +export const version: string = "3.24.0"; \ No newline at end of file diff --git a/src/controls/groupPicker/GroupPicker.tsx b/src/controls/groupPicker/GroupPicker.tsx new file mode 100644 index 000000000..3700c2447 --- /dev/null +++ b/src/controls/groupPicker/GroupPicker.tsx @@ -0,0 +1,256 @@ +import * as React from "react"; +import { + TagPicker, + IBasePicker, + ITag, + IBasePickerSuggestionsProps, + IPickerItemProps, + ISuggestionItemProps, +} from "@fluentui/react/lib/Pickers"; + +import { useGroups } from "../../hooks"; +import { IGroup } from "../../common/model/IGroup"; +import { IGroupPickerProps, GroupTypeFilter } from "./IGroupPickerProps"; +import { IGroupPickerState } from "./IGroupPickerState"; +import { useGroupPickerStyles } from "./GroupPickerStyles"; +import { IconButton } from "@fluentui/react/lib/Button"; +import { Text } from "@fluentui/react/lib/Text"; +import { Stack } from "@fluentui/react/lib/Stack"; +import { Label } from "@fluentui/react/lib/Label"; +import { FontIcon } from "@fluentui/react/lib/Icon"; +import { Customizer } from "@fluentui/react/lib/Utilities"; + +import pullAllBy from "lodash/pullAllBy"; +import find from "lodash/find"; +import strings from "ControlStrings"; + +const pickerSuggestionsProps: IBasePickerSuggestionsProps = { + suggestionsHeaderText: strings.GroupPickerSuggestionsHeaderText, + noResultsFoundText: strings.genericNoResultsFoundText, +}; + +const initialState: IGroupPickerState = { + savedSelectedGroups: [], +}; + +const getTextFromItem = (item: ITag): string => item.name; + +const matchGroupType = ( + group: IGroup, + groupType?: GroupTypeFilter +): boolean => { + if (!groupType || groupType === "All") return true; + + const isUnified = group.groupTypes?.includes("Unified"); + const isSecurity = !!group.securityEnabled && !isUnified; + + if (groupType === "M365") return isUnified; + if (groupType === "Security") return isSecurity; + return true; +}; + +const reducer = ( + state: IGroupPickerState, + action: { type: string; payload: any } // eslint-disable-line @typescript-eslint/no-explicit-any +): IGroupPickerState => { + switch (action.type) { + case "UPDATE_SELECTEDITEM": + return { ...state, savedSelectedGroups: action.payload }; + default: + return state; + } +}; + +export const GroupPicker: React.FunctionComponent = ( + props: IGroupPickerProps +) => { + const [state, dispatch] = React.useReducer(reducer, initialState); + const picker = React.useRef>(null); + const { serviceScope } = props.appcontext; + const { getGroups } = useGroups(serviceScope); + const { + onSelectedGroups, + selectedGroups, + itemLimit, + multiSelect, + label, + styles, + themeVariant, + groupType, + } = props; + + const { + pickerStylesMulti, + pickerStylesSingle, + renderItemStylesMulti, + renderItemStylesSingle, + renderIconButtonRemoveStyles, + componentClasses, + } = useGroupPickerStyles(themeVariant); + + const groupTypeById = React.useRef>({}); + + const getGroupTypeIcon = React.useCallback( + (groupId: string | number | undefined): JSX.Element | null => { + if (!groupId) return null; + const groupType = groupTypeById.current[groupId.toString()]; + if (!groupType) return null; + if (groupType === "m365") { + return ( + + ); + } + return ( + + ); + }, + [componentClasses.groupTypeIconM365, componentClasses.groupTypeIconSecurity] + ); + + const useFilterSuggestedGroups = React.useCallback( + async (filterText: string, groupsList: ITag[]): Promise => { + const tags: ITag[] = []; + try { + const groups: IGroup[] = await getGroups(filterText); + if (groups?.length) { + for (const group of groups) { + if (!matchGroupType(group, groupType)) continue; + const isUnified = group.groupTypes?.includes("Unified"); + const groupTypeKey: "m365" | "security" | undefined = isUnified + ? "m365" + : group.securityEnabled + ? "security" + : undefined; + if (groupTypeKey) { + groupTypeById.current[group.id] = groupTypeKey; + } + const checkExists = find(groupsList, { key: group.id }); + if (checkExists) continue; + tags.push({ key: group.id, name: group.displayName }); + } + } + return tags; + } catch (error) { + console.log(error); + return tags; + } + }, + [groupType, getGroups] + ); + + React.useEffect(() => { + dispatch({ + type: "UPDATE_SELECTEDITEM", + payload: selectedGroups, + }); + }, [props]); + + const _onRenderItem = React.useCallback( + (itemProps: IPickerItemProps) => { + const { savedSelectedGroups } = state; + if (itemProps.item) { + return ( + 1) + ? renderItemStylesMulti + : renderItemStylesSingle + } + > + + {itemProps.item.name} + {getGroupTypeIcon(itemProps.item.key)} + { + const _newSelectedGroups = pullAllBy(savedSelectedGroups, [ + itemProps.item, + ]); + dispatch({ + type: "UPDATE_SELECTEDITEM", + payload: _newSelectedGroups, + }); + onSelectedGroups(_newSelectedGroups); + }} + /> + + ); + } + return null; + }, + [ + state.savedSelectedGroups, + renderItemStylesMulti, + renderItemStylesSingle, + renderIconButtonRemoveStyles, + itemLimit, + onSelectedGroups, + ] + ); + + const _onRenderSuggestionsItem = React.useCallback( + (propsTag: ITag, _itemProps: ISuggestionItemProps) => { + return ( + + + {propsTag.name} + {getGroupTypeIcon(propsTag.key)} + + ); + }, + [] + ); + + + return ( + +
+ {label && } + 1) + ? pickerStylesMulti + : pickerStylesSingle) + } + selectedItems={state.savedSelectedGroups} + onRenderItem={_onRenderItem} + onRenderSuggestionsItem={_onRenderSuggestionsItem} + onResolveSuggestions={useFilterSuggestedGroups} + getTextFromItem={getTextFromItem} + pickerSuggestionsProps={pickerSuggestionsProps} + onEmptyResolveSuggestions={(selectGroups) => { + return useFilterSuggestedGroups("", selectGroups); + }} + itemLimit={(multiSelect ?? true) ? (props.itemLimit ?? undefined) : 1} + onChange={(items) => { + dispatch({ type: "UPDATE_SELECTEDITEM", payload: items }); + props.onSelectedGroups(items); + }} + componentRef={picker} + /> +
+
+ ); +}; diff --git a/src/controls/groupPicker/GroupPickerStyles.ts b/src/controls/groupPicker/GroupPickerStyles.ts new file mode 100644 index 000000000..641a5784e --- /dev/null +++ b/src/controls/groupPicker/GroupPickerStyles.ts @@ -0,0 +1,166 @@ + +import { IButtonStyles } from "@fluentui/react/lib/Button"; +import { IStackStyles } from "@fluentui/react/lib/Stack"; +import { mergeStyles, mergeStyleSets } from "@fluentui/react/lib/Styling"; +import { IReadonlyTheme } from "@microsoft/sp-component-base"; +import { IBasePickerStyles } from "@fluentui/react/lib/Pickers"; +const theme = window.__themeState__.theme; + +export const useGroupPickerStyles = ( + themeVariant: IReadonlyTheme | undefined +) => { // eslint-disable-line @typescript-eslint/explicit-function-return-type + const renderIconButtonRemoveStyles: Partial = { + root: { + height: 26, + lineHeight: 26, + }, + }; + + const renderItemStylesMulti: Partial = { + root: { + height: 26, + lineHeight: 26, + paddingLeft: 10, + marginLeft: 5, + marginBottom: 5, + cursor: "default", + backgroundColor: + themeVariant?.palette?.themeLighterAlt ?? theme.themeLighterAlt, + ":hover": { + backgroundColor: theme.themeLighter, + }, + }, + }; + + const renderItemStylesSingle: Partial = { + root: { + height: 26, + lineHeight: 26, + paddingLeft: 10, + cursor: "default", + margin: 2, + backgroundColor: + themeVariant?.palette?.themeLighterAlt ?? theme.themeLighterAlt, + ":hover": { + backgroundColor: + themeVariant?.palette?.themeLighter ?? theme.themeLighter, + }, + }, + }; + + const pickerStylesSingle: Partial = { + root: { + width: " 100%", + borderRadius: 0, + marginTop: 0, + }, + + input: { + width: "100%", + backgroundColor: themeVariant?.palette?.white ?? theme.white, + }, + text: { + borderStyle: "solid", + width: "100%", + borderWidth: 1, + backgroundColor: themeVariant?.palette?.white ?? theme.white, + borderRadius: 0, + borderColor: + themeVariant?.palette?.neutralQuaternaryAlt ?? + theme.neutralQuaternaryAlt, + ":focus": { + borderStyle: "solid", + borderWidth: 1, + borderColor: themeVariant?.palette?.themePrimary ?? theme.themePrimary, + }, + ":hover": { + borderStyle: "solid", + borderWidth: 1, + borderColor: themeVariant?.palette?.themePrimary ?? theme.themePrimary, + }, + ":after": { + borderWidth: 0, + borderRadius: 0, + }, + }, + }; + + const pickerStylesMulti: Partial = { + root: { + width: " 100%", + borderRadius: 0, + }, + + input: { + width: "100%", + backgroundColor: themeVariant?.palette?.white ?? theme.white, + }, + itemsWrapper: { + padding: 3, + }, + text: { + borderStyle: "solid", + width: "100%", + borderWidth: 1, + backgroundColor: themeVariant?.palette?.white ?? theme.white, + borderRadius: 0, + borderColor: + themeVariant?.palette?.neutralQuaternaryAlt ?? + theme.neutralQuaternaryAlt, + ":focus": { + borderStyle: "solid", + borderWidth: 1, + borderColor: themeVariant?.palette?.themePrimary ?? theme.themePrimary, + }, + ":hover": { + borderStyle: "solid", + borderWidth: 1, + borderColor: themeVariant?.palette?.themePrimary ?? theme.themePrimary, + }, + ":after": { + borderStyle: "solid", + borderWidth: 1, + borderColor: themeVariant?.palette?.themePrimary ?? theme.themePrimary, + }, + }, + }; + + const componentClasses = mergeStyleSets({ + iconStyles: { + paddingLeft: 2, + fontWeight: 500, + color: themeVariant?.palette?.themePrimary ?? theme?.themePrimary, + }, + groupTypeIconM365: mergeStyles({ + fontSize: 14, + marginLeft: 8, + fontWeight: 600, + color: themeVariant?.palette?.themeDark ?? theme.themeDark, + }), + groupTypeIconSecurity: mergeStyles({ + fontSize: 14, + marginLeft: 8, + fontWeight: 600, + color: themeVariant?.palette?.neutralPrimary ?? theme.neutralPrimary, + }), + separator: mergeStyles({ + marginTop: 25, + marginLeft: 20, + marginRight: 20, + borderBottomWidth: 1, + borderBottomColor: + themeVariant?.palette?.neutralQuaternaryAlt ?? + theme.neutralQuaternaryAlt, + borderBottomStyle: "solid", + }), + }); + + return { + componentClasses, + pickerStylesMulti, + pickerStylesSingle, + renderItemStylesSingle, + renderItemStylesMulti, + renderIconButtonRemoveStyles, + }; +}; diff --git a/src/controls/groupPicker/IGroupPickerProps.ts b/src/controls/groupPicker/IGroupPickerProps.ts new file mode 100644 index 000000000..19fee5b5d --- /dev/null +++ b/src/controls/groupPicker/IGroupPickerProps.ts @@ -0,0 +1,19 @@ +import { BaseComponentContext } from "@microsoft/sp-component-base"; +import { IReadonlyTheme } from "@microsoft/sp-component-base"; +import { IBasePickerStyles, ITag } from "@fluentui/react/lib/Pickers"; + +export type GroupTypeFilter = "All" | "M365" | "Security"; + +export interface IGroupPickerProps { + appcontext: BaseComponentContext; + onSelectedGroups: (tagsList: ITag[]) => void; + selectedGroups: ITag[]; + themeVariant?: IReadonlyTheme; + /** Filter groups by type. Defaults to "All". */ + groupType?: GroupTypeFilter; + itemLimit?: number; + /** Optional mode indicates if multi-choice selections is allowed. Default is true. */ + multiSelect?: boolean; + label?: string; + styles?: IBasePickerStyles; +} diff --git a/src/controls/groupPicker/IGroupPickerState.ts b/src/controls/groupPicker/IGroupPickerState.ts new file mode 100644 index 000000000..d43db2e71 --- /dev/null +++ b/src/controls/groupPicker/IGroupPickerState.ts @@ -0,0 +1,5 @@ +import { ITag } from "@fluentui/react/lib/Pickers"; + +export interface IGroupPickerState { + savedSelectedGroups: ITag[]; +} diff --git a/src/controls/groupPicker/index.ts b/src/controls/groupPicker/index.ts new file mode 100644 index 000000000..0eccbeaff --- /dev/null +++ b/src/controls/groupPicker/index.ts @@ -0,0 +1,3 @@ +export * from "./IGroupPickerState"; +export * from "./GroupPicker"; +export * from "./IGroupPickerProps"; diff --git a/src/controls/listItemAttachments/AttachmentsDisplayMode.ts b/src/controls/listItemAttachments/AttachmentsDisplayMode.ts new file mode 100644 index 000000000..0e31c4923 --- /dev/null +++ b/src/controls/listItemAttachments/AttachmentsDisplayMode.ts @@ -0,0 +1,14 @@ +export enum AttachmentsDisplayMode { + /** + * Display attachments as tiles/thumbnails using DocumentCard + */ + Tiles = 'tiles', + /** + * Display attachments as a list using DetailsList in normal mode + */ + DetailsList = 'list', + /** + * Display attachments as a compact list using DetailsList in compact mode + */ + DetailsListCompact = 'listCompact' +} \ No newline at end of file diff --git a/src/controls/listItemAttachments/IListItemAttachmentsProps.ts b/src/controls/listItemAttachments/IListItemAttachmentsProps.ts index e3d8be952..afed9e1a7 100644 --- a/src/controls/listItemAttachments/IListItemAttachmentsProps.ts +++ b/src/controls/listItemAttachments/IListItemAttachmentsProps.ts @@ -1,4 +1,5 @@ import { BaseComponentContext } from '@microsoft/sp-component-base'; +import { AttachmentsDisplayMode } from './AttachmentsDisplayMode'; export interface IListItemAttachmentsProps { listId: string; @@ -16,6 +17,10 @@ export interface IListItemAttachmentsProps { * Description text to display on the placeholder, below the main text and icon */ description?:string; + /** + * Display mode for rendering attachments. Defaults to Tiles. + */ + displayMode?: AttachmentsDisplayMode; /** * Callback function to notify parent components when attachments are modified and the item ETag changes * @param itemData - The updated item data including the new ETag diff --git a/src/controls/listItemAttachments/ListItemAttachments.module.scss b/src/controls/listItemAttachments/ListItemAttachments.module.scss index 7b62563dc..6413ff27e 100644 --- a/src/controls/listItemAttachments/ListItemAttachments.module.scss +++ b/src/controls/listItemAttachments/ListItemAttachments.module.scss @@ -33,6 +33,17 @@ background-color: transparent !important; font-size: 15px; } + + .detailsList { + .detailsListIcon { + vertical-align: middle; + max-height: 16px; + max-width: 16px; + } + .detailsListLink { + padding-top: 2px; + } + } } .uploadBar { diff --git a/src/controls/listItemAttachments/ListItemAttachments.tsx b/src/controls/listItemAttachments/ListItemAttachments.tsx index 665c0c83d..15447fb76 100755 --- a/src/controls/listItemAttachments/ListItemAttachments.tsx +++ b/src/controls/listItemAttachments/ListItemAttachments.tsx @@ -1,9 +1,11 @@ // Joao Mendes November 2018, SPFx reusable Control ListItemAttachments import * as React from 'react'; import { Dialog, DialogType, DialogFooter } from '@fluentui/react/lib/Dialog'; -import { PrimaryButton, DefaultButton } from '@fluentui/react/lib/Button'; +import { PrimaryButton, DefaultButton, IconButton } from '@fluentui/react/lib/Button'; import { DirectionalHint } from '@fluentui/react/lib/Callout'; import { Label } from "@fluentui/react/lib/Label"; +import { Link } from '@fluentui/react/lib/Link'; +import { DetailsList, DetailsListLayoutMode, SelectionMode } from '@fluentui/react/lib/DetailsList'; import * as strings from 'ControlStrings'; import styles from './ListItemAttachments.module.scss'; import { UploadAttachment } from './UploadAttachment'; @@ -17,6 +19,7 @@ import { import { ImageFit } from '@fluentui/react/lib/Image'; import { IListItemAttachmentsProps } from './IListItemAttachmentsProps'; import { IListItemAttachmentsState } from './IListItemAttachmentsState'; +import { AttachmentsDisplayMode } from './AttachmentsDisplayMode'; import SPservice from "../../services/SPService"; import { TooltipHost } from '@fluentui/react/lib/Tooltip'; import { Spinner, SpinnerSize } from '@fluentui/react/lib/Spinner'; @@ -251,35 +254,26 @@ export class ListItemAttachments extends React.Component { - const { openAttachmentsInNewWindow } = this.props; - return ( -
- this.setState({ fireUpload: false })} - onAttachmentChange={this.props.onAttachmentChange} - /> - - { - this.state.showPlaceHolder ? - this.setState({ fireUpload: true })} /> - : + private getFileExtension(fileName: string): string { + const lastDotIndex = fileName.lastIndexOf('.'); + if (lastDotIndex === -1 || lastDotIndex === fileName.length - 1) { + return ''; + } + return fileName.substring(lastDotIndex + 1).toLowerCase(); + } - this.state.attachments.map(file => { + /** + * Renders attachments in tile/thumbnail mode using DocumentCard components + * @returns JSX element containing attachment tiles + */ + private renderTiles (): JSX.Element { + const { openAttachmentsInNewWindow } = this.props; + return { + this.state.attachments.map(file => { const fileName = file.FileName; const previewImage = this.previewImages[fileName]; const clickDisabled = !this.state.itemId; @@ -321,7 +315,134 @@ export class ListItemAttachments extends React.Component
); - })} + }) + } + } + + /** + * Renders attachments in list mode using DetailsList component + * Supports both normal and compact display modes + * @returns JSX element containing attachment list + */ + private renderDetailsList (): JSX.Element { + const { displayMode, openAttachmentsInNewWindow } = this.props; + const columns = [ + { + key: 'columnFileType', + name: 'File Type', + iconName: 'Page', + isIconOnly: true, + minWidth: 16, + maxWidth: 16, + onRender: (file: IListItemAttachmentFile) => { + const fileExtension = this.getFileExtension(file.FileName); + const previewImage = this.previewImages[file.FileName]; + const iconUrl = previewImage?.previewImageSrc || ''; + return ( + + {`${fileExtension} + + ); + }, + }, + { + key: 'columnFileName', + name: 'File Name', + fieldName: 'FileName', + minWidth: 150, + maxWidth: 800, + isResizable: true, + onRender: (file: IListItemAttachmentFile) => { + const clickDisabled = !this.state.itemId; + + if (clickDisabled) { + return {file.FileName}; + } + + if (openAttachmentsInNewWindow) { + return ( + window.open(`${file.ServerRelativeUrl}?web=1`, "_blank")} + > + {file.FileName} + + ); + } + + return ( + + {file.FileName} + + ); + } + }, + { + key: 'columnDeleteIcon', + name: '', + minWidth: 32, + maxWidth: 32, + isResizable: true, + onRender: (file: IListItemAttachmentFile) => { + return ( + { + ev.preventDefault(); + ev.stopPropagation(); + this.onDeleteAttachment(file); }} /> + + ); + }, + } + ]; + return + } + + /** + * Default React render method + */ + public render(): React.ReactElement { + const { displayMode } = this.props; + return ( +
+ this.setState({ fireUpload: false })} + onAttachmentChange={this.props.onAttachmentChange} + /> + + { + this.state.showPlaceHolder ? + this.setState({ fireUpload: true })} /> + : + + <> + {(!displayMode || displayMode === AttachmentsDisplayMode.Tiles) && this.renderTiles()} + {(displayMode === AttachmentsDisplayMode.DetailsList || displayMode === AttachmentsDisplayMode.DetailsListCompact) && this.renderDetailsList()} + + } {!this.state.hideDialog && = ( const { text, mentions } = props; const mentionsResults: Mention[] = mentions; - useEffect(() => { - const hasMentions = mentions?.length ? true : false; - let result: string | JSX.Element[] = text; - if (hasMentions) { - result = regexifyString({ - pattern: /@mention{\d+}/g, - decorator: (match, index) => { - const mention = mentionsResults[index]; - const _name = `@${mention.name}`; - return ( - <> - {_name}} - /> - - ); - }, - input: text, - }) as JSX.Element[]; - } - setCommentText(result); - }, []); - const convertTextToLinksAndText = ( text: string ): (string | JSX.Element)[] => { @@ -69,34 +44,80 @@ export const CommentText: React.FunctionComponent = ( }); }; - return ( - <> - - {isArray(commentText) ? ( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (commentText as any[]).map((el, i) => { - if (isObject(el)) { - return ( - - {el} - - ); - } else { - const _el: string = el.trim(); - if (_el.length) { + useEffect(() => { + const hasMentions = mentions?.length ? true : false; + const lines = text.split(/\r?\n/); + const result: JSX.Element[] = []; + lines.forEach((line, idx) => { + let lineContent: string | JSX.Element[] = line; + if (hasMentions) { + lineContent = regexifyString({ + pattern: /@mention{\d+}/g, + decorator: (match, index) => { + const mention = mentionsResults[index]; + const _name = `@${mention.name}`; + return ( + + {_name} + + } + /> + ); + }, + input: line, + }) as JSX.Element[]; + } + result.push( + + {isArray(lineContent) ? ( + lineContent.length > 0 ? + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (lineContent as any[]).map((el, i) => { + if (isObject(el)) { return ( - - {convertTextToLinksAndText(he.decode(_el))} - + + {el} + ); + } else { + const _el: string = el.trim(); + if (_el.length) { + return ( + + {convertTextToLinksAndText(he.decode(_el))} + + ); + } } - } - }) - ) : ( - - {convertTextToLinksAndText(he.decode(commentText))} - - )} + }):
+ ) : lineContent.trim().length > 0 ? ( + + {convertTextToLinksAndText(he.decode(lineContent))} + + ) : ( +
+ )} +
+ ); + }); + setCommentText(result); + }, []); + + return ( + <> + + {commentText} ); diff --git a/src/controls/modernTaxonomyPicker/ModernTaxonomyPicker.tsx b/src/controls/modernTaxonomyPicker/ModernTaxonomyPicker.tsx index 5567b78d7..19d963ea4 100644 --- a/src/controls/modernTaxonomyPicker/ModernTaxonomyPicker.tsx +++ b/src/controls/modernTaxonomyPicker/ModernTaxonomyPicker.tsx @@ -168,7 +168,11 @@ export function ModernTaxonomyPicker(props: IModernTaxonomyPickerProps): JSX.Ele return terms; } + let searchFilter: string = null; + async function onResolveSuggestions(filter: string, selectedItems?: ITermInfo[]): Promise { + + searchFilter = filter; if (filter === '') { return []; } @@ -213,6 +217,7 @@ export function ModernTaxonomyPicker(props: IModernTaxonomyPickerProps): JSX.Ele term={term} termStoreInfo={currentTermStoreInfo} languageTag={currentLanguageTag} + searchFilter={searchFilter} {...itemProps} /> ); diff --git a/src/controls/modernTaxonomyPicker/termItem/TermItemSuggestion.tsx b/src/controls/modernTaxonomyPicker/termItem/TermItemSuggestion.tsx index f4ae951e4..09d9b4e44 100644 --- a/src/controls/modernTaxonomyPicker/termItem/TermItemSuggestion.tsx +++ b/src/controls/modernTaxonomyPicker/termItem/TermItemSuggestion.tsx @@ -9,6 +9,7 @@ export interface ITermItemSuggestionProps extends ISuggestionItemProps { term: ITermInfo; languageTag?: string; termStoreInfo?: ITermStoreInfo; + searchFilter?: string; onLoadParentLabel?: (termId: Guid) => Promise; } @@ -27,21 +28,34 @@ export function TermItemSuggestion(props: ITermItemSuggestionProps): } }, []); - let labels: { - name: string; - isDefault: boolean; - languageTag: string; - }[]; + const filterLabels = (isDefault: boolean, nameFilter?: (name: string) => boolean): { + name: string; + isDefault: boolean; + languageTag: string; + }[] => { - if (props.languageTag && props.termStoreInfo) { - labels = props.term.labels.filter((name) => name.languageTag === props.languageTag && name.isDefault); - if (labels.length === 0) { - labels = props.term.labels.filter((name) => name.languageTag === props.termStoreInfo.defaultLanguageTag && name.isDefault); + nameFilter = nameFilter || (() => true); + + if (props.languageTag && props.termStoreInfo) { + let labels = props.term.labels.filter((name) => name.languageTag === props.languageTag && name.isDefault === isDefault && nameFilter(name.name)); + if (labels.length === 0) { + labels = props.term.labels.filter((name) => name.languageTag === props.termStoreInfo.defaultLanguageTag && name.isDefault === isDefault && nameFilter(name.name)); + } + return labels; + } + else { + return props.term.labels.filter((name) => name.isDefault === isDefault && nameFilter(name.name)); } } - else { - labels = props.term.labels.filter((name) => name.isDefault); - } + + const labels = filterLabels(true); + const synonyms = props.searchFilter ? filterLabels(false, (name) => { + const prefix = props.searchFilter!; + if (prefix.length > name.length) + return false; + const compareTo = name.substring(0, prefix.length); + return compareTo.localeCompare(prefix, undefined, { sensitivity: 'base' }) === 0; + }) : []; return (
@@ -49,6 +63,9 @@ export function TermItemSuggestion(props: ITermItemSuggestionProps): {parentLabel !== "" &&
{`${strings.ModernTaxonomyPickerSuggestionInLabel} ${parentLabel}`}
} + {synonyms.length > 0 &&
    + {synonyms.map((synonym) =>
  • {synonym.name.substring(0, props.searchFilter!.length)}{synonym.name.substring(props.searchFilter!.length)}
  • )} +
}
); } diff --git a/src/controls/modernTaxonomyPicker/termItem/TermItemSuggestions.module.scss b/src/controls/modernTaxonomyPicker/termItem/TermItemSuggestions.module.scss index a0cb72004..a2e4fe7c8 100644 --- a/src/controls/modernTaxonomyPicker/termItem/TermItemSuggestions.module.scss +++ b/src/controls/modernTaxonomyPicker/termItem/TermItemSuggestions.module.scss @@ -1,13 +1,25 @@ @import '~@fluentui/react/dist/sass/References.scss'; -html[dir='ltr'] .termSuggestionContainer +html[dir='ltr'] { - text-align: left; + .termSuggestionContainer + { + text-align: left; + } + .termSynonymList { + padding-left: 0; + } } -html[dir='rtl'] .termSuggestionContainer +html[dir='rtl'] { - text-align: right; + .termSuggestionContainer + { + text-align: right; + } + .termSynonymList { + padding-right: 0; + } } .termSuggestionContainer @@ -17,10 +29,34 @@ html[dir='rtl'] .termSuggestionContainer padding-right: 12px; padding-bottom: 7px; - .termSuggestionPath + .termSuggestionPath, + .termSynonymList { font-size: 12px; color: #666666; } + .termSynonymList + { + color: #605e5c; + font-size: var(--ms-fonts-medium-fontSize, 14px); + list-style: none; + margin-block-start: 2px; + margin-top: 2px; + > li + { + &::before + { + content: '•'; + font-size: 11px; + padding-left: 4px; + } + + > span.synonymPrefix + { + font-weight: 600; + } + } + } + } diff --git a/src/controls/treeView/TreeItem.tsx b/src/controls/treeView/TreeItem.tsx index a0307e994..1deaacd3e 100644 --- a/src/controls/treeView/TreeItem.tsx +++ b/src/controls/treeView/TreeItem.tsx @@ -198,7 +198,7 @@ export default class TreeItem extends React.Component - +   } diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 07047eb51..48bc0ac7e 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -1 +1,2 @@ export * from './useTeams'; +export * from './useGroups'; diff --git a/src/hooks/useGroups.ts b/src/hooks/useGroups.ts new file mode 100644 index 000000000..6ae54e31a --- /dev/null +++ b/src/hooks/useGroups.ts @@ -0,0 +1,51 @@ +import { ServiceScope } from "@microsoft/sp-core-library"; +import { MSGraphClientFactory, MSGraphClientV3 } from "@microsoft/sp-http"; +import { PageContext } from "@microsoft/sp-page-context"; +import React from "react"; +import { IGroup } from "../common/model/IGroup"; + +const escapeFilterValue = (value: string): string => + value.replace(/'/g, "''"); + +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export const useGroups = (serviceScope: ServiceScope) => { + const _pageContext = React.useRef(); + const _msgGraphClient = React.useRef(); + + const init = React.useCallback(async () => { + _pageContext.current = serviceScope.consume(PageContext.serviceKey); + _msgGraphClient.current = await serviceScope + .consume(MSGraphClientFactory.serviceKey) + .getClient("3"); + }, [serviceScope]); + + const getGroups = React.useCallback( + async (filter?: string): Promise => { + await init(); + if (!_msgGraphClient.current) return []; + + const api = _msgGraphClient.current + .api("/groups") + .select( + "id,displayName,description,groupTypes,mailEnabled,mail,securityEnabled,visibility,resourceProvisioningOptions" + ); + + if (filter) { + api.filter( + `startswith(toupper(displayName),toupper('${escapeFilterValue( + filter + )}'))` + ); + } + + const groupResults = await api.get(); + return groupResults.value as IGroup[]; + }, + [init] + ); + + return { + init, + getGroups, + }; +}; diff --git a/src/index.ts b/src/index.ts index 4d12a69c4..37114e389 100644 --- a/src/index.ts +++ b/src/index.ts @@ -47,3 +47,4 @@ export * from './MonacoEditor'; export * from './UploadFiles'; export * from './ShareDialog'; export * from './Calendar'; +export * from './GroupPicker'; diff --git a/src/loc/bg-bg.ts b/src/loc/bg-bg.ts index 53d862346..823a65c2b 100644 --- a/src/loc/bg-bg.ts +++ b/src/loc/bg-bg.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Предложени екипни канали", "TeamPickerButtonRemoveTitle": "махам", "TeamPickernoResultsFoundText": "Не са намерени Екипи", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Предложени екипи", "TeamsChannelPickerButtonRemoveTitle": "махам", "TeamsChannelPickerNoresultsFoundText": "Няма намерени канали", diff --git a/src/loc/ca-es.ts b/src/loc/ca-es.ts index 0c822b46d..d28ca88ee 100644 --- a/src/loc/ca-es.ts +++ b/src/loc/ca-es.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Canals d'equip suggerits", "TeamPickerButtonRemoveTitle": "treure", "TeamPickernoResultsFoundText": "No s'ha trobat cap equip", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Equips suggerits", "TeamsChannelPickerButtonRemoveTitle": "treure", "TeamsChannelPickerNoresultsFoundText": "No s'ha trobat cap canal", diff --git a/src/loc/cs-cz.ts b/src/loc/cs-cz.ts index b61ae41ab..149ff2192 100644 --- a/src/loc/cs-cz.ts +++ b/src/loc/cs-cz.ts @@ -395,6 +395,9 @@ define([], () => { TeamChannelPickerSugestionHeaderText: "Navrhované týmové kanály", TeamPickerButtonRemoveTitle: "odebrat", TeamPickernoResultsFoundText: "Žádné týmy nenalezeny", + GroupPickerSuggestionsHeaderText: "Suggested groups", + GroupPickerGroupTypeM365Label: "M365", + GroupPickerGroupTypeSecurityLabel: "Security", TeamPickerSugestionsHeaderText: "Navrhované týmy", TeamsChannelPickerButtonRemoveTitle: "odebrat", TeamsChannelPickerNoresultsFoundText: "Žádné kanály nenalezeny", diff --git a/src/loc/da-dk.ts b/src/loc/da-dk.ts index d2ca468aa..c3babe9c5 100644 --- a/src/loc/da-dk.ts +++ b/src/loc/da-dk.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Foreslåede teamkanaler", "TeamPickerButtonRemoveTitle": "fjerne", "TeamPickernoResultsFoundText": "Der blev ikke fundet nogen teams", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Foreslåede teams", "TeamsChannelPickerButtonRemoveTitle": "fjerne", "TeamsChannelPickerNoresultsFoundText": "Der blev ikke fundet nogen kanaler", diff --git a/src/loc/de-de.ts b/src/loc/de-de.ts index 852cd96ab..ba2c1f4c2 100644 --- a/src/loc/de-de.ts +++ b/src/loc/de-de.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Vorgeschlagene Teamkanäle", "TeamPickerButtonRemoveTitle": "entfernen", "TeamPickernoResultsFoundText": "Keine Teams gefunden", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Vorgeschlagene Teams", "TeamsChannelPickerButtonRemoveTitle": "entfernen", "TeamsChannelPickerNoresultsFoundText": "Keine Kanäle gefunden", diff --git a/src/loc/el-gr.ts b/src/loc/el-gr.ts index 23ca7be42..913bfd607 100644 --- a/src/loc/el-gr.ts +++ b/src/loc/el-gr.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Προτεινόμενα κανάλια ομάδας", "TeamPickerButtonRemoveTitle": "αφαιρώ", "TeamPickernoResultsFoundText": "Δεν βρέθηκαν ομάδες", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Προτεινόμενες ομάδες", "TeamsChannelPickerButtonRemoveTitle": "αφαιρώ", "TeamsChannelPickerNoresultsFoundText": "Δεν βρέθηκαν κανάλια", diff --git a/src/loc/en-us.ts b/src/loc/en-us.ts index 71ab214c4..703c2b76a 100644 --- a/src/loc/en-us.ts +++ b/src/loc/en-us.ts @@ -372,6 +372,9 @@ define([], () => { TeamChannelPickerSugestionHeaderText: "Suggested Team Channels", TeamPickerButtonRemoveTitle: "remove", TeamPickernoResultsFoundText: "No Teams found", + GroupPickerSuggestionsHeaderText: "Suggested groups", + GroupPickerGroupTypeM365Label: "M365", + GroupPickerGroupTypeSecurityLabel: "Security", TeamPickerSugestionsHeaderText: "Suggested Teams", TeamsChannelPickerButtonRemoveTitle: "remove", TeamsChannelPickerNoresultsFoundText: "No channels found", @@ -435,7 +438,7 @@ define([], () => { ImagePickerCancelLabel: "Cancel", ImagePickerPanelHeaderText: "Please select an image to use as a thumbnail", ImagePickerSharePointTabLabel: "SharePoint", - ImagePickerOneDriveTabLabel: "OnDrive", + ImagePickerOneDriveTabLabel: "OneDrive", ImagePickerStockImagesTabLabel: "Stock Images", ImagePickerUploadTabLabel: "Upload", ImagePickerDragFilesAccpted: "Accepted file types: .gif, .jpg, .jpeg, .png, .svg", @@ -443,7 +446,7 @@ define([], () => { ImagePickerDragFilesActive:"Drop Images here...", ImagePickerDragDropText: "Drag 'n' drop image files or click to select files, max files to upload in one go is 10", ImagePickerUploadLocationLabel: "Select upload location", - ImagePickerUploadLocationOndriveLabel: "OnDrive", + ImagePickerUploadLocationOndriveLabel: "OneDrive", ImagePickerUploadLocationSharePointLabel: "Current Site", ImagePickerRetryButtonLabel: "Retry", ImagePickerDeleteLabel: "Delete", diff --git a/src/loc/es-es.ts b/src/loc/es-es.ts index c3111d956..fd3a9aecf 100644 --- a/src/loc/es-es.ts +++ b/src/loc/es-es.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Canales de equipo sugeridos", "TeamPickerButtonRemoveTitle": "eliminar", "TeamPickernoResultsFoundText": "No se han encontrado equipos", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Equipos sugeridos", "TeamsChannelPickerButtonRemoveTitle": "eliminar", "TeamsChannelPickerNoresultsFoundText": "No se han encontrado canales", diff --git a/src/loc/et-ee.ts b/src/loc/et-ee.ts index 7e3973966..7b2fe0a74 100644 --- a/src/loc/et-ee.ts +++ b/src/loc/et-ee.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Soovitatud meeskonnakanalid", "TeamPickerButtonRemoveTitle": "Eemaldada", "TeamPickernoResultsFoundText": "Meeskondi ei leitud", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Soovitatud meeskonnad", "TeamsChannelPickerButtonRemoveTitle": "Eemaldada", "TeamsChannelPickerNoresultsFoundText": "Kanaleid ei leitud", diff --git a/src/loc/eu-es.ts b/src/loc/eu-es.ts index 3f182d253..df3188ce9 100644 --- a/src/loc/eu-es.ts +++ b/src/loc/eu-es.ts @@ -341,6 +341,9 @@ define([], () => { TeamChannelPickerSugestionHeaderText: "Suggested Team Channels", TeamPickerButtonRemoveTitle: "remove", TeamPickernoResultsFoundText: "No Teams found", + GroupPickerSuggestionsHeaderText: "Suggested groups", + GroupPickerGroupTypeM365Label: "M365", + GroupPickerGroupTypeSecurityLabel: "Security", TeamPickerSugestionsHeaderText: "Suggested Teams", TeamsChannelPickerButtonRemoveTitle: "remove", TeamsChannelPickerNoresultsFoundText: "No channels found", diff --git a/src/loc/fi-fi.ts b/src/loc/fi-fi.ts index 1018059f5..154a0216d 100644 --- a/src/loc/fi-fi.ts +++ b/src/loc/fi-fi.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Ehdotetut ryhmäkanavat", "TeamPickerButtonRemoveTitle": "poista", "TeamPickernoResultsFoundText": "Tiimejä ei löytynyt", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Ehdotetut tiimit", "TeamsChannelPickerButtonRemoveTitle": "poista", "TeamsChannelPickerNoresultsFoundText": "Kanavia ei löytynyt", diff --git a/src/loc/fr-ca.ts b/src/loc/fr-ca.ts index 258b20760..cb604eb47 100644 --- a/src/loc/fr-ca.ts +++ b/src/loc/fr-ca.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Canaux d’équipe suggérés", "TeamPickerButtonRemoveTitle": "supprimer", "TeamPickernoResultsFoundText": "Aucune équipe trouvée", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Équipes suggérées", "TeamsChannelPickerButtonRemoveTitle": "supprimer", "TeamsChannelPickerNoresultsFoundText": "Aucun canal trouvé", diff --git a/src/loc/fr-fr.ts b/src/loc/fr-fr.ts index fbef46a47..9cac71a8a 100644 --- a/src/loc/fr-fr.ts +++ b/src/loc/fr-fr.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Canaux d’équipe suggérés", "TeamPickerButtonRemoveTitle": "enlever", "TeamPickernoResultsFoundText": "Aucune équipe trouvée", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Équipes suggérées", "TeamsChannelPickerButtonRemoveTitle": "enlever", "TeamsChannelPickerNoresultsFoundText": "Aucun canal trouvé", diff --git a/src/loc/it-it.ts b/src/loc/it-it.ts index 43c7a4392..17b35d83e 100644 --- a/src/loc/it-it.ts +++ b/src/loc/it-it.ts @@ -367,6 +367,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Canali del team suggeriti", "TeamPickerButtonRemoveTitle": "togliere", "TeamPickernoResultsFoundText": "Nessuna squadra trovata", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Team suggeriti", "TeamsChannelPickerButtonRemoveTitle": "togliere", "TeamsChannelPickerNoresultsFoundText": "Nessun canale trovato", diff --git a/src/loc/ja-jp.ts b/src/loc/ja-jp.ts index 00ee196ba..d60c9e419 100644 --- a/src/loc/ja-jp.ts +++ b/src/loc/ja-jp.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "推奨されるチーム チャネル", "TeamPickerButtonRemoveTitle": "削除", "TeamPickernoResultsFoundText": "チームが見つかりません", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "推奨されるチーム", "TeamsChannelPickerButtonRemoveTitle": "削除", "TeamsChannelPickerNoresultsFoundText": "チャネルが見つかりません", diff --git a/src/loc/lt-lt.ts b/src/loc/lt-lt.ts index d4cb9f6d3..d13727410 100644 --- a/src/loc/lt-lt.ts +++ b/src/loc/lt-lt.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Siūlomi komandos kanalai", "TeamPickerButtonRemoveTitle": "šalinti", "TeamPickernoResultsFoundText": "Komandų nerasta", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Siūlomos komandos", "TeamsChannelPickerButtonRemoveTitle": "šalinti", "TeamsChannelPickerNoresultsFoundText": "Kanalų nerasta", diff --git a/src/loc/lv-lv.ts b/src/loc/lv-lv.ts index f170f1442..89f6444ca 100644 --- a/src/loc/lv-lv.ts +++ b/src/loc/lv-lv.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Ieteiktie grupas kanāli", "TeamPickerButtonRemoveTitle": "noņemt", "TeamPickernoResultsFoundText": "Nav atrasta neviena komanda", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Ieteicamās darba grupas", "TeamsChannelPickerButtonRemoveTitle": "noņemt", "TeamsChannelPickerNoresultsFoundText": "Nav atrasts neviens kanāls", diff --git a/src/loc/mystrings.d.ts b/src/loc/mystrings.d.ts index 8b1b3ff40..0ac20f4cb 100644 --- a/src/loc/mystrings.d.ts +++ b/src/loc/mystrings.d.ts @@ -60,6 +60,9 @@ declare interface IControlStrings { TeamPickerButtonRemoveTitle: string; TeamPickerSugestionsHeaderText: string; TeamPickernoResultsFoundText: string; + GroupPickerSuggestionsHeaderText: string; + GroupPickerGroupTypeM365Label: string; + GroupPickerGroupTypeSecurityLabel: string; TeamChannelPickerSugestionHeaderText: string; TeamsChannelPickerNoresultsFoundText: string; diff --git a/src/loc/nb-no.ts b/src/loc/nb-no.ts index bad4d1aa6..a7d4c0878 100644 --- a/src/loc/nb-no.ts +++ b/src/loc/nb-no.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Foreslåtte teamkanaler", "TeamPickerButtonRemoveTitle": "fjern", "TeamPickernoResultsFoundText": "Finner ingen team", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Foreslåtte team", "TeamsChannelPickerButtonRemoveTitle": "fjern", "TeamsChannelPickerNoresultsFoundText": "Finner ingen kanaler", diff --git a/src/loc/nl-nl.ts b/src/loc/nl-nl.ts index 50ea1a22e..e0d4792e0 100644 --- a/src/loc/nl-nl.ts +++ b/src/loc/nl-nl.ts @@ -367,6 +367,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Voorgestelde teamkanalen", "TeamPickerButtonRemoveTitle": "verwijderen", "TeamPickernoResultsFoundText": "Geen teams gevonden", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Voorgestelde teams", "TeamsChannelPickerButtonRemoveTitle": "verwijderen", "TeamsChannelPickerNoresultsFoundText": "Geen kanalen gevonden", diff --git a/src/loc/pl-pl.ts b/src/loc/pl-pl.ts index dc867ab17..1e6116525 100644 --- a/src/loc/pl-pl.ts +++ b/src/loc/pl-pl.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Sugerowane kanały zespołu", "TeamPickerButtonRemoveTitle": "usunąć", "TeamPickernoResultsFoundText": "Nie znaleziono zespołów", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Sugerowane zespoły", "TeamsChannelPickerButtonRemoveTitle": "usunąć", "TeamsChannelPickerNoresultsFoundText": "Nie znaleziono kanałów", diff --git a/src/loc/pt-br.ts b/src/loc/pt-br.ts index 853f29670..c0b664628 100644 --- a/src/loc/pt-br.ts +++ b/src/loc/pt-br.ts @@ -354,6 +354,9 @@ define([], () => { TeamChannelPickerSugestionHeaderText: "Canais de Equipa Sugeridos", TeamPickerButtonRemoveTitle: "remover", TeamPickernoResultsFoundText: "Nenhuma equipa encontrada", + GroupPickerSuggestionsHeaderText: "Suggested groups", + GroupPickerGroupTypeM365Label: "M365", + GroupPickerGroupTypeSecurityLabel: "Security", TeamPickerSugestionsHeaderText: "Equipas Sugeridas", TeamsChannelPickerButtonRemoveTitle: "remover", TeamsChannelPickerNoresultsFoundText: "Não há canais encontrados", diff --git a/src/loc/pt-pt.ts b/src/loc/pt-pt.ts index 802c225b3..cab375d44 100644 --- a/src/loc/pt-pt.ts +++ b/src/loc/pt-pt.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Canais de Equipa Sugeridos", "TeamPickerButtonRemoveTitle": "remover", "TeamPickernoResultsFoundText": "Nenhuma equipa encontrada", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Equipas Sugeridas", "TeamsChannelPickerButtonRemoveTitle": "remover", "TeamsChannelPickerNoresultsFoundText": "Não há canais encontrados", diff --git a/src/loc/ro-ro.ts b/src/loc/ro-ro.ts index 5f06c4a33..193d09237 100644 --- a/src/loc/ro-ro.ts +++ b/src/loc/ro-ro.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Canale de echipă sugerate", "TeamPickerButtonRemoveTitle": "depărta", "TeamPickernoResultsFoundText": "Nu s-au găsit echipe", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Echipe sugerate", "TeamsChannelPickerButtonRemoveTitle": "depărta", "TeamsChannelPickerNoresultsFoundText": "Nu s-au găsit canale", diff --git a/src/loc/ru-ru.ts b/src/loc/ru-ru.ts index bdd9bd67e..5747ce068 100644 --- a/src/loc/ru-ru.ts +++ b/src/loc/ru-ru.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Рекомендуемые каналы команды", "TeamPickerButtonRemoveTitle": "убирать", "TeamPickernoResultsFoundText": "Команды не найдены", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Рекомендуемые команды", "TeamsChannelPickerButtonRemoveTitle": "убирать", "TeamsChannelPickerNoresultsFoundText": "Каналы не найдены", diff --git a/src/loc/sk-sk.ts b/src/loc/sk-sk.ts index befe2ac81..33e52452c 100644 --- a/src/loc/sk-sk.ts +++ b/src/loc/sk-sk.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Navrhované tímové kanály", "TeamPickerButtonRemoveTitle": "odstrániť", "TeamPickernoResultsFoundText": "Nenašli sa žiadne tímy", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Navrhované tímy", "TeamsChannelPickerButtonRemoveTitle": "odstrániť", "TeamsChannelPickerNoresultsFoundText": "Nenašli sa žiadne kanály", diff --git a/src/loc/sr-latn-rs.ts b/src/loc/sr-latn-rs.ts index e6f1d6cbd..6fd771117 100644 --- a/src/loc/sr-latn-rs.ts +++ b/src/loc/sr-latn-rs.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Predloženi kanali tima", "TeamPickerButtonRemoveTitle": "Uklonite", "TeamPickernoResultsFoundText": "Nije pronađen nijedan tim", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Predloženi timovi", "TeamsChannelPickerButtonRemoveTitle": "Uklonite", "TeamsChannelPickerNoresultsFoundText": "Nisu pronađeni kanali", diff --git a/src/loc/sv-se.ts b/src/loc/sv-se.ts index bd70ed2ac..3f90b5277 100644 --- a/src/loc/sv-se.ts +++ b/src/loc/sv-se.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Föreslagna teamkanaler", "TeamPickerButtonRemoveTitle": "avlägsna", "TeamPickernoResultsFoundText": "Inga team hittades", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Föreslagna team", "TeamsChannelPickerButtonRemoveTitle": "ta bort", "TeamsChannelPickerNoresultsFoundText": "Inga kanaler hittades", diff --git a/src/loc/tr-tr.ts b/src/loc/tr-tr.ts index a59a0ba17..0e54af34e 100644 --- a/src/loc/tr-tr.ts +++ b/src/loc/tr-tr.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Önerilen Ekip Kanalları", "TeamPickerButtonRemoveTitle": "kaldırmak", "TeamPickernoResultsFoundText": "Takım bulunamadı", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Önerilen Takımlar", "TeamsChannelPickerButtonRemoveTitle": "kaldırmak", "TeamsChannelPickerNoresultsFoundText": "Kanal bulunamadı", diff --git a/src/loc/vi-vn.ts b/src/loc/vi-vn.ts index 4092705a7..2cd4421eb 100644 --- a/src/loc/vi-vn.ts +++ b/src/loc/vi-vn.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "Các kênh nhóm được đề xuất", "TeamPickerButtonRemoveTitle": "triệt", "TeamPickernoResultsFoundText": "Không tìm thấy đội", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "Các đội được đề xuất", "TeamsChannelPickerButtonRemoveTitle": "triệt", "TeamsChannelPickerNoresultsFoundText": "Không tìm thấy kênh", diff --git a/src/loc/zh-cn.ts b/src/loc/zh-cn.ts index 45a264346..14b12e944 100644 --- a/src/loc/zh-cn.ts +++ b/src/loc/zh-cn.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "推荐的团队频道", "TeamPickerButtonRemoveTitle": "删除", "TeamPickernoResultsFoundText": "未找到团队", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "推荐的团队", "TeamsChannelPickerButtonRemoveTitle": "删除", "TeamsChannelPickerNoresultsFoundText": "未找到频道", diff --git a/src/loc/zh-tw.ts b/src/loc/zh-tw.ts index a768213be..db9e72d07 100644 --- a/src/loc/zh-tw.ts +++ b/src/loc/zh-tw.ts @@ -369,6 +369,9 @@ define([], () => { "TeamChannelPickerSugestionHeaderText": "推薦的團隊頻道", "TeamPickerButtonRemoveTitle": "刪除", "TeamPickernoResultsFoundText": "未找到團隊", + "GroupPickerSuggestionsHeaderText": "Suggested groups", + "GroupPickerGroupTypeM365Label": "M365", + "GroupPickerGroupTypeSecurityLabel": "Security", "TeamPickerSugestionsHeaderText": "推薦的團隊", "TeamsChannelPickerButtonRemoveTitle": "刪除", "TeamsChannelPickerNoresultsFoundText": "未找到頻道", diff --git a/src/webparts/controlsTest/ControlsTestWebPart.manifest.json b/src/webparts/controlsTest/ControlsTestWebPart.manifest.json index 77ef97d9e..baaa78f8e 100644 --- a/src/webparts/controlsTest/ControlsTestWebPart.manifest.json +++ b/src/webparts/controlsTest/ControlsTestWebPart.manifest.json @@ -52,6 +52,7 @@ "FileTypeIcon": false, "FolderExplorer": false, "FolderPicker": false, + "GroupPicker": false, "GridLayout": false, "HoverReactionsBar": false, "IconPicker": false, diff --git a/src/webparts/controlsTest/IControlsTestWebPartProps.ts b/src/webparts/controlsTest/IControlsTestWebPartProps.ts index 0028b81c8..a450251ad 100644 --- a/src/webparts/controlsTest/IControlsTestWebPartProps.ts +++ b/src/webparts/controlsTest/IControlsTestWebPartProps.ts @@ -5,6 +5,7 @@ export type ValidControls = "all" | "DragDropFiles" | "DynamicForm" | "EnhancedThemeProvider" | "FieldCollectionData" | "FieldPicker" | "FilePicker" | "FileTypeIcon" | "FilterBar" | "FolderExplorer" | "FolderPicker" | + "GroupPicker" | "GridLayout" | "HoverReactionsBar" | "IconPicker" | "IFrameDialog" | "IFramePanel" | "ImagePicker" | "ListItemAttachments" | "ListItemComments" | "ListItemPicker" | "ListPicker" | "ListView" | "LivePersona" | diff --git a/src/webparts/controlsTest/components/ControlsTest.tsx b/src/webparts/controlsTest/components/ControlsTest.tsx index 9577941ce..091d4860c 100644 --- a/src/webparts/controlsTest/components/ControlsTest.tsx +++ b/src/webparts/controlsTest/components/ControlsTest.tsx @@ -233,6 +233,7 @@ const FolderExplorer = React.lazy(() => import('../../../FolderExplorer').then(m const FolderPicker = React.lazy(() => import('../../../FolderPicker').then(module => ({ default: module.FolderPicker }))); const GridLayout = React.lazy(() => import('../../../GridLayout').then(module => ({ default: module.GridLayout }))); const HoverReactionsBar = React.lazy(() => import('../../../HoverReactionsBar').then(module => ({ default: module.HoverReactionsBar }))); +const GroupPicker = React.lazy(() => import('../../../GroupPicker').then(module => ({ default: module.GroupPicker }))); const IFrameDialog = React.lazy>(() => import('../../../IFrameDialog').then(module => ({ default: module.IFrameDialog }))); @@ -617,6 +618,7 @@ export default class ControlsTest extends React.Component
} + {controlVisibility.GroupPicker && +
+ { + this.setState({ selectedGroups: tagList }); + }} + groupType="M365" + themeVariant={this.props.themeVariant} + /> +
+ } {controlVisibility.DragDropFiles &&
Drag and Drop Files diff --git a/src/webparts/controlsTest/components/IControlsTestState.ts b/src/webparts/controlsTest/components/IControlsTestState.ts index 11df740a3..266b6d303 100644 --- a/src/webparts/controlsTest/components/IControlsTestState.ts +++ b/src/webparts/controlsTest/components/IControlsTestState.ts @@ -33,6 +33,7 @@ export interface IControlsTestState { showErrorDialog?: boolean; selectedTeam: ITag[]; selectedTeamChannels: ITag[]; + selectedGroups?: ITag[]; filePickerDefaultFolderAbsolutePath?: string; errorMessage?: string; termPanelIsOpen?: boolean; diff --git a/src/webparts/controlsTest/propertyPane/controls/ControlToggles.tsx b/src/webparts/controlsTest/propertyPane/controls/ControlToggles.tsx index a06c5aeca..a095ef00f 100644 --- a/src/webparts/controlsTest/propertyPane/controls/ControlToggles.tsx +++ b/src/webparts/controlsTest/propertyPane/controls/ControlToggles.tsx @@ -57,7 +57,7 @@ export class ControlToggles extends React.Component