allow more actions on store ops

This commit is contained in:
2022-03-03 15:03:29 +01:00
parent a07e42986e
commit 4bed7a3c41
10 changed files with 78 additions and 30 deletions
@@ -108,7 +108,7 @@
// called when an action has been clicked
onActionClicked(action, opts)
{
action.call(opts);
action.call(opts, this);
},
@@ -294,16 +294,17 @@ a.ui-table-row:hover, button.ui-table-row:hover
padding: 4px 12px;
border-radius: 20px;
&[data-state="completed"], &[data-state="cancelled"]
&[data-state="completed"], &[data-state="cancelled"],
&[data-state="none"], &[data-state="captured"], &[data-state="authorized"], &[data-state="cancelled"], &[data-state="refunded"]
{
font-weight: 400;
color: var(--color-text-dim);
}
/*&[data-payment-state="none"], &[data-payment-state="pending"], &[data-payment-state="cancelled"], &[data-payment-state="refunded"]
&[data-state="error"]
{
font-weight: 400;
color: var(--color-text-dim);
}*/
color: var(--color-accent-error);
background: var(--color-accent-error-bg);
}
&[data-payment-state]
{
font-weight: 400;
@@ -23,9 +23,9 @@ class ListAction
* Calls the action
* @returns {ListColumn}
*/
call(options)
call(options, cmp)
{
this.action(options);
this.action(options, cmp);
}
}
@@ -49,8 +49,7 @@ public class ZeroTokenProvider : IZeroTokenProvider
await session.StoreAsync(securityToken);
// set the expires flag for the token
IMetadataDictionary tokenMetadata = session.Advanced.GetMetadataFor(securityToken);
tokenMetadata[Constants.Database.Expires] = DateTime.UtcNow.AddSeconds(expires.TotalSeconds);
session.Expires(securityToken, expires);
await session.SaveChangesAsync();
return tokenKey;
@@ -0,0 +1,14 @@
namespace zero.Persistence;
public static class ZeroDocumentSessionExtensions
{
public static void SetCollection<T>(this IZeroDocumentSession session, T model, string collectionName)
{
session.Advanced.GetMetadataFor(model)[Raven.Client.Constants.Documents.Metadata.Collection] = collectionName;
}
public static void Expires<T>(this IZeroDocumentSession session, T model, TimeSpan expires)
{
session.Advanced.GetMetadataFor(model)[Raven.Client.Constants.Documents.Metadata.Expires] = DateTime.UtcNow.AddSeconds(expires.TotalSeconds);
}
}
+4 -4
View File
@@ -67,10 +67,10 @@ public abstract class EntityStore<T> : IEntityStore<T> where T : ZeroIdEntity, I
public virtual string GetChangeToken(T model) => Operations.GetChangeToken(model);
/// <inheritdoc />
public virtual Task<Result<T>> Create(T model) => Operations.Create(model, async m => await Validate(m));
public virtual Task<Result<T>> Create(T model, Action<IZeroDocumentSession> onAfterStore = null) => Operations.Create(model, async m => await Validate(m), onAfterStore);
/// <inheritdoc />
public virtual Task<Result<T>> Update(T model) => Operations.Update(model, async m => await Validate(m));
public virtual Task<Result<T>> Update(T model, Action<IZeroDocumentSession> onAfterStore = null) => Operations.Update(model, async m => await Validate(m), onAfterStore);
/// <inheritdoc />
public virtual Task<Result<IOrderedEnumerable<T>>> Sort(string[] sortedIds) => Operations.Sort<T>(sortedIds);
@@ -171,12 +171,12 @@ public interface IEntityStore<T> where T : ZeroIdEntity, ISupportsFlavors, ISupp
/// <summary>
/// Creates an entity with an optional validator
/// </summary>
Task<Result<T>> Create(T model);
Task<Result<T>> Create(T model, Action<IZeroDocumentSession> onAfterStore = null);
/// <summary>
/// Updates an entity with an optional validator
/// </summary>
Task<Result<T>> Update(T model);
Task<Result<T>> Update(T model, Action<IZeroDocumentSession> onAfterStore = null);
/// <summary>
/// Update sorting of entities on a specific level
+5 -2
View File
@@ -12,14 +12,17 @@ public partial class StoreOperations : IStoreOperations
InterceptorInstruction<T> instruction = Interceptors.ForDelete(model);
if (!await instruction.Start(this))
if (InterceptorBlocker == null && !await instruction.Start(this))
{
return instruction.Result;
}
Session.Delete(model);
await Session.SaveChangesAsync();
await instruction.Complete();
if (InterceptorBlocker == null)
{
await instruction.Complete();
}
await Session.SaveChangesAsync();
return Result<T>.Success();
+9 -5
View File
@@ -5,13 +5,13 @@ namespace zero.Stores;
public partial class StoreOperations : IStoreOperations
{
/// <inheritdoc />
public virtual Task<Result<T>> Create<T>(T model, Func<T, Task<ValidationResult>> validate = null) where T : ZeroIdEntity, new() => Save(model, validate);
public virtual Task<Result<T>> Create<T>(T model, Func<T, Task<ValidationResult>> validate = null, Action<IZeroDocumentSession> onAfterStore = null) where T : ZeroIdEntity, new() => Save(model, validate, onAfterStore);
/// <inheritdoc />
public virtual Task<Result<T>> Update<T>(T model, Func<T, Task<ValidationResult>> validate = null) where T : ZeroIdEntity, new() => Save(model, validate);
public virtual Task<Result<T>> Update<T>(T model, Func<T, Task<ValidationResult>> validate = null, Action<IZeroDocumentSession> onAfterStore = null) where T : ZeroIdEntity, new() => Save(model, validate, onAfterStore);
/// <inheritdoc />
protected virtual async Task<Result<T>> Save<T>(T model, Func<T, Task<ValidationResult>> validate = null) where T : ZeroIdEntity, new()
protected virtual async Task<Result<T>> Save<T>(T model, Func<T, Task<ValidationResult>> validate = null, Action<IZeroDocumentSession> onAfterStore = null) where T : ZeroIdEntity, new()
{
if (model == null)
{
@@ -69,15 +69,19 @@ public partial class StoreOperations : IStoreOperations
// run interceptor
InterceptorInstruction<T> instruction = isUpdate ? Interceptors.ForUpdate(model, previousModel) : Interceptors.ForCreate(model);
if (!await instruction.Start(this))
if (InterceptorBlocker == null && !await instruction.Start(this))
{
return instruction.Result;
}
// store our model
await Session.StoreAsync(model);
onAfterStore?.Invoke(Session);
await Session.SaveChangesAsync();
await instruction.Complete();
if (InterceptorBlocker == null)
{
await instruction.Complete();
}
await Session.SaveChangesAsync();
return Result<T>.Success(model);
+32 -5
View File
@@ -28,6 +28,8 @@ public partial class StoreOperations :
protected IServiceProvider Services { get; private set; }
protected StoreInterceptorBlocker InterceptorBlocker { get; private set; }
string _overrideDatabase = null;
@@ -98,9 +100,7 @@ public partial class StoreOperations :
}
/// <summary>
/// Validates an entity
/// </summary>
/// <inheritdoc />
public async Task<ValidationResult> Validate<T>(T model) where T : ZeroIdEntity, new()
{
IZeroMergedValidator<T> validator = Services.GetService<IZeroMergedValidator<T>>();
@@ -114,6 +114,13 @@ public partial class StoreOperations :
}
/// <inheritdoc />
public StoreInterceptorBlocker WithoutInterceptors()
{
return InterceptorBlocker ?? (InterceptorBlocker = new(() => InterceptorBlocker = null));
}
/// <summary>
/// Do only return the model when it is set to active or inactive entities are included with IncludeInactive()
/// </summary>
@@ -124,6 +131,21 @@ public partial class StoreOperations :
}
public class StoreInterceptorBlocker : IDisposable
{
Action _onRelease;
internal StoreInterceptorBlocker(Action onRelease)
{
_onRelease = onRelease;
}
public void Dispose()
{
_onRelease();
}
}
public interface IStoreOperations
{
@@ -211,15 +233,20 @@ public interface IStoreOperations
/// </summary>
Task<ValidationResult> Validate<T>(T model) where T : ZeroIdEntity, new();
/// <summary>
/// Do not run interceptors for create/update/delete operations while this disposable is active
/// </summary>
StoreInterceptorBlocker WithoutInterceptors();
/// <summary>
/// Creates an entity with an optional validator
/// </summary>
Task<Result<T>> Create<T>(T model, Func<T, Task<ValidationResult>> validate = null) where T : ZeroIdEntity, new();
Task<Result<T>> Create<T>(T model, Func<T, Task<ValidationResult>> validate = null, Action<IZeroDocumentSession> onAfterStore = null) where T : ZeroIdEntity, new();
/// <summary>
/// Updates an entity with an optional validator
/// </summary>
Task<Result<T>> Update<T>(T model, Func<T, Task<ValidationResult>> validate = null) where T : ZeroIdEntity, new();
Task<Result<T>> Update<T>(T model, Func<T, Task<ValidationResult>> validate = null, Action<IZeroDocumentSession> onAfterStore = null) where T : ZeroIdEntity, new();
/// <inheritdoc />
Task<Result<IOrderedEnumerable<T>>> Sort<T>(string[] sortedIds) where T : ZeroIdEntity, ISupportsSorting, new();
+4 -4
View File
@@ -9,23 +9,23 @@ public abstract class TreeEntityStore<T> : EntityStore<T>, ITreeEntityStore<T> w
/// <inheritdoc />
public override async Task<Result<T>> Create(T model)
public override async Task<Result<T>> Create(T model, Action<IZeroDocumentSession> onAfterStore = null)
{
if (!await IsAllowedAsChild(model, model.ParentId))
{
return Result<T>.Fail("@errors.treeentity.parentnotallowed");
}
return await base.Create(model);
return await base.Create(model, onAfterStore);
}
/// <inheritdoc />
public override async Task<Result<T>> Update(T model)
public override async Task<Result<T>> Update(T model, Action<IZeroDocumentSession> onAfterStore = null)
{
if (!await IsAllowedAsChild(model, model.ParentId))
{
return Result<T>.Fail("@errors.treeentity.parentnotallowed");
}
return await base.Update(model);
return await base.Update(model, onAfterStore);
}
/// <inheritdoc />