Browse Source

Language support

pull/1/head
Sebastian 9 years ago
parent
commit
96b5174e84
  1. 2
      src/Squidex.Read.MongoDb/History/MongoHistoryEventRepository.cs
  2. 24
      src/Squidex.Read/Apps/AppHistoryEventsCreator.cs
  3. 46
      src/Squidex.Read/Contents/ContentHistoryEventsCreator.cs
  4. 20
      src/Squidex.Read/History/HistoryEventsCreatorBase.cs
  5. 87
      src/Squidex.Read/Schemas/SchemaHistoryEventsCreator.cs
  6. 5
      src/Squidex/Config/Domain/ReadModule.cs
  7. 9
      src/Squidex/Config/Domain/Serializers.cs
  8. 10
      src/Squidex/Config/Domain/WriteModule.cs
  9. 8
      src/Squidex/app/features/content/module.ts
  10. 2
      src/Squidex/app/features/content/pages/contents/content-item.component.ts
  11. 5
      src/Squidex/app/features/content/pages/contents/contents-page.component.html
  12. 2
      src/Squidex/app/shared/services/auth.service.ts

2
src/Squidex.Read.MongoDb/History/MongoHistoryEventRepository.cs

@ -67,7 +67,7 @@ namespace Squidex.Read.MongoDb.History
public async Task<List<IHistoryEventEntity>> QueryEventsByChannel(Guid appId, string channelPrefix, int count)
{
var entities =
await Collection.Find(x => x.AppId == appId && x.Channel.StartsWith(channelPrefix))
await Collection.Find(x => x.AppId == appId && x.Channel == channelPrefix)
.SortByDescending(x => x.Created).ThenByDescending(x => x.SessionEventIndex).Limit(count).ToListAsync();
return entities.Select(x => (IHistoryEventEntity)new ParsedHistoryEvent(x, texts)).ToList();

24
src/Squidex.Read/Apps/AppHistoryEventsCreator.cs

@ -46,36 +46,35 @@ namespace Squidex.Read.Apps
"changed master language to {[Language]}");
}
protected Task<HistoryEventToStore> On(AppContributorAssigned @event, EnvelopeHeaders headers)
protected Task<HistoryEventToStore> On(AppContributorRemoved @event, EnvelopeHeaders headers)
{
const string channel = "settings.contributors";
return Task.FromResult(
ForEvent(@event, channel)
.AddParameter("Contributor", @event.ContributorId)
.AddParameter("Permission", @event.Permission.ToString()));
.AddParameter("Contributor", @event.ContributorId));
}
protected Task<HistoryEventToStore> On(AppContributorRemoved @event, EnvelopeHeaders headers)
protected Task<HistoryEventToStore> On(AppContributorAssigned @event, EnvelopeHeaders headers)
{
const string channel = "settings.contributors";
return Task.FromResult(
ForEvent(@event, channel)
.AddParameter("Contributor", @event.ContributorId));
.AddParameter("Contributor", @event.ContributorId)
.AddParameter("Permission", @event.Permission.ToString()));
}
protected Task<HistoryEventToStore> On(AppClientRenamed @event, EnvelopeHeaders headers)
protected Task<HistoryEventToStore> On(AppClientAttached @event, EnvelopeHeaders headers)
{
const string channel = "settings.clients";
return Task.FromResult(
ForEvent(@event, channel)
.AddParameter("Id", @event.Id)
.AddParameter("Name", !string.IsNullOrWhiteSpace(@event.Name) ? @event.Name : @event.Id));
.AddParameter("Id", @event.Id));
}
protected Task<HistoryEventToStore> On(AppClientAttached @event, EnvelopeHeaders headers)
protected Task<HistoryEventToStore> On(AppClientRevoked @event, EnvelopeHeaders headers)
{
const string channel = "settings.clients";
@ -84,13 +83,14 @@ namespace Squidex.Read.Apps
.AddParameter("Id", @event.Id));
}
protected Task<HistoryEventToStore> On(AppClientRevoked @event, EnvelopeHeaders headers)
protected Task<HistoryEventToStore> On(AppClientRenamed @event, EnvelopeHeaders headers)
{
const string channel = "settings.clients";
return Task.FromResult(
ForEvent(@event, channel)
.AddParameter("Id", @event.Id));
.AddParameter("Id", @event.Id)
.AddParameter("Name", !string.IsNullOrWhiteSpace(@event.Name) ? @event.Name : @event.Id));
}
protected Task<HistoryEventToStore> On(AppLanguageAdded @event, EnvelopeHeaders headers)
@ -120,7 +120,7 @@ namespace Squidex.Read.Apps
.AddParameter("Language", @event.Language.EnglishName));
}
public override Task<HistoryEventToStore> CreateEventAsync(Envelope<IEvent> @event)
protected override Task<HistoryEventToStore> CreateEventCoreAsync(Envelope<IEvent> @event)
{
return this.DispatchFuncAsync(@event.Payload, @event.Headers, (HistoryEventToStore)null);
}

