Skip to content

Commit

Permalink
fix(Dashboard): refactored dashboard components improving use of reac…
Browse files Browse the repository at this point in the history
…tive programming

Signed-off-by: Jean-Baptiste Bianchi <[email protected]>
  • Loading branch information
JBBianchi committed Jun 19, 2024
1 parent d1454b5 commit 9475cb0
Show file tree
Hide file tree
Showing 34 changed files with 1,072 additions and 460 deletions.
2 changes: 1 addition & 1 deletion src/api/Synapse.Api.Server/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"ServeDashboard": true,
"Authentication": {
"Tokens": {
"h0v0fixhkg9z4bgtxele7892x9sjtw7o": {
"debug": {
"sub": "fc4c86cd-e4ff-463c-b0e4-36f34f795d7e",
"name": "root",
"role": "admin"
Expand Down
29 changes: 11 additions & 18 deletions src/dashboard/Synapse.Dashboard.StateManagement/ActionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,23 @@ namespace Synapse.Dashboard.StateManagement;
/// <summary>
/// Represents the default implementation of the <see cref="IActionContext"/> interface
/// </summary>
public class ActionContext
: IActionContext
/// <remarks>
/// Initializes a new <see cref="ActionContext"/>
/// </remarks>
/// <param name="services">The current <see cref="IServiceProvider"/></param>
/// <param name="store">The current <see cref="IStore"/></param>
/// <param name="action">The action to dispatch</param>
public class ActionContext(IServiceProvider services, IStore store, object action)
: IActionContext
{

/// <summary>
/// Initializes a new <see cref="ActionContext"/>
/// </summary>
/// <param name="services">The current <see cref="IServiceProvider"/></param>
/// <param name="store">The current <see cref="IStore"/></param>
/// <param name="action">The action to dispatch</param>
public ActionContext(IServiceProvider services, IStore store, object action)
{
this.Services = services;
this.Store = store;
this.Action = action;
}

/// <inheritdoc/>
public IServiceProvider Services { get; }
public IServiceProvider Services { get; } = services;

/// <inheritdoc/>
public IStore Store { get; }
public IStore Store { get; } = store;

/// <inheritdoc/>
public object Action { get; set; }
public object Action { get; set; } = action;

}
49 changes: 21 additions & 28 deletions src/dashboard/Synapse.Dashboard.StateManagement/ComponentStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,21 @@ namespace Synapse.Dashboard.StateManagement;
/// Represents the base class for all component stores
/// </summary>
/// <typeparam name="TState">The type of the component store's state</typeparam>
public abstract class ComponentStore<TState>
/// <remarks>
/// Initializes a new <see cref="ComponentStore{TState}"/>
/// </remarks>
/// <param name="state">The store's initial state</param>
public abstract class ComponentStore<TState>(TState state)
: IComponentStore<TState>
{
private BehaviorSubject<TState> _Subject;
private TState _State;
private bool _Disposed;

/// <summary>
/// Initializes a new <see cref="ComponentStore{TState}"/>
/// </summary>
/// <param name="state">The store's initial state</param>
protected ComponentStore(TState state)
{
this.CancellationTokenSource = new CancellationTokenSource();
this._State = state;
this._Subject = new(state);
}
private readonly BehaviorSubject<TState> _subject = new(state);
private TState _state = state;
private bool _disposed;

/// <summary>
/// Gets the <see cref="ComponentStore{TState}"/>'s <see cref="System.Threading.CancellationTokenSource"/>
/// </summary>
protected CancellationTokenSource CancellationTokenSource { get; }
protected CancellationTokenSource CancellationTokenSource { get; } = new CancellationTokenSource();

/// <inheritdoc/>
public virtual Task InitializeAsync() => Task.CompletedTask;
Expand All @@ -52,8 +45,8 @@ protected ComponentStore(TState state)
/// <param name="state">The updated state to set</param>
protected virtual void Set(TState state)
{
this._State = state;
this._Subject.OnNext(this._State);
this._state = state;
this._subject.OnNext(this._state);
}

/// <summary>
Expand All @@ -62,7 +55,7 @@ protected virtual void Set(TState state)
/// <param name="reducer">A <see cref="Func{T, TResult}"/> used to reduce the <see cref="ComponentStore{TState}"/>'s state</param>
protected virtual void Reduce(Func<TState, TState> reducer)
{
this.Set(reducer(this._State));
this.Set(reducer(this._state));
}

/// <summary>
Expand All @@ -71,7 +64,7 @@ protected virtual void Reduce(Func<TState, TState> reducer)
/// <returns></returns>
protected virtual TState Get()
{
return this._State;
return this._state;
}

/// <summary>
Expand All @@ -80,26 +73,26 @@ protected virtual TState Get()
/// <returns></returns>
protected virtual T Get<T>(Func<TState, T> project)
{
return project(this._State);
return project(this._state);
}

/// <inheritdoc/>
public virtual IDisposable Subscribe(IObserver<TState> observer) => this._Subject.Throttle(TimeSpan.FromMicroseconds(1)).Subscribe(observer);
public virtual IDisposable Subscribe(IObserver<TState> observer) => this._subject.Throttle(TimeSpan.FromMicroseconds(1)).Subscribe(observer);

/// <summary>
/// Disposes of the <see cref="ComponentStore{TState}"/>
/// </summary>
/// <param name="disposing">A boolean indicating whether or not the <see cref="ComponentStore{TState}"/> is being disposed of</param>
protected virtual void Dispose(bool disposing)
{
if (!this._Disposed)
if (!this._disposed)
{
if (disposing)
{
this.CancellationTokenSource.Dispose();
this._Subject.Dispose();
this._subject.Dispose();
}
this._Disposed = true;
this._disposed = true;
}
}

Expand All @@ -117,14 +110,14 @@ public void Dispose()
/// <returns>A new awaitable <see cref="ValueTask"/></returns>
protected virtual ValueTask DisposeAsync(bool disposing)
{
if (!this._Disposed)
if (!this._disposed)
{
if (disposing)
{
this.CancellationTokenSource.Dispose();
this._Subject.Dispose();
this._subject.Dispose();
}
this._Disposed = true;
this._disposed = true;
}
return ValueTask.CompletedTask;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class FluxOptions
/// <summary>
/// Gets/sets a <see cref="List{T}"/> containing the assemblies to scan for Flux components
/// </summary>
public virtual List<Assembly> AssembliesToScan { get; set; } = new();
public virtual List<Assembly> AssembliesToScan { get; set; } = [];

/// <summary>
/// Gets/sets a boolean indicating whether or not to automatically register scanned <see cref="IFeature"/>s and <see cref="IReducer"/>s
Expand Down Expand Up @@ -60,17 +60,17 @@ public class FluxOptions
/// <summary>
/// Gets/sets a <see cref="List{T}"/> containing the types of the <see cref="IFeature"/>s to use
/// </summary>
public virtual List<IFeature> Features { get; set; } = new();
public virtual List<IFeature> Features { get; set; } = [];

/// <summary>
/// Gets/sets a <see cref="List{T}"/> containing the types of the <see cref="IMiddleware"/>s to use
/// </summary>
public virtual List<Type> Middlewares { get; set; } = new();
public virtual List<Type> Middlewares { get; set; } = [];

/// <summary>
/// Gets/sets a <see cref="List{T}"/> containing the types of the <see cref="IEffect"/>s to use
/// </summary>
public virtual List<IEffect> Effects { get; set; } = new();
public virtual List<IEffect> Effects { get; set; } = [];

/// <summary>
/// Gets/sets the lifetime of all Flux services
Expand Down
17 changes: 6 additions & 11 deletions src/dashboard/Synapse.Dashboard.StateManagement/Reducer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,18 @@ namespace Synapse.Dashboard.StateManagement;
/// </summary>
/// <typeparam name="TState">The type of state to reduce</typeparam>
/// <typeparam name="TAction">The type of flux action the reducer applies to</typeparam>
public class Reducer<TState, TAction>
/// <remarks>
/// Initializes a new <see cref="Reducer{TState, TAction}"/>
/// </remarks>
/// <param name="reduceFunction">The function used to reduce the state</param>
public class Reducer<TState, TAction>(Func<TState, TAction, TState> reduceFunction)
: IReducer<TState, TAction>
{

/// <summary>
/// Initializes a new <see cref="Reducer{TState, TAction}"/>
/// </summary>
/// <param name="reduceFunction">The function used to reduce the state</param>
public Reducer(Func<TState, TAction, TState> reduceFunction)
{
this.ReduceFunction = reduceFunction;
}

/// <summary>
/// Gets the function used to reduce the state
/// </summary>
protected Func<TState, TAction, TState> ReduceFunction { get; }
protected Func<TState, TAction, TState> ReduceFunction { get; } = reduceFunction;

/// <inheritdoc/>
public TState Reduce(TState state, TAction action)
Expand Down
2 changes: 1 addition & 1 deletion src/dashboard/Synapse.Dashboard.StateManagement/Store.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ protected virtual async Task DispatchAsync(object action)
{
try
{
var pipelineBuilder = (DispatchDelegate reducer) => this.Middlewares
DispatchDelegate pipelineBuilder(DispatchDelegate reducer) => this.Middlewares
.AsEnumerable()
.Reverse()
.Aggregate(reducer, (next, type) => this.InstantiateMiddleware(type, next).InvokeAsync);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
@namespace Synapse.Dashboard.Components
@*
Copyright © 2024-Present The Synapse Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*@

@namespace Synapse.Dashboard.Components
@implements IDisposable
@inject IApplicationLayout Layout
@code
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
@namespace Synapse.Dashboard
@*
Copyright © 2024-Present The Synapse Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*@

@namespace Synapse.Dashboard
@inherits LayoutComponentBase
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject IOptions<ApplicationOptions> Options
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
@namespace Synapse.Dashboard.Components
@*
Copyright © 2024-Present The Synapse Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*@

@namespace Synapse.Dashboard.Components
@inject IMonacoEditorHelper MonacoEditorHelper
@implements IDisposable

<div class="width d-flex justify-content-end mb-2">
<div class="btn-group btn-group-xsm" role="group" aria-label="Toggle editor language">
<Button Color="!isJsonSelected ? ButtonColor.Primary : ButtonColor.Secondary" Outline="true" Active="!isJsonSelected" @onclick="_ => ToggleLanguage()">YAML</Button>
<Button Color="isJsonSelected ? ButtonColor.Primary : ButtonColor.Secondary" Outline="true" Active="isJsonSelected" @onclick="_ => ToggleLanguage()">JSON</Button>
<Button class="@(!isJsonSelected ? "btn-outline-primary" : "btn-outline-mute")" Outline="true" Active="!isJsonSelected" @onclick="_ => ToggleLanguage()">YAML</Button>
<Button class="@(isJsonSelected ? "btn-outline-primary" : "btn-outline-mute")" Outline="true" Active="isJsonSelected" @onclick="_ => ToggleLanguage()">JSON</Button>
</div>
</div>

Expand Down
Loading

0 comments on commit 9475cb0

Please sign in to comment.