Skip to content

Commit 01441bb

Browse files
committed
Merge branch 'master' into winui
2 parents 3c2f904 + 67c6527 commit 01441bb

File tree

17 files changed

+119
-154
lines changed

17 files changed

+119
-154
lines changed

Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
4848
</PropertyGroup>
4949
<ItemGroup>
50-
<PackageReference Include="Microsoft.SourceLink.Vsts.Git" Version="1.0.0-beta-62925-02" PrivateAssets="All"/>
50+
<PackageReference Include="Microsoft.SourceLink.AzureRepos.Git" Version="1.0.0" PrivateAssets="All"/>
5151
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
5252
</ItemGroup>
5353
</When>

Microsoft.Toolkit.Graph.Controls/Controls/LoginButton/LoginButton.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ public async Task LoginAsync()
185185
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
186186
public async Task LogoutAsync()
187187
{
188+
// Close Menu
189+
if (FlyoutBase.GetAttachedFlyout(_loginButton) is FlyoutBase flyout)
190+
{
191+
flyout.Hide();
192+
}
193+
188194
if (IsLoading)
189195
{
190196
return;
@@ -217,12 +223,6 @@ public async Task LogoutAsync()
217223

218224
LogoutCompleted?.Invoke(this, new EventArgs());
219225
}
220-
221-
// Close Menu
222-
if (FlyoutBase.GetAttachedFlyout(_loginButton) is FlyoutBase flyout)
223-
{
224-
flyout.Hide();
225-
}
226226
}
227227
}
228228
}

Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.Properties.cs

-53
This file was deleted.

Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.cs

+39-41
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Collections;
7+
using System.Collections.ObjectModel;
68
using System.Linq;
79
using Microsoft.Graph;
810
using Microsoft.Toolkit.Graph.Extensions;
@@ -17,13 +19,8 @@ namespace Microsoft.Toolkit.Graph.Controls
1719
/// <summary>
1820
/// Control which allows user to search for a person or contact within Microsoft Graph. Built on top of <see cref="TokenizingTextBox"/>.
1921
/// </summary>
20-
[TemplatePart(Name = PeoplePickerTokenizingTextBoxName, Type = typeof(TokenizingTextBox))]
21-
public partial class PeoplePicker : Control
22+
public partial class PeoplePicker : TokenizingTextBox
2223
{
23-
private const string PeoplePickerTokenizingTextBoxName = "PART_TokenizingTextBox";
24-
25-
private TokenizingTextBox _tokenBox;
26-
2724
private DispatcherTimer _typeTimer = new DispatcherTimer();
2825

2926
/// <summary>
@@ -32,26 +29,11 @@ public partial class PeoplePicker : Control
3229
public PeoplePicker()
3330
{
3431
this.DefaultStyleKey = typeof(PeoplePicker);
35-
}
36-
37-
/// <inheritdoc/>
38-
protected override void OnApplyTemplate()
39-
{
40-
base.OnApplyTemplate();
4132

42-
if (_tokenBox != null)
43-
{
44-
_tokenBox.TextChanged -= TokenBox_TextChanged;
45-
_tokenBox.TokenItemAdding -= TokenBox_TokenItemTokenItemAdding;
46-
}
47-
48-
_tokenBox = GetTemplateChild(PeoplePickerTokenizingTextBoxName) as TokenizingTextBox;
33+
SuggestedItemsSource = new ObservableCollection<Person>();
4934

50-
if (_tokenBox != null)
51-
{
52-
_tokenBox.TextChanged += TokenBox_TextChanged;
53-
_tokenBox.TokenItemAdding += TokenBox_TokenItemTokenItemAdding;
54-
}
35+
TextChanged += TokenBox_TextChanged;
36+
TokenItemAdding += TokenBox_TokenItemTokenItemAdding;
5537
}
5638

5739
private async void TokenBox_TokenItemTokenItemAdding(TokenizingTextBox sender, TokenItemAddingEventArgs args)
@@ -85,33 +67,49 @@ private void TokenBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChang
8567
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
8668
{
8769
var text = sender.Text;
88-
_typeTimer.Debounce(
89-
async () =>
70+
var list = SuggestedItemsSource as IList;
71+
72+
if (list != null)
9073
{
91-
var graph = ProviderManager.Instance.GlobalProvider.Graph;
92-
if (graph != null)
74+
_typeTimer.Debounce(
75+
async () =>
9376
{
94-
// If empty, clear out
95-
if (string.IsNullOrWhiteSpace(text))
96-
{
97-
SuggestedPeople.Clear();
98-
}
99-
else
77+
var graph = ProviderManager.Instance.GlobalProvider.Graph;
78+
if (graph != null)
10079
{
101-
SuggestedPeople.Clear();
80+
// If empty, will clear out
81+
list.Clear();
10282

103-
foreach (var contact in (await graph.FindPersonAsync(text)).CurrentPage)
83+
if (!string.IsNullOrWhiteSpace(text))
10484
{
105-
if (!_tokenBox.Items.Any(person => (person as Person)?.Id == contact.Id))
85+
foreach (var user in (await graph.FindUserAsync(text)).CurrentPage)
10686
{
107-
SuggestedPeople.Add(contact);
87+
// Exclude people in suggested list that we already have picked
88+
if (!Items.Any(person => (person as Person)?.Id == user.Id))
89+
{
90+
list.Add(user.ToPerson());
91+
}
92+
}
93+
94+
// Grab ids of current suggestions
95+
var ids = list.Cast<object>().Select(person => (person as Person).Id);
96+
97+
foreach (var contact in (await graph.FindPersonAsync(text)).CurrentPage)
98+
{
99+
// Exclude people in suggested list that we already have picked
100+
// Or already suggested
101+
if (!Items.Any(person => (person as Person)?.Id == contact.Id) &&
102+
!ids.Any(id => id == contact.Id))
103+
{
104+
list.Add(contact);
105+
}
108106
}
109107
}
110108
}
111-
}
112109

113-
// TODO: If we don't have Graph connection and just list of Person should we auto-filter here?
114-
}, TimeSpan.FromSeconds(0.3));
110+
// TODO: If we don't have Graph connection and just list of Person should we auto-filter here?
111+
}, TimeSpan.FromSeconds(0.3));
112+
}
115113
}
116114
}
117115
}

Microsoft.Toolkit.Graph.Controls/Controls/PeoplePicker/PeoplePicker.xaml

+26-28
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,34 @@
22
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
xmlns:local="using:Microsoft.Toolkit.Graph.Controls"
5-
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls">
5+
xmlns:ex="using:Microsoft.Toolkit.Uwp.UI.Extensions">
6+
<ResourceDictionary.MergedDictionaries>
7+
<ResourceDictionary Source="ms-appx:///Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.xaml" />
8+
</ResourceDictionary.MergedDictionaries>
69

7-
<Style TargetType="local:PeoplePicker">
8-
<Setter Property="Template">
10+
<Style TargetType="local:PeoplePicker" BasedOn="{StaticResource DefaultPeoplePickerStyle}"/>
11+
12+
<Style x:Key="DefaultPeoplePickerStyle" TargetType="local:PeoplePicker" BasedOn="{StaticResource DefaultTokenizingTextBoxStyle}">
13+
<Setter Property="QueryIcon">
14+
<Setter.Value>
15+
<SymbolIconSource Symbol="Find"/>
16+
</Setter.Value>
17+
</Setter>
18+
<Setter Property="PlaceholderText" Value="Start typing a name"/>
19+
<Setter Property="TextMemberPath" Value="DisplayName"/>
20+
<Setter Property="TokenDelimiter" Value=","/>
21+
<Setter Property="SuggestedItemTemplate">
22+
<Setter.Value>
23+
<DataTemplate>
24+
<local:PersonView PersonDetails="{Binding}" ShowName="True" ShowEmail="True"/>
25+
</DataTemplate>
26+
</Setter.Value>
27+
</Setter>
28+
<Setter Property="TokenItemTemplate">
929
<Setter.Value>
10-
<ControlTemplate TargetType="local:PeoplePicker">
11-
<Border
12-
Background="{TemplateBinding Background}"
13-
BorderBrush="{TemplateBinding BorderBrush}"
14-
BorderThickness="{TemplateBinding BorderThickness}">
15-
<controls:TokenizingTextBox
16-
x:Name="PART_TokenizingTextBox"
17-
QueryIcon="Find"
18-
PlaceholderText="Start typing a name"
19-
TextMemberPath="DisplayName"
20-
TokenDelimiter=","
21-
SuggestedItemsSource="{TemplateBinding SuggestedPeople}">
22-
<controls:TokenizingTextBox.SuggestedItemTemplate>
23-
<DataTemplate>
24-
<local:PersonView PersonDetails="{Binding}" ShowName="True" ShowEmail="True"/>
25-
</DataTemplate>
26-
</controls:TokenizingTextBox.SuggestedItemTemplate>
27-
<controls:TokenizingTextBox.TokenItemTemplate>
28-
<DataTemplate>
29-
<local:PersonView PersonDetails="{Binding}" ShowName="True"/>
30-
</DataTemplate>
31-
</controls:TokenizingTextBox.TokenItemTemplate>
32-
</controls:TokenizingTextBox>
33-
</Border>
34-
</ControlTemplate>
30+
<DataTemplate>
31+
<local:PersonView PersonDetails="{Binding}" ShowName="True"/>
32+
</DataTemplate>
3533
</Setter.Value>
3634
</Setter>
3735
</Style>

Microsoft.Toolkit.Graph.Controls/Microsoft.Toolkit.Graph.Controls.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@
5454
</ItemGroup>
5555

5656
<ItemGroup>
57-
<PackageReference Include="Microsoft.Graph.Beta" Version="0.8.0-preview" />
58-
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.2" />
57+
<PackageReference Include="Microsoft.Graph.Beta" Version="0.18.0-preview" />
58+
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.4" />
5959
</ItemGroup>
6060

6161
<ItemGroup>