46
src/Squidex.Read/Contents/ContentHistoryEventsCreator.cs

@ -0,0 +1,46 @@
// ==========================================================================
// ContentHistoryEventsCreator.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.Threading.Tasks;
using Squidex.Events.Contents;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Read.History;
namespace Squidex.Read.Contents
{
public sealed class ContentHistoryEventsCreator : HistoryEventsCreatorBase
{
public ContentHistoryEventsCreator(TypeNameRegistry typeNameRegistry)
: base(typeNameRegistry)
{
AddEventMessage<ContentCreated>(
"created content element.");
AddEventMessage<ContentUpdated>(
"updated content element.");
AddEventMessage<ContentDeleted>(
"deleted content element.");
AddEventMessage<ContentPublished>(
"published content element.");
AddEventMessage<ContentUnpublished>(
"unpublished content element.");
}
protected override Task<HistoryEventToStore> CreateEventCoreAsync(Envelope<IEvent> @event)
{
var channel = $"contents.{@event.Headers.AggregateId()}";
return Task.FromResult(ForEvent(@event.Payload, channel));
}
}
}

20
src/Squidex.Read/History/HistoryEventsCreatorBase.cs

@ -11,6 +11,7 @@ using System.Threading.Tasks;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS;
using Squidex.Infrastructure.CQRS.Events;
// ReSharper disable ConvertIfStatementToReturnStatement
namespace Squidex.Read.History
{
@ -38,6 +39,13 @@ namespace Squidex.Read.History
texts[typeNameRegistry.GetName<TEvent>()] = message;
}
protected bool HasEventText(IEvent @event)
{
var message = typeNameRegistry.GetName(@event.GetType());
return texts.ContainsKey(message);
}
protected HistoryEventToStore ForEvent(IEvent @event, string channel)
{
var message = typeNameRegistry.GetName(@event.GetType());
@ -45,6 +53,16 @@ namespace Squidex.Read.History
return new HistoryEventToStore(channel, message);
}
public abstract Task<HistoryEventToStore> CreateEventAsync(Envelope<IEvent> @event);
public Task<HistoryEventToStore> CreateEventAsync(Envelope<IEvent> @event)
{
if (HasEventText(@event.Payload))
{
return CreateEventCoreAsync(@event);
}
return Task.FromResult<HistoryEventToStore>(null);
}
protected abstract Task<HistoryEventToStore> CreateEventCoreAsync(Envelope<IEvent> @event);
}
}

87
src/Squidex.Read/Schemas/SchemaHistoryEventsCreator.cs

@ -11,13 +11,13 @@ using Squidex.Events.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.Dispatching;
using Squidex.Read.History;
using Squidex.Read.Schemas.Services;
// ReSharper disable InvertIf
namespace Squidex.Read.Schemas
{
public class SchemaHistoryEventsCreator : HistoryEventsCreatorBase
public sealed class SchemaHistoryEventsCreator : HistoryEventsCreatorBase
{
private readonly ISchemaProvider schemaProvider;
@ -34,67 +34,70 @@ namespace Squidex.Read.Schemas
AddEventMessage<SchemaUpdated>(
"updated schema {[Name]}");
AddEventMessage<SchemaDeleted>(
"deleted schema {[Name]}");
AddEventMessage<SchemaPublished>(
"published schema {[Name]}");
AddEventMessage<SchemaUnpublished>(
"unpublished schema {[Name]}");
}
protected Task<HistoryEventToStore> On(SchemaCreated @event, EnvelopeHeaders headers)
{
var name = @event.Name;
AddEventMessage<FieldAdded>(
"added field {[Field]} to schema {[Name]}");
string channel = $"schemas.{name}";
AddEventMessage<FieldDeleted>(
"deleted field {[Field]} from schema {[Name]}");
return Task.FromResult(
ForEvent(@event, channel)
.AddParameter("Name", name));
}
AddEventMessage<FieldDisabled>(
"disabled field {[Field]} of schema {[Name]}");
protected async Task<HistoryEventToStore> On(SchemaUpdated @event, EnvelopeHeaders headers)
{
var name = await FindSchemaNameAsync(headers);
AddEventMessage<FieldEnabled>(
"disabled field {[Field]} of schema {[Name]}");
string channel = $"schemas.{name}";
return
ForEvent(@event, channel)
.AddParameter("Name", name);
}
AddEventMessage<FieldHidden>(
"has hidden field {[Field]} of schema {[Name]}");
protected async Task<HistoryEventToStore> On(SchemaPublished @event, EnvelopeHeaders headers)
{
var name = await FindSchemaNameAsync(headers);
AddEventMessage<FieldShown>(
"has shown field {[Field]} of schema {[Name]}");
string channel = $"schemas.{name}";
AddEventMessage<FieldUpdated>(
"has updated field {[Field]} of schema {[Name]}");
return
ForEvent(@event, channel)
.AddParameter("Name", name);
AddEventMessage<FieldDeleted>(
"deleted field {[Field]} of schema {[Name]}");
}
protected async Task<HistoryEventToStore> On(SchemaUnpublished @event, EnvelopeHeaders headers)
protected override async Task<HistoryEventToStore> CreateEventCoreAsync(Envelope<IEvent> @event)
{
var name = await FindSchemaNameAsync(headers);
var schemaCreated = @event.Payload as SchemaCreated;
string channel = $"schemas.{name}";
if (schemaCreated != null)
{
string channel = $"schemas.{schemaCreated.Name}";
return
ForEvent(@event, channel)
.AddParameter("Name", name);
}
return ForEvent(@event.Payload, channel).AddParameter("Name", schemaCreated.Name);
}
else
{
var schemaEntity = await schemaProvider.FindSchemaByIdAsync(@event.Headers.AggregateId());
var schemaName = schemaEntity.Label ?? schemaEntity.Name;
public override Task<HistoryEventToStore> CreateEventAsync(Envelope<IEvent> @event)
{
return this.DispatchFuncAsync(@event.Payload, @event.Headers, (HistoryEventToStore)null);
}
string channel = $"schemas.{schemaName}";
private async Task<string> FindSchemaNameAsync(EnvelopeHeaders headers)
{
var schema = await schemaProvider.FindSchemaByIdAsync(headers.AggregateId());
var result = ForEvent(@event.Payload, channel).AddParameter("Name", schemaName);
var fieldEvent = @event.Payload as FieldEvent;
if (fieldEvent != null)
{
var fieldName = schemaEntity.Schema.Fields.GetOrDefault(fieldEvent.FieldId)?.Name;
result.AddParameter("Field", fieldName);
}
return schema.Label ?? schema.Name;
return result;
}
}
}
}

5
src/Squidex/Config/Domain/ReadModule.cs

@ -12,6 +12,7 @@ using Squidex.Infrastructure.CQRS.Events;
using Squidex.Read.Apps;
using Squidex.Read.Apps.Services;
using Squidex.Read.Apps.Services.Implementations;
using Squidex.Read.Contents;
using Squidex.Read.History;
using Squidex.Read.Schemas;
using Squidex.Read.Schemas.Services;
@ -44,6 +45,10 @@ namespace Squidex.Config.Domain
.As<IHistoryEventsCreator>()
.SingleInstance();
builder.RegisterType<ContentHistoryEventsCreator>()
.As<IHistoryEventsCreator>()
.SingleInstance();
builder.RegisterType<SchemaHistoryEventsCreator>()
.As<IHistoryEventsCreator>()
.SingleInstance();

9
src/Squidex/Config/Domain/Serializers.cs

