Skip to content

Commit

Permalink
Merge pull request #2 from EasyOC/UserPickerField
Browse files Browse the repository at this point in the history
User picker field
  • Loading branch information
hyzx86 authored Mar 19, 2024
2 parents 9541a11 + cd0d788 commit 1f58aa3
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public override void ConfigureServices(IServiceCollection services)
services.AddObjectGraphType<LinkField, LinkFieldQueryObjectType>();
services.AddObjectGraphType<HtmlField, HtmlFieldQueryObjectType>();
services.AddObjectGraphType<ContentPickerField, ContentPickerFieldQueryObjectType>();
services.AddObjectGraphType<UserPickerField, UserPickerFieldQueryObjectType>();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System.Collections.Generic;
using System.Linq;
using GraphQL;
using GraphQL.DataLoader;
using GraphQL.Types;
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.Apis.GraphQL;
using OrchardCore.ContentFields.Fields;
using OrchardCore.ContentManagement;
using OrchardCore.Users.GraphQL;
using OrchardCore.Users.Indexes;
using OrchardCore.Users.Models;
using YesSql;
using YesSql.Services;

namespace OrchardCore.ContentFields.GraphQL
{
public class UserPickerFieldQueryObjectType : ObjectGraphType<UserPickerField>
{
public UserPickerFieldQueryObjectType(UserType userType)
{
Name = nameof(UserPickerField);

Field<ListGraphType<StringGraphType>, IEnumerable<string>>("userIds")
.Description("user ids")
.PagingArguments()
.Resolve(x =>
{
return x.Page(x.Source.UserIds);
});

Field<ListGraphType<UserType>, IEnumerable<User>>("users")
.Type(new ListGraphType(userType))
.Description("the user items")
.PagingArguments()
.ResolveAsync(x =>
{
var userLoader = GetOrAddUserProfileByIdDataLoader(x);
return userLoader.LoadAsync(x.Page(x.Source.UserIds)).Then(itemResultSet =>
{
return itemResultSet.SelectMany(x => x);
});
});
Field<UserType, User>("user")
.Type(userType)
.Description("the first user")
.ResolveAsync(x =>
{
var userLoader = GetOrAddUserProfileByIdDataLoader(x);
return userLoader.LoadAsync(x.Source.UserIds.FirstOrDefault()).Then(itemResultSet =>
{
return itemResultSet.FirstOrDefault();
});
});
}

public static IDataLoader<string, IEnumerable<User>> GetOrAddUserProfileByIdDataLoader<T>(IResolveFieldContext<T> context)
{
IDataLoaderContextAccessor requiredService = context.RequestServices.GetRequiredService<IDataLoaderContextAccessor>();
var session = context.RequestServices.GetService<ISession>();
return requiredService.Context.GetOrAddCollectionBatchLoader("GetOrAddUserByIds", async (IEnumerable<string> userIds) =>
{
if (userIds == null || !userIds.Any())
{
return null;
}
var users = await session.Query<User, UserIndex>(y => y.UserId.IsIn(userIds)).ListAsync();

return users.ToLookup((User k) => k.UserId, (User user) => user);
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<ProjectReference Include="..\..\OrchardCore\OrchardCore.Shortcodes.Abstractions\OrchardCore.Shortcodes.Abstractions.csproj" />
<ProjectReference Include="..\..\OrchardCore\OrchardCore.ResourceManagement\OrchardCore.ResourceManagement.csproj" />
<ProjectReference Include="..\..\OrchardCore\OrchardCore.Users.Core\OrchardCore.Users.Core.csproj" />
<ProjectReference Include="..\OrchardCore.Users\OrchardCore.Users.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ public class Startup : StartupBase
public override void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ISchemaBuilder, CurrentUserQuery>();
services.AddTransient<UserType>();
services.AddScoped<UserType>();
}
}
36 changes: 20 additions & 16 deletions src/OrchardCore.Modules/OrchardCore.Users/GraphQL/UserType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using GraphQL.Types;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using OrchardCore.ContentManagement;
using OrchardCore.ContentManagement.GraphQL.Queries.Types;
using OrchardCore.ContentManagement.Metadata.Models;
using OrchardCore.Users.Models;
using OrchardCore.Users.Services;
Expand Down Expand Up @@ -30,27 +32,29 @@ public UserType(IStringLocalizer<UserType> localizer)
internal void AddField(ISchema schema, ContentTypeDefinition typeDefinition)
{
var contentItemType = schema.AdditionalTypeInstances.SingleOrDefault(t => t.Name == typeDefinition.Name);

if (contentItemType == null)
{
// This error would indicate that this graph type is build too early.
throw new InvalidOperationException("ContentTypeDefinition has not been registered in GraphQL");
}

var field = Field(typeDefinition.Name, contentItemType.GetType())
.Description(S["Custom user settings of {0}.", typeDefinition.DisplayName])
.ResolveAsync(static async context => {
// We don't want to create an empty content item if it does not exist.
if (context.Source is User user &&
user.Properties.ContainsKey(context.FieldDefinition.ResolvedType.Name))
{
var customUserSettingsService = context.RequestServices!.GetRequiredService<CustomUserSettingsService>();
var settingsType = await customUserSettingsService.GetSettingsTypeAsync(context.FieldDefinition.ResolvedType.Name);

return await customUserSettingsService.GetSettingsAsync(user, settingsType);
}

return null;
});
Field<ContentItemInterface, ContentItem>(typeDefinition.Name)
.Type(contentItemType)
.Description(S["Custom user settings of {0}.", typeDefinition.DisplayName])
.ResolveAsync(static async context =>
{
// We don't want to create an empty content item if it does not exist.
if (context.Source is User user &&
user.Properties.ContainsKey(context.FieldDefinition.ResolvedType.Name))
{
var customUserSettingsService = context.RequestServices!.GetRequiredService<CustomUserSettingsService>();
var settingsType = await customUserSettingsService.GetSettingsTypeAsync(context.FieldDefinition.ResolvedType.Name);

return await customUserSettingsService.GetSettingsAsync(user, settingsType);
}

return null;
});
}
}

0 comments on commit 1f58aa3

Please sign in to comment.