Microsoft.Toolkit.Graph.Controls/Providers/QuickCreate.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace Microsoft.Toolkit.Graph.Providers
1818
//// TODO: Need to set up XAML Islands sample to test in the new repo and make sure this works from this context.
1919

2020
/// <summary>
21-
/// Helper class for XAML Islands to easily initialize provider from just ClientId from within WPF context.
21+
/// Helper class to easily initialize provider from just ClientId.
2222
/// </summary>
2323
public static class QuickCreate
2424
{

Microsoft.Toolkit.Graph/Extensions/GraphExtensions.cs

+25-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public static Person ToPerson(this User user)
5252
/// </summary>
5353
/// <param name="graph">Instance of the <see cref="GraphServiceClient"/>.</param>
5454
/// <param name="query">User to search for.</param>
55-
/// <returns><see cref="IUserPeopleCollectionPage"/> collection of <see cref="User"/>.</returns>
55+
/// <returns><see cref="IUserPeopleCollectionPage"/> collection of <see cref="Person"/>.</returns>
5656
public static async Task<IUserPeopleCollectionPage> FindPersonAsync(this GraphServiceClient graph, string query)
5757
{
5858
try
@@ -72,6 +72,30 @@ public static async Task<IUserPeopleCollectionPage> FindPersonAsync(this GraphSe
7272
return new UserPeopleCollectionPage();
7373
}
7474

75+
/// <summary>
76+
/// Shortcut to perform a user query.
77+
/// </summary>
78+
/// <param name="graph">Instance of the <see cref="GraphServiceClient"/>.</param>
79+
/// <param name="query">User to search for.</param>
80+
/// <returns><see cref="IGraphServiceUsersCollectionPage"/> collection of <see cref="User"/>.</returns>
81+
public static async Task<IGraphServiceUsersCollectionPage> FindUserAsync(this GraphServiceClient graph, string query)
82+
{
83+
try
84+
{
85+
return await graph
86+
.Users
87+
.Request()
88+
.Filter($"startswith(displayName, '{query}') or startswith(givenName, '{query}') or startswith(surname, '{query}') or startswith(mail, '{query}') or startswith(userPrincipalName, '{query}')")
89+
.WithScopes(new string[] { "user.readbasic.all" })
90+
.GetAsync();
91+
}
92+
catch
93+
{
94+
}
95+
96+
return new GraphServiceUsersCollectionPage();
97+
}
98+
7599
/// <summary>
76100
/// Helper to get the photo of a particular user.
77101
/// </summary>

Microsoft.Toolkit.Graph/Microsoft.Toolkit.Graph.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
</PropertyGroup>
1313

1414
<ItemGroup>
15-
<PackageReference Include="Microsoft.Graph.Beta" Version="0.8.0-preview" />
16-
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.2" />
15+
<PackageReference Include="Microsoft.Graph.Beta" Version="0.18.0-preview" />
16+
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.4" />
1717
<PackageReference Include="Microsoft.Toolkit" Version="8.0.0-preview1" />
1818
</ItemGroup>
1919
</Project>

Microsoft.Toolkit.Graph/Providers/ProviderManager.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6-
using Microsoft.Graph;
7-
using Microsoft.Identity.Client;
8-
using Microsoft.Toolkit.Helpers;
96

107
namespace Microsoft.Toolkit.Graph.Providers
118
{
@@ -27,7 +24,7 @@ public class ProviderManager
2724
/// <summary>
2825
/// Gets the instance of the GlobalProvider.
2926
/// </summary>
30-
public static ProviderManager Instance => Singleton<ProviderManager>.Instance;
27+
public static ProviderManager Instance { get; } = new ProviderManager();
3128

3229
/// <summary>
3330
/// Event called when the <see cref="IProvider"/> changes.
@@ -64,6 +61,11 @@ public IProvider GlobalProvider
6461
}
6562
}
6663

64+
private ProviderManager()
65+
{
66+
// Use Instance
67+
}
68+
6769
private void ProviderStateChanged(object sender, StateChangedEventArgs e)
6870
{
6971
ProviderUpdated?.Invoke(this, new ProviderUpdatedEventArgs(ProviderManagerChangedState.ProviderStateChanged));

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ If you need similar controls for the Web, please use the [Microsoft Graph Toolki
1818

1919
Before using controls that access [Microsoft Graph](https://graph.microsoft.com), you will need to [register your application](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) to get a **ClientID**.
2020

21-
> After finishing the initial registration page, you will also need to add an additional redirect URI. Clcik on "Add a Redirect URI" and check the `https://login.microsoftonline.com/common/oauth2/nativeclient` checkbox on that page. Then click "Save".
21+
> After finishing the initial registration page, you will also need to add an additional redirect URI. Click on "Add a Redirect URI", then "Add a platform", and then on "Mobile and desktop applications". Check the `https://login.microsoftonline.com/common/oauth2/nativeclient` checkbox on that page. Then click "Configure".
2222
2323
### UWP Quick Start
2424

0 commit comments

Comments
 (0)