Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial GraphPresenter prototype for #17 #18

Merged
merged 24 commits into from
Aug 11, 2020
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8988341
Initial GraphPresenter prototype for #17
michael-hawker Oct 20, 2019
268fdff
Merge branch 'master' into michael-hawker/graph-presenter
michael-hawker Jun 25, 2020
f6b6a0d
Update Example to use ImageEx to show something for files with no images
michael-hawker Jun 25, 2020
eedfc14
Update link to issue filed in Graph for the API we're trying to use
michael-hawker Jun 25, 2020
7d43dd8
Update Missing Headers
michael-hawker Jun 29, 2020
3a844f8
Merge remote-tracking branch 'origin/main' into michael-hawker/graph-…
michael-hawker Jul 16, 2020
0c04921
[Broken] CalendarView Example
michael-hawker Jul 16, 2020
e5b3013
Add forgotten .NET Foundation Header
michael-hawker Jul 16, 2020
2a9e157
Add OrderBy property to GraphPresenter
michael-hawker Jul 16, 2020
6556c2d
Try updating dependencies
michael-hawker Jul 23, 2020
ff9ee75
Fix Stylecop Issues
michael-hawker Jul 26, 2020
dc8a641
Reconfigure Proxy to work in all cases and more effectively
michael-hawker Jul 27, 2020
b70e6b7
Better separate out Samples in UWP app
michael-hawker Jul 27, 2020
f028d3f
Add (Mail) Messages GraphPresenter sample
michael-hawker Jul 27, 2020
a4919fb
Add Task sample to GraphPresenter
michael-hawker Aug 6, 2020
7cdd34f
Add in Teams Messages example to GraphPresenter
michael-hawker Aug 6, 2020
b93e18c
Remove unused OneDrive sample Converters
michael-hawker Aug 8, 2020
97d4eba
Initial PR Feedback
michael-hawker Aug 9, 2020
6e71a13
Apply suggestions from code review
michael-hawker Aug 9, 2020
bdabc31
Apply last feedback comment from @Sergio0694
michael-hawker Aug 9, 2020
4a45671
Add extra scopes needed for InteractiveProvider for new samples
michael-hawker Aug 10, 2020
3cc9ec3
Update Microsoft.Toolkit.Graph/Providers/MockProvider.cs
michael-hawker Aug 11, 2020
f012a4e
Address PR comments
michael-hawker Aug 11, 2020
c2dd9ea
Update Microsoft.Toolkit.Graph.Controls/Controls/GraphPresenter/Query…
azchohfi Aug 11, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.Graph;
using Microsoft.Toolkit.Uwp.Helpers;
using Newtonsoft.Json.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Microsoft.Toolkit.Graph.Controls
{
/// <summary>
/// Specialized <see cref="ContentPresenter"/> to fetch and display data from the Microsoft Graph.
/// </summary>
public class GraphPresenter : ContentPresenter
{
/// <summary>
/// Gets or sets a <see cref="IBaseRequestBuilder"/> to be used to make a request to the graph. The results will be automatically populated to the <see cref="ContentPresenter.Content"/> property. Use a <see cref="ContentPresenter.ContentTemplate"/> to change the presentation of the data.
/// </summary>
public IBaseRequestBuilder RequestBuilder
{
get { return (IBaseRequestBuilder)GetValue(RequestBuilderProperty); }
set { SetValue(RequestBuilderProperty, value); }
}

/// <summary>
/// Identifies the <see cref="RequestBuilder"/> dependency property.
/// </summary>
/// <returns>
/// The identifier for the <see cref="RequestBuilder"/> dependency property.
/// </returns>
public static readonly DependencyProperty RequestBuilderProperty =
DependencyProperty.Register(nameof(RequestBuilder), typeof(IBaseRequestBuilder), typeof(GraphPresenter), new PropertyMetadata(null));
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Gets or sets the <see cref="Type"/> of item returned by the <see cref="RequestBuilder"/>.
/// Set to the base item type and use the <see cref="IsCollection"/> property to indicate if a collection is expected back.
/// </summary>
public Type ResponseType { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the returned data from the <see cref="RequestBuilder"/> is a collection.
/// </summary>
public bool IsCollection { get; set; }

/// <summary>
/// Gets or sets list of <see cref="QueryOption"/> representing <see cref="Microsoft.Graph.QueryOption"/> values to pass into the request built by <see cref="RequestBuilder"/>.
/// </summary>
public List<QueryOption> QueryOptions { get; set; } = new List<QueryOption>();

/// <summary>
/// Gets or sets a string to indicate a sorting order for the <see cref="RequestBuilder"/>. This is a helper to add this specific request option to the <see cref="QueryOptions"/>.
/// </summary>
public string OrderBy { get; set; }
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Initializes a new instance of the <see cref="GraphPresenter"/> class.
/// </summary>
public GraphPresenter()
{
Loaded += GraphPresenter_Loaded;
}

private async void GraphPresenter_Loaded(object sender, RoutedEventArgs e)
{
// Note: some interfaces from the Graph SDK don't implement IBaseRequestBuilder properly, see https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/722
if (RequestBuilder != null)
{
var request = new BaseRequest(
RequestBuilder.RequestUrl,
RequestBuilder.Client); // TODO: Do we need separate Options here?
request.Method = "GET";
request.QueryOptions = QueryOptions?.Select(option => (Microsoft.Graph.QueryOption)option)?.ToList() ?? new List<Microsoft.Graph.QueryOption>();

// Handle Special QueryOptions
if (!string.IsNullOrWhiteSpace(OrderBy))
{
request.QueryOptions.Add(new Microsoft.Graph.QueryOption("$orderby", OrderBy));
}

try
{
var response = await request.SendAsync<object>(null, CancellationToken.None).ConfigureAwait(false) as JObject;

//// TODO: Deal with paging?

var values = response["value"];
object data = null;

if (IsCollection)
{
data = values.ToObject(Array.CreateInstance(ResponseType, 0).GetType());
}
else
{
data = values.ToObject(ResponseType);
}

_ = DispatcherHelper.ExecuteOnUIThreadAsync(() => Content = data);
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
}
catch
{
// TODO: We should figure out what we want to do for Loading/Error states here.
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;

namespace Microsoft.Toolkit.Graph.Controls
{
/// <summary>
/// XAML Proxy for <see cref="Microsoft.Graph.QueryOption"/>.
/// </summary>
public sealed class QueryOption
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
{
/// <inheritdoc cref="Microsoft.Graph.Option.Name"/>
public string Name { get; set; }

/// <inheritdoc cref="Microsoft.Graph.Option.Value"/>
public string Value { get; set; }

/// <summary>
/// Implicit conversion for <see cref="QueryOption"/> to <see cref="Microsoft.Graph.QueryOption"/>.
/// </summary>
/// <param name="option">query option to convert</param>
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
public static implicit operator Microsoft.Graph.QueryOption(QueryOption option)
{
return new Microsoft.Graph.QueryOption(option.Name, option.Value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<PackageTags>UWP Toolkit Windows Controls MSAL Microsoft Graph AadLogin ProfileCard Person PeoplePicker Login</PackageTags>
<SignAssembly>false</SignAssembly>
<GenerateLibraryLayout>true</GenerateLibraryLayout>
<LangVersion>8.0</LangVersion>
<Configurations>Debug;Release;CI</Configurations>
<Platforms>AnyCPU;ARM;ARM64;x64;x86</Platforms>
</PropertyGroup>
Expand All @@ -34,8 +35,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Graph.Beta" Version="0.18.0-preview" />
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.4" />
<PackageReference Include="Microsoft.Graph.Beta" Version="0.19.0-preview" />
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.5" />
</ItemGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions Microsoft.Toolkit.Graph/Extensions/GraphExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Graph;
Expand Down
4 changes: 2 additions & 2 deletions Microsoft.Toolkit.Graph/Microsoft.Toolkit.Graph.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Graph.Beta" Version="0.18.0-preview" />
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.4" />
<PackageReference Include="Microsoft.Graph.Beta" Version="0.19.0-preview" />
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.5" />
<PackageReference Include="Microsoft.Toolkit" Version="6.1.0" />
</ItemGroup>
</Project>
27 changes: 11 additions & 16 deletions Microsoft.Toolkit.Graph/Providers/MockProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ namespace Microsoft.Toolkit.Graph.Providers
/// </summary>
public class MockProvider : IProvider
{
private const string GRAPH_PROXY_URL = "https://proxy.apisandbox.msdn.microsoft.com/svc?url=";

private ProviderState _state = ProviderState.Loading;

/// <inheritdoc/>
Expand All @@ -42,22 +44,15 @@ private set

/// <inheritdoc/>
public GraphServiceClient Graph => new GraphServiceClient(
"https://proxy.apisandbox.msdn.microsoft.com/svc?url=" + HttpUtility.HtmlEncode("https://graph.microsoft.com/beta/"),
new DelegateAuthenticationProvider((requestMessage) =>
{
//// Temporary Workaround for https://github.com/microsoftgraph/msgraph-sdk-dotnet-core/issues/59
//// ------------------------
var requestUri = requestMessage.RequestUri.ToString();
var index = requestUri.IndexOf("&");
if (index >= 0)
{
requestMessage.RequestUri = new Uri(requestUri.Remove(index, 1).Insert(index, "?"));
}

//// End Workaround

return this.AuthenticateRequestAsync(requestMessage);
}));
new DelegateAuthenticationProvider((requestMessage) =>
{
var requestUri = requestMessage.RequestUri.ToString();

// Prepend Proxy Service URI to our request
requestMessage.RequestUri = new Uri(GRAPH_PROXY_URL + Uri.EscapeDataString(requestUri));

return this.AuthenticateRequestAsync(requestMessage);
}));

/// <inheritdoc/>
public event EventHandler<StateChangedEventArgs> StateChanged;
Expand Down
11 changes: 10 additions & 1 deletion Microsoft.Toolkit.Graph/Providers/ProviderManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
// See the LICENSE file in the project root for more information.

using System;
using System.ComponentModel;
using Microsoft.Graph;
using Microsoft.Identity.Client;
using Microsoft.Toolkit.Helpers;

namespace Microsoft.Toolkit.Graph.Providers
{
Expand All @@ -14,7 +18,7 @@ namespace Microsoft.Toolkit.Graph.Providers
/// ProviderManager.Instance.GlobalProvider = await MsalProvider.CreateAsync(...);
/// </code>
/// </example>
public class ProviderManager
public class ProviderManager : INotifyPropertyChanged
{
/// <summary>
/// Gets the name of the toolkit client to identify self in Graph calls.
Expand All @@ -31,6 +35,9 @@ public class ProviderManager
/// </summary>
public event EventHandler<ProviderUpdatedEventArgs> ProviderUpdated;

/// <inheritdoc/>
public event PropertyChangedEventHandler PropertyChanged;

private IProvider _provider;

/// <summary>
Expand Down Expand Up @@ -58,6 +65,8 @@ public IProvider GlobalProvider
}

ProviderUpdated?.Invoke(this, new ProviderUpdatedEventArgs(ProviderManagerChangedState.ProviderChanged));

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(GlobalProvider)));
}
}

Expand Down
Binary file added SampleTest/Assets/FileIcon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading