+
仅当用户具有`AbpIdentity.Roles`权限时,此内容才可见.
```
@@ -58,6 +58,8 @@ export class YourComponent {
将 `requiredPolicy` 添加到路由模块中的 `routes`属性.
```js
+import { PermissionGuard } from '@abp/ng.core';
+// ...
const routes: Routes = [
{
path: 'path',
diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json
index c14355497b..04da437b7b 100644
--- a/docs/zh-Hans/docs-nav.json
+++ b/docs/zh-Hans/docs-nav.json
@@ -154,16 +154,23 @@
]
},
{
- "text": "事件",
+ "text": "事件总线",
"items": [
{
- "text": "本地 Event Bus"
+ "text": "概述",
+ "path": "Event-Bus.md"
+ },
+ {
+ "text": "本地 Event Bus",
+ "path": "Local-Event-Bus.md"
},
{
"text": "分布式 Event Bus",
+ "path": "Distributed-Event-Bus.md",
"items": [
{
- "text": "RabbitMQ 集成"
+ "text": "RabbitMQ 集成",
+ "path": "Distributed-Event-Bus-RabbitMQ-Integration.md"
}
]
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs
index 1e5f138f97..81696d5e71 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs
@@ -12,6 +12,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Select2
{
//TODO: Add select2.full.min.js or localize!
context.Files.AddIfNotContains("/libs/select2/js/select2.min.js");
+ context.Files.AddIfNotContains("/libs/select2/js/select2-bootstrap-modal-patch.js");
}
}
}
diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/DefaultContainer.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/DefaultContainer.cs
index 038d53af6d..278ed46839 100644
--- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/DefaultContainer.cs
+++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/DefaultContainer.cs
@@ -3,6 +3,6 @@
[BlobContainerName(Name)]
public class DefaultContainer
{
- public const string Name = "Default";
+ public const string Name = "default";
}
}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs
index 83182fc965..83c2c4c38e 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs
@@ -359,5 +359,15 @@ namespace Volo.Abp.Reflection
? type.GenericTypeArguments[0]
: type;
}
+
+ public static bool IsDefaultValue([CanBeNull] object obj)
+ {
+ if (obj == null)
+ {
+ return true;
+ }
+
+ return obj.Equals(GetDefaultValue(obj.GetType()));
+ }
}
}
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs
index b78a5aa400..cf1b643305 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Reflection;
-using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Domain.Entities
{
@@ -16,6 +14,11 @@ namespace Volo.Abp.Domain.Entities
}
public abstract object[] GetKeys();
+
+ public bool EntityEquals(IEntity other)
+ {
+ return EntityHelper.EntityEquals(this, other);
+ }
}
///
@@ -35,44 +38,6 @@ namespace Volo.Abp.Domain.Entities
Id = id;
}
- public bool EntityEquals(object obj)
- {
- if (obj == null || !(obj is Entity
))
- {
- return false;
- }
-
- //Same instances must be considered as equal
- if (ReferenceEquals(this, obj))
- {
- return true;
- }
-
- //Transient objects are not considered as equal
- var other = (Entity)obj;
- if (EntityHelper.HasDefaultId(this) && EntityHelper.HasDefaultId(other))
- {
- return false;
- }
-
- //Must have a IS-A relation of types or must be same type
- var typeOfThis = GetType().GetTypeInfo();
- var typeOfOther = other.GetType().GetTypeInfo();
- if (!typeOfThis.IsAssignableFrom(typeOfOther) && !typeOfOther.IsAssignableFrom(typeOfThis))
- {
- return false;
- }
-
- //Different tenants may have an entity with same Id.
- if (this is IMultiTenant && other is IMultiTenant &&
- this.As().TenantId != other.As().TenantId)
- {
- return false;
- }
-
- return Id.Equals(other.Id);
- }
-
public override object[] GetKeys()
{
return new object[] {Id};
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs
index ad082c3fb0..65f2992257 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs
@@ -5,6 +5,8 @@ using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using JetBrains.Annotations;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.Reflection;
namespace Volo.Abp.Domain.Entities
{
@@ -16,6 +18,98 @@ namespace Volo.Abp.Domain.Entities
private static readonly ConcurrentDictionary CachedIdProperties =
new ConcurrentDictionary();
+ public static bool EntityEquals(IEntity entity1, IEntity entity2)
+ {
+ if (entity1 == null || entity2 == null)
+ {
+ return false;
+ }
+
+ //Same instances must be considered as equal
+ if (ReferenceEquals(entity1, entity2))
+ {
+ return true;
+ }
+
+ //Must have a IS-A relation of types or must be same type
+ var typeOfEntity1 = entity1.GetType();
+ var typeOfEntity2 = entity2.GetType();
+ if (!typeOfEntity1.IsAssignableFrom(typeOfEntity2) && !typeOfEntity2.IsAssignableFrom(typeOfEntity1))
+ {
+ return false;
+ }
+
+ //Different tenants may have an entity with same Id.
+ if (entity1 is IMultiTenant && entity2 is IMultiTenant)
+ {
+ var tenant1Id = ((IMultiTenant) entity1).TenantId;
+ var tenant2Id = ((IMultiTenant) entity2).TenantId;
+
+ if (tenant1Id != tenant2Id)
+ {
+ if (tenant1Id == null || tenant2Id == null)
+ {
+ return false;
+ }
+
+ if (!tenant1Id.Equals(tenant2Id))
+ {
+ return false;
+ }
+ }
+ }
+
+ //Transient objects are not considered as equal
+ if (HasDefaultKeys(entity1) && HasDefaultKeys(entity2))
+ {
+ return false;
+ }
+
+ var entity1Keys = entity1.GetKeys();
+ var entity2Keys = entity2.GetKeys();
+
+ if (entity1Keys.Length != entity2Keys.Length)
+ {
+ return false;
+ }
+
+ for (var i = 0; i < entity1Keys.Length; i++)
+ {
+ var entity1Key = entity1Keys[i];
+ var entity2Key = entity2Keys[i];
+
+ if (entity1Key == null)
+ {
+ if (entity2Key == null)
+ {
+ //Both null, so considered as equals
+ continue;
+ }
+
+ //entity2Key is not null!
+ return false;
+ }
+
+ if (entity2Key == null)
+ {
+ //entity1Key was not null!
+ return false;
+ }
+
+ if (TypeHelper.IsDefaultValue(entity1Key) && TypeHelper.IsDefaultValue(entity2Key))
+ {
+ return false;
+ }
+
+ if (!entity1Key.Equals(entity2Key))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
public static bool IsEntity([NotNull] Type type)
{
return typeof(IEntity).IsAssignableFrom(type);
@@ -25,7 +119,8 @@ namespace Volo.Abp.Domain.Entities
{
foreach (var interfaceType in type.GetInterfaces())
{
- if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEntity<>))
+ if (interfaceType.GetTypeInfo().IsGenericType &&
+ interfaceType.GetGenericTypeDefinition() == typeof(IEntity<>))
{
return true;
}
@@ -55,6 +150,44 @@ namespace Volo.Abp.Domain.Entities
return false;
}
+ private static bool IsDefaultKeyValue(object value)
+ {
+ if (value == null)
+ {
+ return true;
+ }
+
+ var type = value.GetType();
+
+ //Workaround for EF Core since it sets int/long to min value when attaching to DbContext
+ if (type == typeof(int))
+ {
+ return Convert.ToInt32(value) <= 0;
+ }
+
+ if (type == typeof(long))
+ {
+ return Convert.ToInt64(value) <= 0;
+ }
+
+ return TypeHelper.IsDefaultValue(value);
+ }
+
+ public static bool HasDefaultKeys([NotNull] IEntity entity)
+ {
+ Check.NotNull(entity, nameof(entity));
+
+ foreach (var key in entity.GetKeys())
+ {
+ if (!IsDefaultKeyValue(key))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
///
/// Tries to find the primary key type of the given entity type.
/// May return null if given type does not implement
@@ -75,12 +208,14 @@ namespace Volo.Abp.Domain.Entities
{
if (!typeof(IEntity).IsAssignableFrom(entityType))
{
- throw new AbpException($"Given {nameof(entityType)} is not an entity. It should implement {typeof(IEntity).AssemblyQualifiedName}!");
+ throw new AbpException(
+ $"Given {nameof(entityType)} is not an entity. It should implement {typeof(IEntity).AssemblyQualifiedName}!");
}
foreach (var interfaceType in entityType.GetTypeInfo().GetInterfaces())
{
- if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEntity<>))
+ if (interfaceType.GetTypeInfo().IsGenericType &&
+ interfaceType.GetGenericTypeDefinition() == typeof(IEntity<>))
{
return interfaceType.GenericTypeArguments[0];
}
@@ -132,4 +267,4 @@ namespace Volo.Abp.Domain.Entities
property?.SetValue(entity, idFactory());
}
}
-}
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs
new file mode 100644
index 0000000000..19652fca8e
--- /dev/null
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AbpDistributedEntityEventOptions.cs
@@ -0,0 +1,15 @@
+namespace Volo.Abp.Domain.Entities.Events.Distributed
+{
+ public class AbpDistributedEntityEventOptions
+ {
+ public IAutoEntityDistributedEventSelectorList AutoEventSelectors { get; }
+
+ public EtoMappingDictionary EtoMappings { get; set; }
+
+ public AbpDistributedEntityEventOptions()
+ {
+ AutoEventSelectors = new AutoEntityDistributedEventSelectorList();
+ EtoMappings = new EtoMappingDictionary();
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs
new file mode 100644
index 0000000000..328c74e324
--- /dev/null
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace Volo.Abp.Domain.Entities.Events.Distributed
+{
+ public class AutoEntityDistributedEventSelectorList : List, IAutoEntityDistributedEventSelectorList
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions.cs
new file mode 100644
index 0000000000..d2a0622f54
--- /dev/null
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using JetBrains.Annotations;
+
+namespace Volo.Abp.Domain.Entities.Events.Distributed
+{
+ public static class AutoEntityDistributedEventSelectorListExtensions
+ {
+ public const string AllEntitiesSelectorName = "All";
+
+ public static void AddNamespace([NotNull] this IAutoEntityDistributedEventSelectorList selectors, [NotNull] string namespaceName)
+ {
+ Check.NotNull(selectors, nameof(selectors));
+
+ var selectorName = "Namespace:" + namespaceName;
+ if (selectors.Any(s => s.Name == selectorName))
+ {
+ return;
+ }
+
+ selectors.Add(
+ new NamedTypeSelector(
+ selectorName,
+ t => t.FullName?.StartsWith(namespaceName) ?? false
+ )
+ );
+ }
+
+ ///
+ /// Adds a specific entity type and the types derived from that entity type.
+ ///
+ /// Type of the entity
+ public static void Add([NotNull] this IAutoEntityDistributedEventSelectorList selectors)
+ where TEntity : IEntity
+ {
+ Check.NotNull(selectors, nameof(selectors));
+
+ var selectorName = "Entity:" + typeof(TEntity).FullName;
+ if (selectors.Any(s => s.Name == selectorName))
+ {
+ return;
+ }
+
+ selectors.Add(
+ new NamedTypeSelector(
+ selectorName,
+ t => typeof(TEntity).IsAssignableFrom(t)
+ )
+ );
+ }
+
+ ///
+ /// Adds all entity types.
+ ///
+ public static void AddAll([NotNull] this IAutoEntityDistributedEventSelectorList selectors)
+ {
+ Check.NotNull(selectors, nameof(selectors));
+
+ if (selectors.Any(s => s.Name == AllEntitiesSelectorName))
+ {
+ return;
+ }
+
+ selectors.Add(
+ new NamedTypeSelector(
+ AllEntitiesSelectorName,
+ t => typeof(IEntity).IsAssignableFrom(t)
+ )
+ );
+ }
+
+ public static void Add(
+ [NotNull] this IAutoEntityDistributedEventSelectorList selectors,
+ string selectorName,
+ Func predicate)
+ {
+ Check.NotNull(selectors, nameof(selectors));
+
+ if (selectors.Any(s => s.Name == selectorName))
+ {
+ throw new AbpException($"There is already a selector added before with the same name: {selectorName}");
+ }
+
+ selectors.Add(
+ new NamedTypeSelector(
+ selectorName,
+ predicate
+ )
+ );
+ }
+
+ public static void Add(
+ [NotNull] this IAutoEntityDistributedEventSelectorList selectors,
+ Func predicate)
+ {
+ selectors.Add(Guid.NewGuid().ToString("N"), predicate);
+ }
+
+ public static bool RemoveByName(
+ [NotNull] this IAutoEntityDistributedEventSelectorList selectors,
+ [NotNull] string name)
+ {
+ Check.NotNull(selectors, nameof(selectors));
+ Check.NotNull(name, nameof(name));
+
+ return selectors.RemoveAll(s => s.Name == name).Count > 0;
+ }
+
+
+ public static bool IsMatch([NotNull] this IAutoEntityDistributedEventSelectorList selectors, Type entityType)
+ {
+ Check.NotNull(selectors, nameof(selectors));
+ return selectors.Any(s => s.Predicate(entityType));
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs
index 24a757fb08..15a41bad9d 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EntityToEtoMapper.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
-using Volo.Abp.EventBus.Distributed;
using Volo.Abp.ObjectMapping;
namespace Volo.Abp.Domain.Entities.Events.Distributed
@@ -11,10 +10,11 @@ namespace Volo.Abp.Domain.Entities.Events.Distributed
public class EntityToEtoMapper : IEntityToEtoMapper, ITransientDependency
{
protected IHybridServiceScopeFactory HybridServiceScopeFactory { get; }
- protected AbpDistributedEventBusOptions Options { get; }
+
+ protected AbpDistributedEntityEventOptions Options { get; }
public EntityToEtoMapper(
- IOptions options,
+ IOptions options,
IHybridServiceScopeFactory hybridServiceScopeFactory)
{
HybridServiceScopeFactory = hybridServiceScopeFactory;
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/EtoMappingDictionary.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs
similarity index 79%
rename from framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/EtoMappingDictionary.cs
rename to framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs
index aae99d0cb7..3988ceb3b5 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/EtoMappingDictionary.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionary.cs
@@ -1,7 +1,8 @@
using System;
using System.Collections.Generic;
+using Volo.Abp.EventBus.Distributed;
-namespace Volo.Abp.EventBus.Distributed
+namespace Volo.Abp.Domain.Entities.Events.Distributed
{
public class EtoMappingDictionary : Dictionary
{
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/EtoMappingDictionaryItem.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs
similarity index 87%
rename from framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/EtoMappingDictionaryItem.cs
rename to framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs
index d634c44b4d..2550c83a53 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/EtoMappingDictionaryItem.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/EtoMappingDictionaryItem.cs
@@ -1,6 +1,6 @@
using System;
-namespace Volo.Abp.EventBus.Distributed
+namespace Volo.Abp.Domain.Entities.Events.Distributed
{
public class EtoMappingDictionaryItem
{
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs
new file mode 100644
index 0000000000..fc130eb55c
--- /dev/null
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs
@@ -0,0 +1,9 @@
+using System;
+using System.Collections.Generic;
+
+namespace Volo.Abp.Domain.Entities.Events.Distributed
+{
+ public interface IAutoEntityDistributedEventSelectorList : IList
+ {
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs
index c9219feffc..5de3b22c77 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs
@@ -1,6 +1,10 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events.Distributed;
@@ -17,21 +21,26 @@ namespace Volo.Abp.Domain.Entities.Events
///
public class EntityChangeEventHelper : IEntityChangeEventHelper, ITransientDependency
{
+ public ILogger Logger { get; set; }
public ILocalEventBus LocalEventBus { get; set; }
public IDistributedEventBus DistributedEventBus { get; set; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected IEntityToEtoMapper EntityToEtoMapper { get; }
+ protected AbpDistributedEntityEventOptions DistributedEntityEventOptions { get; }
public EntityChangeEventHelper(
IUnitOfWorkManager unitOfWorkManager,
- IEntityToEtoMapper entityToEtoMapper)
+ IEntityToEtoMapper entityToEtoMapper,
+ IOptions distributedEntityEventOptions)
{
UnitOfWorkManager = unitOfWorkManager;
EntityToEtoMapper = entityToEtoMapper;
+ DistributedEntityEventOptions = distributedEntityEventOptions.Value;
LocalEventBus = NullLocalEventBus.Instance;
DistributedEventBus = NullDistributedEventBus.Instance;
+ Logger = NullLogger.Instance;
}
public async Task TriggerEventsAsync(EntityChangeReport changeReport)
@@ -52,6 +61,7 @@ namespace Volo.Abp.Domain.Entities.Events
LocalEventBus,
typeof(EntityCreatingEventData<>),
entity,
+ entity,
true
);
}
@@ -62,27 +72,44 @@ namespace Volo.Abp.Domain.Entities.Events
LocalEventBus,
typeof(EntityCreatedEventData<>),
entity,
+ entity,
false
);
- var eto = EntityToEtoMapper.Map(entity);
- if (eto != null)
+ if (ShouldPublishDistributedEventForEntity(entity))
{
- await TriggerEventWithEntity(
- DistributedEventBus,
- typeof(EntityCreatedEto<>),
- eto,
- false
- );
+ var eto = EntityToEtoMapper.Map(entity);
+ if (eto != null)
+ {
+ await TriggerEventWithEntity(
+ DistributedEventBus,
+ typeof(EntityCreatedEto<>),
+ eto,
+ entity,
+ false
+ );
+ }
}
}
+ private bool ShouldPublishDistributedEventForEntity(object entity)
+ {
+ return DistributedEntityEventOptions
+ .AutoEventSelectors
+ .IsMatch(
+ ProxyHelper
+ .UnProxy(entity)
+ .GetType()
+ );
+ }
+
public virtual async Task TriggerEntityUpdatingEventAsync(object entity)
{
await TriggerEventWithEntity(
LocalEventBus,
typeof(EntityUpdatingEventData<>),
entity,
+ entity,
true
);
}
@@ -93,18 +120,23 @@ namespace Volo.Abp.Domain.Entities.Events
LocalEventBus,
typeof(EntityUpdatedEventData<>),
entity,
+ entity,
false
);
- var eto = EntityToEtoMapper.Map(entity);
- if (eto != null)
+ if (ShouldPublishDistributedEventForEntity(entity))
{
- await TriggerEventWithEntity(
- DistributedEventBus,
- typeof(EntityUpdatedEto<>),
- eto,
- false
- );
+ var eto = EntityToEtoMapper.Map(entity);
+ if (eto != null)
+ {
+ await TriggerEventWithEntity(
+ DistributedEventBus,
+ typeof(EntityUpdatedEto<>),
+ eto,
+ entity,
+ false
+ );
+ }
}
}
@@ -114,6 +146,7 @@ namespace Volo.Abp.Domain.Entities.Events
LocalEventBus,
typeof(EntityDeletingEventData<>),
entity,
+ entity,
true
);
}
@@ -124,18 +157,23 @@ namespace Volo.Abp.Domain.Entities.Events
LocalEventBus,
typeof(EntityDeletedEventData<>),
entity,
+ entity,
false
);
- var eto = EntityToEtoMapper.Map(entity);
- if (eto != null)
+ if (ShouldPublishDistributedEventForEntity(entity))
{
- await TriggerEventWithEntity(
- DistributedEventBus,
- typeof(EntityDeletedEto<>),
- EntityToEtoMapper.Map(entity),
- false
- );
+ var eto = EntityToEtoMapper.Map(entity);
+ if (eto != null)
+ {
+ await TriggerEventWithEntity(
+ DistributedEventBus,
+ typeof(EntityDeletedEto<>),
+ eto,
+ entity,
+ false
+ );
+ }
}
}
@@ -182,22 +220,129 @@ namespace Volo.Abp.Domain.Entities.Events
{
foreach (var distributedEvent in distributedEvents)
{
- await DistributedEventBus.PublishAsync(distributedEvent.EventData.GetType(), distributedEvent.EventData);
+ await DistributedEventBus.PublishAsync(distributedEvent.EventData.GetType(),
+ distributedEvent.EventData);
}
}
- protected virtual async Task TriggerEventWithEntity(IEventBus eventPublisher, Type genericEventType, object entity, bool triggerInCurrentUnitOfWork)
+ protected virtual async Task TriggerEventWithEntity(
+ IEventBus eventPublisher,
+ Type genericEventType,
+ object entityOrEto,
+ object originalEntity,
+ bool triggerInCurrentUnitOfWork)
{
- var entityType = ProxyHelper.UnProxy(entity).GetType();
+ var entityType = ProxyHelper.UnProxy(entityOrEto).GetType();
var eventType = genericEventType.MakeGenericType(entityType);
+ var currentUow = UnitOfWorkManager.Current;
- if (triggerInCurrentUnitOfWork || UnitOfWorkManager.Current == null)
+ if (triggerInCurrentUnitOfWork || currentUow == null)
{
- await eventPublisher.PublishAsync(eventType, Activator.CreateInstance(eventType, entity));
+ await eventPublisher.PublishAsync(
+ eventType,
+ Activator.CreateInstance(eventType, entityOrEto)
+ );
+
return;
}
- UnitOfWorkManager.Current.OnCompleted(() => eventPublisher.PublishAsync(eventType, Activator.CreateInstance(eventType, entity)));
+ var eventList = GetEventList(currentUow);
+ var isFirstEvent = !eventList.Any();
+
+ eventList.AddUniqueEvent(eventPublisher, eventType, entityOrEto, originalEntity);
+
+ /* Register to OnCompleted if this is the first item.
+ * Other items will already be in the list once the UOW completes.
+ */
+ if (isFirstEvent)
+ {
+ currentUow.OnCompleted(
+ async () =>
+ {
+ foreach (var eventEntry in eventList)
+ {
+ try
+ {
+ await eventPublisher.PublishAsync(
+ eventEntry.EventType,
+ Activator.CreateInstance(eventEntry.EventType, eventEntry.EntityOrEto)
+ );
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError(
+ $"Caught an exception while publishing the event '{eventType.FullName}' for the entity '{entityOrEto}'");
+ Logger.LogException(ex);
+ }
+ }
+ }
+ );
+ }
+ }
+
+ private EntityChangeEventList GetEventList(IUnitOfWork currentUow)
+ {
+ return (EntityChangeEventList) currentUow.Items.GetOrAdd(
+ "AbpEntityChangeEventList",
+ () => new EntityChangeEventList()
+ );
+ }
+
+ private class EntityChangeEventList : List
+ {
+ public void AddUniqueEvent(IEventBus eventBus, Type eventType, object entityOrEto, object originalEntity)
+ {
+ var newEntry = new EntityChangeEventEntry(eventBus, eventType, entityOrEto, originalEntity);
+
+ //Latest "same" event overrides the previous events.
+ for (var i = 0; i < Count; i++)
+ {
+ if (this[i].IsSameEvent(newEntry))
+ {
+ this[i] = newEntry;
+ return;
+ }
+ }
+
+ //If this is a "new" event, add to the end
+ Add(newEntry);
+ }
+ }
+
+ private class EntityChangeEventEntry
+ {
+ public IEventBus EventBus { get; }
+
+ public Type EventType { get; }
+
+ public object EntityOrEto { get; }
+
+ public object OriginalEntity { get; }
+
+ public EntityChangeEventEntry(IEventBus eventBus, Type eventType, object entityOrEto, object originalEntity)
+ {
+ EventType = eventType;
+ EntityOrEto = entityOrEto;
+ OriginalEntity = originalEntity;
+ EventBus = eventBus;
+ }
+
+ public bool IsSameEvent(EntityChangeEventEntry otherEntry)
+ {
+ if (EventBus != otherEntry.EventBus || EventType != otherEntry.EventType)
+ {
+ return false;
+ }
+
+ var originalEntityRef = OriginalEntity as IEntity;
+ var otherOriginalEntityRef = otherEntry.OriginalEntity as IEntity;
+ if (originalEntityRef == null || otherOriginalEntityRef == null)
+ {
+ return false;
+ }
+
+ return EntityHelper.EntityEquals(originalEntityRef, otherOriginalEntityRef);
+ }
}
}
}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusOptions.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusOptions.cs
index 1d1d7768f2..342e7b77bb 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusOptions.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusOptions.cs
@@ -5,12 +5,10 @@ namespace Volo.Abp.EventBus.Distributed
public class AbpDistributedEventBusOptions
{
public ITypeList Handlers { get; }
- public EtoMappingDictionary EtoMappings { get; set; }
public AbpDistributedEventBusOptions()
{
Handlers = new TypeList();
- EtoMappings = new EtoMappingDictionary();
}
}
}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/tr.json b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/tr.json
new file mode 100644
index 0000000000..4eb4a1209b
--- /dev/null
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/tr.json
@@ -0,0 +1,7 @@
+{
+ "culture": "tr",
+ "texts": {
+ "DisplayName:Abp.Localization.DefaultLanguage": "Varsayılan dil",
+ "Description:Abp.Localization.DefaultLanguage": "Varsayılan uygulama dili."
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Entity_Tests.cs b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Entity_Tests.cs
new file mode 100644
index 0000000000..779ac3fe49
--- /dev/null
+++ b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Entity_Tests.cs
@@ -0,0 +1,139 @@
+using System;
+using Shouldly;
+using Volo.Abp.MultiTenancy;
+using Xunit;
+
+namespace Volo.Abp.Domain.Entities
+{
+ public class Entity_Tests
+ {
+ [Fact]
+ public void EntityEquals_Should_Return_True_For_Same_Keys()
+ {
+ var idValue1 = Guid.NewGuid();
+ var idValue2 = Guid.NewGuid();
+
+ new Person(idValue1).EntityEquals(new Person(idValue1)).ShouldBeTrue();
+
+ new Car(42).EntityEquals(new Car(42)).ShouldBeTrue();
+
+ new Product("a").EntityEquals(new Product("a")).ShouldBeTrue();
+
+ new Phone(idValue1, "123").EntityEquals(new Phone(idValue1, "123")).ShouldBeTrue();
+ }
+
+ [Fact]
+ public void EntityEquals_Should_Return_False_For_Different_Keys()
+ {
+ var idValue1 = Guid.NewGuid();
+ var idValue2 = Guid.NewGuid();
+
+ new Person(idValue1).EntityEquals(new Person()).ShouldBeFalse();
+ new Person(idValue1).EntityEquals(new Person(idValue2)).ShouldBeFalse();
+
+ new Car(42).EntityEquals(new Car()).ShouldBeFalse();
+ new Car(42).EntityEquals(new Car(43)).ShouldBeFalse();
+
+ new Product("a").EntityEquals(new Product()).ShouldBeFalse();
+ new Product("a").EntityEquals(new Product("b")).ShouldBeFalse();
+
+ new Phone(idValue1, "123").EntityEquals(new Phone()).ShouldBeFalse();
+ new Phone(idValue1, "123").EntityEquals(new Phone(idValue1, null)).ShouldBeFalse();
+ new Phone(idValue1, "123").EntityEquals(new Phone(idValue1, "321")).ShouldBeFalse();
+ }
+
+ [Fact]
+ public void EntityEquals_Should_Return_False_For_Both_Default_Keys()
+ {
+ new Person().EntityEquals(new Person()).ShouldBeFalse();
+
+ new Car().EntityEquals(new Car()).ShouldBeFalse();
+
+ new Product().EntityEquals(new Product()).ShouldBeFalse();
+
+ new Phone().EntityEquals(new Phone()).ShouldBeFalse();
+ }
+
+ [Fact]
+ public void Different_Tenants_With_Same_Keys_Considered_As_Different_Objects()
+ {
+ var tenantId1 = Guid.NewGuid();
+ var tenantId2 = Guid.NewGuid();
+
+ new Car(42, tenantId1).EntityEquals(new Car(42)).ShouldBeFalse();
+ new Car(42).EntityEquals(new Car(42, tenantId2)).ShouldBeFalse();
+ new Car(42, tenantId1).EntityEquals(new Car(42, tenantId2)).ShouldBeFalse();
+ }
+
+ [Fact]
+ public void Same_Tenants_With_Same_Keys_Considered_As_Same_Objects()
+ {
+ var tenantId1 = Guid.NewGuid();
+
+ new Car(42).EntityEquals(new Car(42)).ShouldBeTrue();
+ new Car(42, tenantId1).EntityEquals(new Car(42, tenantId1)).ShouldBeTrue();
+ }
+
+ public class Person : Entity
+ {
+ public Person()
+ {
+ }
+
+ public Person(Guid id)
+ : base(id)
+ {
+ }
+ }
+
+ public class Car : Entity, IMultiTenant
+ {
+ public Guid? TenantId { get; }
+
+ public Car()
+ {
+ }
+
+ public Car(int id, Guid? tenantId = null)
+ : base(id)
+ {
+ TenantId = tenantId;
+ }
+ }
+
+ public class Product : Entity
+ {
+ public Product()
+ {
+ }
+
+ public Product(string id)
+ : base(id)
+ {
+ }
+ }
+
+ public class Phone : Entity
+ {
+ public Guid PersonId { get; set; }
+
+ public string Number { get; set; }
+
+ public Phone()
+ {
+
+ }
+
+ public Phone(Guid personId, string number)
+ {
+ PersonId = personId;
+ Number = number;
+ }
+
+ public override object[] GetKeys()
+ {
+ return new Object[] {PersonId, Number};
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions_Tests.cs b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions_Tests.cs
new file mode 100644
index 0000000000..9949d23f1f
--- /dev/null
+++ b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions_Tests.cs
@@ -0,0 +1,22 @@
+using Shouldly;
+using Xunit;
+
+namespace Volo.Abp.Domain.Entities.Events.Distributed
+{
+ public class AutoEntityDistributedEventSelectorListExtensions_Tests
+ {
+ [Fact]
+ public void Add_Entity()
+ {
+ var selectors = new AutoEntityDistributedEventSelectorList();
+ selectors.Add();
+
+ selectors.IsMatch(typeof(MyEntity)).ShouldBeTrue();
+ }
+
+ private class MyEntity : Entity
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json
new file mode 100644
index 0000000000..6c3c94cfdf
--- /dev/null
+++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json
@@ -0,0 +1,6 @@
+{
+ "culture": "tr",
+ "texts": {
+ "hello": "Merhaba"
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DomainEvents/EntityChangeEvents_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DomainEvents/EntityChangeEvents_Tests.cs
index 2b94ee1ed9..9f4b67d089 100644
--- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DomainEvents/EntityChangeEvents_Tests.cs
+++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DomainEvents/EntityChangeEvents_Tests.cs
@@ -4,6 +4,6 @@ namespace Volo.Abp.EntityFrameworkCore.DomainEvents
{
public class EntityChangeEvents_Tests : EntityChangeEvents_Tests
{
-
+
}
}
diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs
index 961f1ba0a4..71c2fafe2e 100644
--- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs
+++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs
@@ -1,6 +1,5 @@
using System.Globalization;
using System.Linq;
-using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Shouldly;
using Volo.Abp.Localization.TestResources.Base.CountryNames;
diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json
index 1f38b5c8d4..a6b6ce2a44 100644
--- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json
+++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json
@@ -1,6 +1,7 @@
-{
+{
"culture": "tr",
"texts": {
- "USA": "Amerika Birleşik Devletleri"
+ "USA": "Amerika Birleşik Devletleri",
+ "Brazil": "Brezilya"
}
}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/tr.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/tr.json
new file mode 100644
index 0000000000..4a1cb24c25
--- /dev/null
+++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/tr.json
@@ -0,0 +1,7 @@
+{
+ "culture": "tr",
+ "texts": {
+ "ThisFieldIsRequired": "Bu alan zorunludur",
+ "MaxLenghtErrorMessage": "Bu alan maksimum '{0}' karakter olabilir"
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json
index fa2d23246b..ee1900e150 100644
--- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json
+++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json
@@ -1,9 +1,10 @@
-{
+{
"culture": "tr",
"texts": {
"Hello {0}.": "Merhaba {0}.",
"Car": "Araba",
"CarPlural": "Araba",
+ "MaxLenghtErrorMessage": "Bu alanın uzunluğu maksimum '{0}' karakter olabilir",
"Universe": "Evren"
}
}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/tr.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/tr.json
new file mode 100644
index 0000000000..7023061d35
--- /dev/null
+++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/tr.json
@@ -0,0 +1,6 @@
+{
+ "culture": "tr",
+ "texts": {
+
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs
index 683c99d417..41079bfa9e 100644
--- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs
+++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs
@@ -4,7 +4,7 @@ using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
using Volo.Abp.TestApp.Domain;
using Volo.Abp.AutoMapper;
-using Volo.Abp.EventBus.Distributed;
+using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.TestApp.Application.Dto;
using Volo.Abp.Threading;
@@ -45,8 +45,9 @@ namespace Volo.Abp.TestApp
private void ConfigureDistributedEventBus()
{
- Configure(options =>
+ Configure(options =>
{
+ options.AutoEventSelectors.Add();
options.EtoMappings.Add();
});
}
diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs
index fe4e0862f3..cb16a46439 100644
--- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs
+++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs
@@ -84,5 +84,44 @@ namespace Volo.Abp.TestApp.Testing
createdEventTriggered.ShouldBeTrue();
createdEtoTriggered.ShouldBeTrue();
}
+
+ [Fact]
+ public async Task Multiple_Update_Should_Result_With_Single_Updated_Event_In_The_Same_Uow()
+ {
+ var personId = Guid.NewGuid();
+ await PersonRepository.InsertAsync(new Person(personId, Guid.NewGuid().ToString("D"), 42));
+
+ var updateEventCount = 0;
+ var updatedAge = 0;
+
+ DistributedEventBus.Subscribe>(eto =>
+ {
+ updateEventCount++;
+ updatedAge = eto.Entity.Age;
+ return Task.CompletedTask;
+ });
+
+ using (var uow = GetRequiredService().Begin())
+ {
+ var person = await PersonRepository.GetAsync(personId);
+
+ person.Age = 43;
+ await PersonRepository.UpdateAsync(person, autoSave: true);
+ updateEventCount.ShouldBe(0);
+
+ person.Age = 44;
+ await PersonRepository.UpdateAsync(person, autoSave: true);
+ updateEventCount.ShouldBe(0);
+
+ person.Age = 45;
+ await PersonRepository.UpdateAsync(person, autoSave: true);
+ updateEventCount.ShouldBe(0);
+
+ await uow.CompleteAsync();
+ }
+
+ updateEventCount.ShouldBe(1);
+ updatedAge.ShouldBe(45);
+ }
}
}
diff --git a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json
index 44cebc1190..60d5f40634 100644
--- a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json
+++ b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json
@@ -1,4 +1,4 @@
-{
+{
"culture": "tr",
"texts": {
"UserName": "Kullanıcı adı",
@@ -11,10 +11,12 @@
"InvalidUserNameOrPassword": "Kullanıcı adı ya da şifre geçersiz!",
"LoginIsNotAllowed": "Giriş yapamazsınız! E-posta adresinizi ya da telefon numaranızı doğrulamanız gerekiyor.",
"SelfRegistrationDisabledMessage": "Bu uygulama için kullanıcıların kendi kendilerine kaydolmaları engellenmiştir. Yeni bir kullanıcı kaydetmek için lütfen uygulama yöneticisi ile iletişime geçin.",
+ "LocalLoginDisabledMessage": "Bu uygulama için local login devre dışı bırakılmıştır.",
"Login": "Giriş yap",
"Cancel": "İptal",
"Register": "Kayıt ol",
"AreYouANewUser": "Yeni bir kullanıcı mısınız?",
+ "AlreadyRegistered": "Zaten kayıtlı mı?",
"InvalidLoginRequest": "Başarısız giriş isteği",
"ThereAreNoLoginSchemesConfiguredForThisClient": "Bu client için konfigüre edilmiş giriş şeması bulunamadı.",
"LogInUsingYourProviderAccount": "{0} hesabınızla giriş yapın.",
@@ -34,6 +36,10 @@
"PasswordChanged": "Şifre değiştirildi",
"NewPasswordConfirmFailed": "Lütfen yeni şifreyi onaylayın.",
"Manage": "Manage",
- "ManageYourProfile": "Profilinizi yönetin"
+ "ManageYourProfile": "Profilinizi yönetin",
+ "DisplayName:Abp.Account.IsSelfRegistrationEnabled": "self-registration etkin mi ?",
+ "Description:Abp.Account.IsSelfRegistrationEnabled": "Bir kullanıcının hesabı kendisi tarafından kaydedip kaydedememesidir.",
+ "DisplayName:Abp.Account.EnableLocalLogin": "Yerel bir hesapla kimlik doğrulaması",
+ "Description:Abp.Account.EnableLocalLogin": "Sunucunun, kullanıcıların yerel bir hesapla kimlik doğrulamasına izin verip vermeyeceğini belirtir."
}
}
\ No newline at end of file
diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/tr.json b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/tr.json
index b4b6cba0be..78e18601ff 100644
--- a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/tr.json
+++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/tr.json
@@ -1,4 +1,4 @@
-{
+{
"culture": "tr",
"texts": {
"Menu:Blogs": "Bloglar",
@@ -20,7 +20,6 @@
"SeeAll": "Hepsini Gör",
"PopularTags": "Popüler Etiketler",
"WiewsWithCount": "{0} görüntüleme",
- "ShareOnTwitter": "Twitter'da paylaş",
"LastPosts": "Son Yazılar",
"LeaveComment": "Yorum Bırak",
"TagsInThisArticle": "Makalenin Etiketleri",
@@ -33,6 +32,7 @@
"AreYouSure": "Emin misiniz?",
"CommentWithCount": "{0} yorum",
"Comment": "Yorum",
+ "ShareOnTwitter": "Twitter'da paylaş",
"CoverImage": "Kapak resmi",
"CreateANewPost": "Yeni Yazı oluştur",
"CreateANewBlog": "Yeni Blog Ekle",
@@ -43,6 +43,7 @@
"Description": "Açıklama",
"Blogs": "Bloglar",
"Tags": "Etiketler",
- "ShareOn": "Paylaş"
+ "ShareOn": "Paylaş",
+ "TitleLengthWarning": "Başlığınınz SEO dostu olabilmesi için 60 karakterden az olmasını sağlayın!"
}
}
\ No newline at end of file
diff --git a/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/BloggingDomainModule.cs b/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/BloggingDomainModule.cs
index f39c4c88fb..3179303215 100644
--- a/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/BloggingDomainModule.cs
+++ b/modules/blogging/src/Volo.Blogging.Domain/Volo/Blogging/BloggingDomainModule.cs
@@ -1,7 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.Domain;
-using Volo.Abp.EventBus.Distributed;
+using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Modularity;
using Volo.Blogging.Blogs;
using Volo.Blogging.Comments;
@@ -25,7 +25,7 @@ namespace Volo.Blogging
options.AddProfile(validate: true);
});
- Configure(options =>
+ Configure(options =>
{
options.EtoMappings.Add(typeof(BloggingDomainModule));
options.EtoMappings.Add(typeof(BloggingDomainModule));
diff --git a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/tr.json b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/tr.json
index 8f49c6e952..c88e95867d 100644
--- a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/tr.json
+++ b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/tr.json
@@ -1,6 +1,7 @@
-{
+{
"culture": "tr",
"texts": {
+ "DocsTitle": "VoloDocs",
"WelcomeVoloDocs": "VoloDocs Hoşgeldiniz!",
"NoProjectWarning": "Henüz bir proje yok!",
"CreateYourFirstProject": "İlk projenizi oluşturmak için tıklayın",
diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/GetAllInput.cs b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/GetAllInput.cs
index ced1c1ceda..e375f6ba0b 100644
--- a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/GetAllInput.cs
+++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/GetAllInput.cs
@@ -12,10 +12,28 @@ namespace Volo.Docs.Admin.Documents
[StringLength(DocumentConsts.MaxNameLength)]
public string Name { get; set; }
+ [StringLength(DocumentConsts.MaxVersionNameLength)]
+ public string Version { get; set; }
+
[StringLength(DocumentConsts.MaxLanguageCodeNameLength)]
public string LanguageCode { get; set; }
- [StringLength(DocumentConsts.MaxVersionNameLength)]
- public string Version { get; set; }
+ [StringLength(DocumentConsts.MaxFileNameNameLength)]
+ public string FileName { get; set; }
+
+ [StringLength(DocumentConsts.MaxFormatNameLength)]
+ public string Format { get; set; }
+
+ public DateTime? CreationTimeMin { get; set; }
+ public DateTime? CreationTimeMax { get; set; }
+
+ public DateTime? LastUpdatedTimeMin { get; set; }
+ public DateTime? LastUpdatedTimeMax { get; set; }
+
+ public DateTime? LastSignificantUpdateTimeMin { get; set; }
+ public DateTime? LastSignificantUpdateTimeMax { get; set; }
+
+ public DateTime? LastCachedTimeMin { get; set; }
+ public DateTime? LastCachedTimeMax { get; set; }
}
}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/en.json b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/en.json
index 32d0b3bc27..b73f43317c 100644
--- a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/en.json
+++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/en.json
@@ -43,6 +43,16 @@
"ReIndexDocumentConfirmation": "Are you sure you want to reindex this item?",
"DeleteDocumentFromDbConfirmation": "Are you sure you want to delete this item from database?",
"DeleteFromDatabase": "Delete from database",
- "Deleted": "Deleted"
+ "Deleted": "Deleted",
+ "Search": "Search",
+ "StartDate": "Start date",
+ "EndDate": "End date",
+ "CreationTime": "Creation time",
+ "LastUpdateTime": "Last update",
+ "LastSignificantUpdateTime": "Last significant update",
+ "Version": "Version",
+ "LanguageCode": "Language code",
+ "FileName": "File name",
+ "LastCachedTime": "Cache time"
}
}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/tr.json b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/tr.json
index c40893e538..319a901004 100644
--- a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/tr.json
+++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/tr.json
@@ -1,4 +1,4 @@
-{
+{
"culture": "tr",
"texts": {
"Permission:DocumentManagement": "Döküman yönetimi",
@@ -7,6 +7,7 @@
"Permission:Delete": "Sil",
"Permission:Create": "Oluştur",
"Permission:Documents": "Döküman",
+ "Menu:Documents": "Dokümanlar",
"Menu:DocumentManagement": "Dökümanlar",
"Menu:ProjectManagement": "Projeler",
"CreateANewProject": "Yeni proje oluştur",
@@ -29,8 +30,19 @@
"DisplayName:LatestVersionBranchName": "Son versiyon Branch adı",
"DisplayName:GitHubRootUrl": "GitHub kök adresi",
"DisplayName:GitHubAccessToken": "GitHub erişim token",
+ "DisplayName:GitHubUserAgent": "GitHub kullanıcı temsilcisi",
"DisplayName:All": "Çekme bütün",
"DisplayName:LanguageCode": "Dil kodu",
- "DisplayName:Version": "versiyon"
+ "DisplayName:Version": "versiyon",
+ "Documents": "Dokümanlar",
+ "RemoveFromCache": "Önbellekten kaldır",
+ "Reindex": "Yeniden İndeksle",
+ "ReindexCompleted": "Yeniden indeksleme tamamlandı",
+ "RemovedFromCache": "Önbellekten kaldırıldı",
+ "RemoveFromCacheConfirmation": "Bu maddeyi önbellekten kaldırmak istediğiniz emin misiniz?",
+ "ReIndexDocumentConfirmation": "Bu maddeyi yeniden indekslemek istediğinize emin misiniz?",
+ "DeleteDocumentFromDbConfirmation": "Bu maddeyi veritabanından silmek istediğinize emin misiniz?",
+ "DeleteFromDatabase": "Veritabanından sil",
+ "Deleted": "Silindi"
}
}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs
index 0868e9eb80..cb6443d268 100644
--- a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs
+++ b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs
@@ -137,20 +137,40 @@ namespace Volo.Docs.Admin.Documents
public async Task> GetAllAsync(GetAllInput input)
{
var totalCount = await _documentRepository.GetAllCountAsync(
- projectId: input.ProjectId,
- name: input.Name,
- version: input.Version,
- languageCode: input.LanguageCode,
- sorting: input.Sorting,
- maxResultCount: input.MaxResultCount,
- skipCount: input.SkipCount
- );
+ projectId: input.ProjectId,
+ name: input.Name,
+ version: input.Version,
+ languageCode: input.LanguageCode,
+ fileName: input.FileName,
+ format: input.Format,
+ creationTimeMin: input.CreationTimeMin,
+ creationTimeMax: input.CreationTimeMax,
+ lastUpdatedTimeMin: input.LastUpdatedTimeMin,
+ lastUpdatedTimeMax: input.LastUpdatedTimeMax,
+ lastSignificantUpdateTimeMin: input.LastSignificantUpdateTimeMin,
+ lastSignificantUpdateTimeMax: input.LastSignificantUpdateTimeMax,
+ lastCachedTimeMin: input.LastCachedTimeMin,
+ lastCachedTimeMax: input.LastCachedTimeMax,
+ sorting: input.Sorting,
+ maxResultCount: input.MaxResultCount,
+ skipCount: input.SkipCount
+ );
var docs = await _documentRepository.GetAllAsync(
projectId: input.ProjectId,
name: input.Name,
version: input.Version,
languageCode: input.LanguageCode,
+ fileName: input.FileName,
+ format: input.Format,
+ creationTimeMin: input.CreationTimeMin,
+ creationTimeMax: input.CreationTimeMax,
+ lastUpdatedTimeMin: input.LastUpdatedTimeMin,
+ lastUpdatedTimeMax: input.LastUpdatedTimeMax,
+ lastSignificantUpdateTimeMin: input.LastSignificantUpdateTimeMin,
+ lastSignificantUpdateTimeMax: input.LastSignificantUpdateTimeMax,
+ lastCachedTimeMin: input.LastCachedTimeMin,
+ lastCachedTimeMax: input.LastCachedTimeMax,
sorting: input.Sorting,
maxResultCount: input.MaxResultCount,
skipCount: input.SkipCount
diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml
index 876d475dfc..1afd658afe 100644
--- a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml
+++ b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml
@@ -22,31 +22,194 @@
}
-
-
-
- Filters ...
- @*
-
- *@
-
-
-
-
-
-
- | @L["Actions"] |
- @L["Name"] |
- @L["Version"] |
- @L["LanguageCode"] |
- @L["FileName"] |
- @L["Format"] |
- @L["CreationTime"] |
- @L["LastUpdatedTime"] |
- @L["LastSignificantUpdateTime"] |
- @L["LastCachedTime"] |
-
-
-
-
-
+@section styles {
+
+}
+
+
+
+
+
+
+
+
+
+
+ | @L["Actions"] |
+ @L["Name"] |
+ @L["Version"] |
+ @L["LanguageCode"] |
+ @L["FileName"] |
+ @L["Format"] |
+ @L["CreationTime"] |
+ @L["LastUpdatedTime"] |
+ @L["LastSignificantUpdateTime"] |
+ @L["LastCachedTime"] |
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml.cs
index def325bd0d..559eaab5eb 100644
--- a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml.cs
+++ b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/Index.cshtml.cs
@@ -1,6 +1,9 @@
+using System;
+using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
+using Volo.Docs.Documents;
namespace Volo.Docs.Admin.Pages.Docs.Admin.Documents
{
diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.css b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.css
new file mode 100644
index 0000000000..006512da9a
--- /dev/null
+++ b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.css
@@ -0,0 +1,3 @@
+#DocumentsContainer .datepicker {
+ display: inline-block !important;
+ width: 7rem !important; }
diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.js b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.js
index ed5e5793de..dc77bbc687 100644
--- a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.js
+++ b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.js
@@ -1,8 +1,32 @@
$(function () {
var l = abp.localization.getResource('Docs');
+ var service = window.volo.docs.admin.documentsAdmin;
- var _dataTable = $('#DocumentsTable').DataTable(abp.libs.datatables.normalizeConfiguration({
+ var getFormattedDate = function ($datePicker) {
+ return $datePicker.data().datepicker.getFormattedDate("yyyy-mm-dd");
+ };
+
+ var getFilter = function () {
+ return {
+ projectId: $("#ProjectId").val(),
+ name: $("#Name").val(),
+ version: $("#Version").val(),
+ languageCode: $("#LanguageCode").val(),
+ fileName: $("#FileName").val(),
+ format: $("#Format").val(),
+ creationTimeMin: getFormattedDate($("#CreationTimeMin")),
+ creationTimeMax: getFormattedDate($("#CreationTimeMax")),
+ lastUpdatedTimeMin: getFormattedDate($("#LastUpdatedTimeMin")),
+ lastUpdatedTimeMax: getFormattedDate($("#LastUpdatedTimeMax")),
+ lastSignificantUpdateTimeMin: getFormattedDate($("#LastSignificantUpdateTimeMin")),
+ lastSignificantUpdateTimeMax: getFormattedDate($("#LastSignificantUpdateTimeMax")),
+ lastCachedTimeMin: getFormattedDate($("#LastCachedTimeMin")),
+ lastCachedTimeMax: getFormattedDate($("#LastCachedTimeMax"))
+ };
+ };
+
+ var dataTable = $('#DocumentsTable').DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
scrollX: true,
@@ -10,7 +34,7 @@
searching: false,
autoWidth: false,
scrollCollapse: true,
- ajax: abp.libs.datatables.createAjax(volo.docs.admin.documentsAdmin.getAll),
+ ajax: abp.libs.datatables.createAjax(service.getAll, getFilter),
columnDefs: [
{
rowAction: {
@@ -21,11 +45,10 @@
visible: abp.auth.isGranted('Docs.Admin.Documents'),
confirmMessage: function (data) { return l('RemoveFromCacheConfirmation'); },
action: function (data) {
- volo.docs.admin.documentsAdmin
- .removeFromCache(data.record.id)
+ service.removeFromCache(data.record.id)
.then(function () {
abp.message.success(l('RemovedFromCache'));
- _dataTable.ajax.reload();
+ dataTable.ajax.reload();
});
}
},
@@ -34,11 +57,10 @@
visible: abp.auth.isGranted('Docs.Admin.Documents'),
confirmMessage: function (data) { return l('ReIndexDocumentConfirmation'); },
action: function (data) {
- volo.docs.admin.documentsAdmin
- .reindex(data.record.id)
+ service.reindex(data.record.id)
.then(function () {
abp.message.success(l('ReindexCompleted'));
- _dataTable.ajax.reload();
+ dataTable.ajax.reload();
});
}
},
@@ -47,11 +69,10 @@
visible: abp.auth.isGranted('Docs.Admin.Documents'),
confirmMessage: function (data) { return l('DeleteDocumentFromDbConfirmation'); },
action: function (data) {
- volo.docs.admin.documentsAdmin
- .deleteFromDatabase(data.record.id)
+ service.deleteFromDatabase(data.record.id)
.then(function () {
abp.message.success(l('Deleted'));
- _dataTable.ajax.reload();
+ dataTable.ajax.reload();
});
}
}
@@ -76,14 +97,7 @@
},
{
target: 5,
- data: "format",
- render: function (data) {
- if (data === 'md') {
- return 'markdown';
- }
-
- return data;
- }
+ data: "format"
},
{
target: 6,
@@ -136,18 +150,15 @@
]
}));
+ $("#FilterForm input[type='text']").keypress(function (e) {
+ if (e.which === 13) {
+ dataTable.ajax.reload();
+ }
+ });
- $("#ReIndexAllProjects").click(function (event) {
- abp.message.confirm(l('ReIndexAllProjectConfirmationMessage'))
- .done(function (accepted) {
- if (accepted) {
- volo.docs.admin.projectsAdmin
- .reindexAll()
- .then(function () {
- abp.message.success(l('SuccessfullyReIndexAllProject'));
- });
- }
- });
+ $("#SearchButton").click(function (e) {
+ e.preventDefault();
+ dataTable.ajax.reload();
});
});
diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.min.css b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.min.css
new file mode 100644
index 0000000000..f98ba4beab
--- /dev/null
+++ b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.min.css
@@ -0,0 +1 @@
+#DocumentsContainer .datepicker{display:inline-block !important;width:7rem !important;}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.scss b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.scss
new file mode 100644
index 0000000000..97147313df
--- /dev/null
+++ b/modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Documents/index.scss
@@ -0,0 +1,6 @@
+#DocumentsContainer {
+ .datepicker {
+ display: inline-block !important;
+ width: 7rem !important;
+ }
+}
diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.csproj b/modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.csproj
index 3098bab9d0..164c28cdb2 100644
--- a/modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.csproj
+++ b/modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.csproj
@@ -13,13 +13,16 @@
2.8
+
+
+
+
-
@@ -29,8 +32,7 @@
-
-
+
diff --git a/modules/docs/src/Volo.Docs.Admin.Web/compilerconfig.json b/modules/docs/src/Volo.Docs.Admin.Web/compilerconfig.json
new file mode 100644
index 0000000000..32ae3754e2
--- /dev/null
+++ b/modules/docs/src/Volo.Docs.Admin.Web/compilerconfig.json
@@ -0,0 +1,6 @@
+[
+ {
+ "outputFile": "Pages/Docs/Admin/Documents/index.css",
+ "inputFile": "Pages/Docs/Admin/Documents/index.scss"
+ }
+]
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Admin.Web/compilerconfig.json.defaults b/modules/docs/src/Volo.Docs.Admin.Web/compilerconfig.json.defaults
new file mode 100644
index 0000000000..b3519312c4
--- /dev/null
+++ b/modules/docs/src/Volo.Docs.Admin.Web/compilerconfig.json.defaults
@@ -0,0 +1,63 @@
+{
+ "compilers": {
+ "less": {
+ "autoPrefix": "",
+ "cssComb": "none",
+ "ieCompat": true,
+ "strictMath": false,
+ "strictUnits": false,
+ "relativeUrls": true,
+ "rootPath": "",
+ "sourceMapRoot": "",
+ "sourceMapBasePath": "",
+ "sourceMap": false
+ },
+ "sass": {
+ "autoPrefix": "",
+ "includePath": "",
+ "indentType": "space",
+ "indentWidth": 2,
+ "outputStyle": "nested",
+ "Precision": 5,
+ "relativeUrls": true,
+ "sourceMapRoot": "",
+ "lineFeed": "",
+ "sourceMap": false
+ },
+ "stylus": {
+ "sourceMap": false
+ },
+ "babel": {
+ "sourceMap": false
+ },
+ "coffeescript": {
+ "bare": false,
+ "runtimeMode": "node",
+ "sourceMap": false
+ },
+ "handlebars": {
+ "root": "",
+ "noBOM": false,
+ "name": "",
+ "namespace": "",
+ "knownHelpersOnly": false,
+ "forcePartial": false,
+ "knownHelpers": [],
+ "commonjs": "",
+ "amd": false,
+ "sourceMap": false
+ }
+ },
+ "minifiers": {
+ "css": {
+ "enabled": true,
+ "termSemicolons": true,
+ "gzip": false
+ },
+ "javascript": {
+ "enabled": true,
+ "termSemicolons": true,
+ "gzip": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs
index 5e53b858ce..ecc52d1f26 100644
--- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs
@@ -4,7 +4,7 @@ using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.AutoMapper;
using Volo.Abp.Domain;
-using Volo.Abp.EventBus.Distributed;
+using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Threading;
@@ -34,7 +34,7 @@ namespace Volo.Docs
options.AddProfile(validate: true);
});
- Configure(options =>
+ Configure(options =>
{
options.EtoMappings.Add(typeof(DocsDomainModule));
options.EtoMappings.Add(typeof(DocsDomainModule));
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs
index c09cb261ec..3773775b88 100644
--- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs
@@ -23,10 +23,21 @@ namespace Volo.Docs.Documents
string version,
CancellationToken cancellationToken = default);
- Task> GetAllAsync(Guid? projectId,
+ Task> GetAllAsync(
+ Guid? projectId,
string name,
string version,
string languageCode,
+ string fileName,
+ string format,
+ DateTime? creationTimeMin,
+ DateTime? creationTimeMax,
+ DateTime? lastUpdatedTimeMin,
+ DateTime? lastUpdatedTimeMax,
+ DateTime? lastSignificantUpdateTimeMin,
+ DateTime? lastSignificantUpdateTimeMax,
+ DateTime? lastCachedTimeMin,
+ DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
@@ -37,6 +48,16 @@ namespace Volo.Docs.Documents
string name,
string version,
string languageCode,
+ string fileName,
+ string format,
+ DateTime? creationTimeMin,
+ DateTime? creationTimeMax,
+ DateTime? lastUpdatedTimeMin,
+ DateTime? lastUpdatedTimeMax,
+ DateTime? lastSignificantUpdateTimeMin,
+ DateTime? lastSignificantUpdateTimeMax,
+ DateTime? lastCachedTimeMin,
+ DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json
index 612274f95d..f41a049932 100644
--- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json
@@ -1,4 +1,4 @@
-{
+{
"culture": "tr",
"texts": {
"Documents": "Dökümanlar",
@@ -9,17 +9,30 @@
"Edit": "Düzenle",
"LastEditTime": "Son Düzenleme",
"Delete": "Sil",
+ "ClearCache": "Önbelleği temizle",
+ "ClearCacheConfirmationMessage": "\"{0}\" Projesinin tüm önbelliğini temizlemek istediğinize emin misiniz? ",
+ "ReIndexAllProjects": "Tüm projeleri yeniden indexle",
+ "ReIndexProject": "Projeyi yeniden indeksle",
+ "ReIndexProjectConfirmationMessage": "\"{0}\" Projesini yeniden insdekslemek istediğinize emin misiniz?",
+ "SuccessfullyReIndexProject": "\"{0}\" Projesi başarıyla yeniden indekslendi",
+ "ReIndexAllProjectConfirmationMessage": "Tüm projeleri yeniden indekslemek istediğinize emin misiniz?",
+ "SuccessfullyReIndexAllProject": "Tüm projeler başarıyla yeniden indekslendi",
"InThisDocument": "Bu dökümanda",
"GoToTop": "En üste çık",
"Projects": "Proje(ler)",
"NoProjectWarning": "Hiç proje yok!",
"DocumentNotFound": "Aradığınız döküman bulunamadı!",
+ "ProjectNotFound": "Talep edilen proje bulunamadı!",
"NavigationDocumentNotFound": "Bu döküman için menü bulunamadı!",
"DocumentNotFoundInSelectedLanguage": "İstediğiniz dilde belge bulunamadı. Varsayılan dilde belge gösterilir.",
+ "FilterTopics": "Konuları Filtrele",
+ "FullSearch": "Dokümanlarda Ara",
+ "Volo.Docs.Domain:010001": "Elastic search etkin değil",
"MultipleVersionDocumentInfo": "Bu dökümanın birden çok versiyonu bulunmaktadır. Sizin için en uygun olan seçenekleri seçiniz.",
"New": "Yeni",
"Upd": "Günc",
"NewExplanation": "Son iki hafta içinde oluşturuldu.",
- "UpdatedExplanation": "Son iki hafta içinde güncellendi."
+ "UpdatedExplanation": "Son iki hafta içinde güncellendi.",
+ "Volo.Docs.Domain:010002": "ShortName {ShortName} zaten var."
}
}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs b/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs
index 46145043b1..f096bc10d9 100644
--- a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs
+++ b/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs
@@ -24,16 +24,44 @@ namespace Volo.Docs.Documents
return await DbSet.Where(d => d.ProjectId == projectId).ToListAsync(cancellationToken: cancellationToken);
}
- public async Task> GetAllAsync(Guid? projectId,
+ public async Task> GetAllAsync(
+ Guid? projectId,
string name,
string version,
string languageCode,
+ string fileName,
+ string format,
+ DateTime? creationTimeMin,
+ DateTime? creationTimeMax,
+ DateTime? lastUpdatedTimeMin,
+ DateTime? lastUpdatedTimeMax,
+ DateTime? lastSignificantUpdateTimeMin,
+ DateTime? lastSignificantUpdateTimeMax,
+ DateTime? lastCachedTimeMin,
+ DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
- var query = ApplyFilterForGetAll(DbSet, projectId, name, version, languageCode);
+ var query = ApplyFilterForGetAll(
+ DbSet,
+ projectId: projectId,
+ name: name,
+ version: version,
+ languageCode: languageCode,
+ format: format,
+ fileName: fileName,
+ creationTimeMin: creationTimeMin,
+ creationTimeMax: creationTimeMax,
+ lastUpdatedTimeMin: lastUpdatedTimeMin,
+ lastUpdatedTimeMax: lastUpdatedTimeMax,
+ lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
+ lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
+ lastCachedTimeMin: lastCachedTimeMin,
+ lastCachedTimeMax: lastCachedTimeMax
+ );
+
query = query.OrderBy(string.IsNullOrWhiteSpace(sorting) ? nameof(Document.Name) : sorting);
return await query.PageBy(skipCount, maxResultCount).ToListAsync(cancellationToken);
}
@@ -43,12 +71,39 @@ namespace Volo.Docs.Documents
string name,
string version,
string languageCode,
+ string fileName,
+ string format,
+ DateTime? creationTimeMin,
+ DateTime? creationTimeMax,
+ DateTime? lastUpdatedTimeMin,
+ DateTime? lastUpdatedTimeMax,
+ DateTime? lastSignificantUpdateTimeMin,
+ DateTime? lastSignificantUpdateTimeMax,
+ DateTime? lastCachedTimeMin,
+ DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
- var query = ApplyFilterForGetAll(DbSet, projectId, name, version, languageCode);
+ var query = ApplyFilterForGetAll(
+ DbSet,
+ projectId: projectId,
+ name: name,
+ version: version,
+ languageCode: languageCode,
+ format: format,
+ fileName: fileName,
+ creationTimeMin: creationTimeMin,
+ creationTimeMax: creationTimeMax,
+ lastUpdatedTimeMin: lastUpdatedTimeMin,
+ lastUpdatedTimeMax: lastUpdatedTimeMax,
+ lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
+ lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
+ lastCachedTimeMin: lastCachedTimeMin,
+ lastCachedTimeMax: lastCachedTimeMax
+ );
+
return await query.LongCountAsync(GetCancellationToken(cancellationToken));
}
@@ -81,13 +136,47 @@ namespace Volo.Docs.Documents
string name,
string version,
string languageCode,
+ string fileName,
+ string format,
+ DateTime? creationTimeMin,
+ DateTime? creationTimeMax,
+ DateTime? lastUpdatedTimeMin,
+ DateTime? lastUpdatedTimeMax,
+ DateTime? lastSignificantUpdateTimeMin,
+ DateTime? lastSignificantUpdateTimeMax,
+ DateTime? lastCachedTimeMin,
+ DateTime? lastCachedTimeMax,
CancellationToken cancellationToken = default)
{
return DbSet
- .WhereIf(projectId.HasValue, d => d.ProjectId == projectId.Value)
- .WhereIf(name != null, d => d.Name != null && d.Name.Contains(name))
- .WhereIf(version != null, d => d.Version != null && d.Version == version)
- .WhereIf(languageCode != null, d => d.LanguageCode != null && d.LanguageCode == languageCode);
+ .WhereIf(projectId.HasValue,
+ d => d.ProjectId == projectId.Value)
+ .WhereIf(name != null,
+ d => d.Name != null && d.Name.Contains(name))
+ .WhereIf(version != null,
+ d => d.Version != null && d.Version == version)
+ .WhereIf(languageCode != null,
+ d => d.LanguageCode != null && d.LanguageCode == languageCode)
+ .WhereIf(fileName != null,
+ d => d.FileName != null && d.FileName.Contains(fileName))
+ .WhereIf(format != null,
+ d => d.Format != null && d.Format == format)
+ .WhereIf(creationTimeMin.HasValue,
+ d => d.CreationTime.Date >= creationTimeMin.Value.Date)
+ .WhereIf(creationTimeMax.HasValue,
+ d => d.CreationTime.Date <= creationTimeMax.Value.Date)
+ .WhereIf(lastUpdatedTimeMin.HasValue,
+ d => d.LastUpdatedTime.Date >= lastUpdatedTimeMin.Value.Date)
+ .WhereIf(lastUpdatedTimeMax.HasValue,
+ d => d.LastUpdatedTime.Date <= lastUpdatedTimeMax.Value.Date)
+ .WhereIf(lastSignificantUpdateTimeMin.HasValue,
+ d => d.LastSignificantUpdateTime != null && d.LastSignificantUpdateTime.Value.Date >= lastSignificantUpdateTimeMin.Value.Date)
+ .WhereIf(lastSignificantUpdateTimeMax.HasValue,
+ d => d.LastSignificantUpdateTime != null && d.LastSignificantUpdateTime.Value.Date <= lastSignificantUpdateTimeMax.Value.Date)
+ .WhereIf(lastCachedTimeMin.HasValue,
+ d => d.LastCachedTime.Date >= lastCachedTimeMin.Value.Date)
+ .WhereIf(lastCachedTimeMax.HasValue,
+ d => d.LastCachedTime.Date <= lastCachedTimeMax.Value.Date);
}
}
}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs b/modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs
index 78710e553e..b3b5210986 100644
--- a/modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs
+++ b/modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs
@@ -43,33 +43,88 @@ namespace Volo.Docs.Documents
x.Version == version, cancellationToken: cancellationToken);
}
- public async Task> GetAllAsync(Guid? projectId,
+ public async Task> GetAllAsync(
+ Guid? projectId,
string name,
string version,
string languageCode,
+ string fileName,
+ string format,
+ DateTime? creationTimeMin,
+ DateTime? creationTimeMax,
+ DateTime? lastUpdatedTimeMin,
+ DateTime? lastUpdatedTimeMax,
+ DateTime? lastSignificantUpdateTimeMin,
+ DateTime? lastSignificantUpdateTimeMax,
+ DateTime? lastCachedTimeMin,
+ DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
+
return await
- ApplyFilterForGetAll(GetMongoQueryable(), projectId, name, version, languageCode)
- .OrderBy(string.IsNullOrWhiteSpace(sorting) ? "name asc" : sorting).As>()
- .PageBy>(skipCount, maxResultCount)
- .ToListAsync(GetCancellationToken(cancellationToken));
+ ApplyFilterForGetAll(
+ GetMongoQueryable(),
+ projectId: projectId,
+ name: name,
+ version: version,
+ languageCode: languageCode,
+ format: format,
+ fileName: fileName,
+ creationTimeMin: creationTimeMin,
+ creationTimeMax: creationTimeMax,
+ lastUpdatedTimeMin: lastUpdatedTimeMin,
+ lastUpdatedTimeMax: lastUpdatedTimeMax,
+ lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
+ lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
+ lastCachedTimeMin: lastCachedTimeMin,
+ lastCachedTimeMax: lastCachedTimeMax)
+ .OrderBy(string.IsNullOrWhiteSpace(sorting) ? "name asc" : sorting).As>()
+ .PageBy>(skipCount, maxResultCount)
+ .ToListAsync(GetCancellationToken(cancellationToken));
}
- public async Task GetAllCountAsync(Guid? projectId,
+ public async Task GetAllCountAsync(
+ Guid? projectId,
string name,
string version,
string languageCode,
+ string fileName,
+ string format,
+ DateTime? creationTimeMin,
+ DateTime? creationTimeMax,
+ DateTime? lastUpdatedTimeMin,
+ DateTime? lastUpdatedTimeMax,
+ DateTime? lastSignificantUpdateTimeMin,
+ DateTime? lastSignificantUpdateTimeMax,
+ DateTime? lastCachedTimeMin,
+ DateTime? lastCachedTimeMax,
string sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
+
+
return await
- ApplyFilterForGetAll(GetMongoQueryable(), projectId, name, version, languageCode)
+ ApplyFilterForGetAll(
+ GetMongoQueryable(),
+ projectId: projectId,
+ name: name,
+ version: version,
+ languageCode: languageCode,
+ format: format,
+ fileName: fileName,
+ creationTimeMin: creationTimeMin,
+ creationTimeMax: creationTimeMax,
+ lastUpdatedTimeMin: lastUpdatedTimeMin,
+ lastUpdatedTimeMax: lastUpdatedTimeMax,
+ lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
+ lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
+ lastCachedTimeMin: lastCachedTimeMin,
+ lastCachedTimeMax: lastCachedTimeMax)
.OrderBy(string.IsNullOrWhiteSpace(sorting) ? "name asc" : sorting).As>()
.PageBy>(skipCount, maxResultCount)
.LongCountAsync(GetCancellationToken(cancellationToken));
@@ -86,6 +141,16 @@ namespace Volo.Docs.Documents
string name,
string version,
string languageCode,
+ string fileName,
+ string format,
+ DateTime? creationTimeMin,
+ DateTime? creationTimeMax,
+ DateTime? lastUpdatedTimeMin,
+ DateTime? lastUpdatedTimeMax,
+ DateTime? lastSignificantUpdateTimeMin,
+ DateTime? lastSignificantUpdateTimeMax,
+ DateTime? lastCachedTimeMin,
+ DateTime? lastCachedTimeMax,
CancellationToken cancellationToken = default)
{
if (projectId.HasValue)
@@ -108,6 +173,51 @@ namespace Volo.Docs.Documents
query = query.Where(d => d.LanguageCode != null && d.LanguageCode == languageCode);
}
+ if (fileName != null)
+ {
+ query = query.Where(d => d.FileName != null && d.FileName.Contains(fileName));
+ }
+
+ if (creationTimeMin.HasValue)
+ {
+ query = query.Where(d => d.CreationTime.Date >= creationTimeMin.Value.Date);
+ }
+
+ if (creationTimeMax.HasValue)
+ {
+ query = query.Where(d => d.CreationTime.Date <= creationTimeMax.Value.Date);
+ }
+
+ if (lastUpdatedTimeMin.HasValue)
+ {
+ query = query.Where(d => d.LastUpdatedTime.Date >= lastUpdatedTimeMin.Value.Date);
+ }
+
+ if (lastUpdatedTimeMax.HasValue)
+ {
+ query = query.Where(d => d.LastUpdatedTime.Date <= lastUpdatedTimeMax.Value.Date);
+ }
+
+ if (lastSignificantUpdateTimeMin.HasValue)
+ {
+ query = query.Where(d => d.LastSignificantUpdateTime != null && d.LastSignificantUpdateTime.Value.Date >= lastSignificantUpdateTimeMin.Value.Date);
+ }
+
+ if (lastSignificantUpdateTimeMax.HasValue)
+ {
+ query = query.Where(d => d.LastSignificantUpdateTime != null && d.LastSignificantUpdateTime.Value.Date <= lastSignificantUpdateTimeMax.Value.Date);
+ }
+
+ if (lastCachedTimeMin.HasValue)
+ {
+ query = query.Where(d => d.LastCachedTime.Date >= lastCachedTimeMin.Value.Date);
+ }
+
+ if (lastCachedTimeMax.HasValue)
+ {
+ query = query.Where(d => d.LastCachedTime.Date <= lastCachedTimeMax.Value.Date);
+ }
+
return query;
}
}
diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
index 7f521de34b..90a754b1a9 100644
--- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
+++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
@@ -131,10 +131,10 @@
- @if (Model.FullSearchEnabled)
- {
-