@ -19,7 +19,8 @@ namespace Squidex.Config.Domain
public static class Serializers
{
private static readonly TypeNameRegistry typeNameRegistry = new TypeNameRegistry();
private static JsonSerializerSettings ConfigureJson(JsonSerializerSettings settings)
private static JsonSerializerSettings ConfigureJson(JsonSerializerSettings settings, TypeNameHandling typeNameHandling)
{
settings.SerializationBinder = new TypeNameSerializationBinder(typeNameRegistry);
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
@ -29,7 +30,7 @@ namespace Squidex.Config.Domain
settings.NullValueHandling = NullValueHandling.Ignore;
settings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
settings.DateParseHandling = DateParseHandling.DateTime;
settings.TypeNameHandling = TypeNameHandling.Auto;
settings.TypeNameHandling = typeNameHandling;
return settings;
}
@ -41,7 +42,7 @@ namespace Squidex.Config.Domain
private static JsonSerializerSettings CreateSettings()
{
return ConfigureJson(new JsonSerializerSettings());
return ConfigureJson(new JsonSerializerSettings(), TypeNameHandling.Auto);
}
private static JsonSerializer CreateSerializer(JsonSerializerSettings settings)
@ -62,7 +63,7 @@ namespace Squidex.Config.Domain
{
mvc.AddJsonOptions(options =>
{
ConfigureJson(options.SerializerSettings);
ConfigureJson(options.SerializerSettings, TypeNameHandling.None);
});
return mvc;

10
src/Squidex/Config/Domain/WriteModule.cs

@ -66,12 +66,12 @@ namespace Squidex.Config.Domain
builder.RegisterType<ClientKeyGenerator>()
.AsSelf()
.InstancePerDependency();
.SingleInstance();
builder.RegisterType<FieldRegistry>()
.AsSelf()
.InstancePerDependency();
.SingleInstance();
builder.RegisterType<AppCommandHandler>()
@ -89,11 +89,11 @@ namespace Squidex.Config.Domain
builder.Register<DomainObjectFactoryFunction<AppDomainObject>>(c => (id => new AppDomainObject(id, 0)))
.AsSelf()
.InstancePerDependency();
.SingleInstance();
builder.Register<DomainObjectFactoryFunction<ContentDomainObject>>(c => (id => new ContentDomainObject(id, 0)))
.AsSelf()
.InstancePerDependency();
.SingleInstance();
builder.Register<DomainObjectFactoryFunction<SchemaDomainObject>>(c =>
{
@ -102,7 +102,7 @@ namespace Squidex.Config.Domain
return (id => new SchemaDomainObject(id, 0, fieldRegistry));
})
.AsSelf()
.InstancePerDependency();
.SingleInstance();
}
}
}

8
src/Squidex/app/features/content/module.ts

@ -43,12 +43,6 @@ const routes: Routes = [
{
path: 'new',
component: ContentPageComponent
}, {
path: 'history',
component: HistoryComponent,
data: {
channel: 'contents.{schemaName}'
}
}, {
path: ':contentId',
component: ContentPageComponent,
@ -60,7 +54,7 @@ const routes: Routes = [
path: 'history',
component: HistoryComponent,
data: {
channel: 'contents.{schemaName}.{contentId}'
channel: 'contents.{contentId}'
}
}
]

2
src/Squidex/app/features/content/pages/contents/content-item.component.ts

@ -59,6 +59,8 @@ export class ContentItemComponent extends AppComponentBase implements OnInit {
}
public ngOnInit() {
this.values = [];
for (let field of this.fields) {
this.values.push(this.getValue(field));
}

5
src/Squidex/app/features/content/pages/contents/contents-page.component.html

@ -78,11 +78,6 @@
</div>
</div>
</div>
<div class="panel-sidebar">
<a class="panel-link" routerLink="history" routerLinkActive="active">
<i class="icon-time"></i>
</a>
</div>
</div>
</sqx-panel>

2
src/Squidex/app/shared/services/auth.service.ts

@ -214,6 +214,8 @@ export class AuthService {
options.headers.append('Content-Type', 'application/json');
}
options.headers.append('Accept-Language', '*');
if (this.currentUser && this.currentUser.user) {
options.headers.append('Authorization', `${this.currentUser.user.token_type} ${this.currentUser.user.access_token}`);
}

Loading…
Cancel
Save