Skip to content

Commit

Permalink
New UI for the InputEditor and add MultiCombobox
Browse files Browse the repository at this point in the history
  • Loading branch information
jaimeatstariongroup committed Sep 22, 2023
1 parent 71a4c6d commit 29e3eed
Show file tree
Hide file tree
Showing 8 changed files with 359 additions and 65 deletions.
3 changes: 3 additions & 0 deletions COMET.Web.Common/COMET.Web.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
<Content Update="wwwroot\DefaultTextConfiguration.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\BookInputConfiguration.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\server_configuration.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
Expand Down
112 changes: 52 additions & 60 deletions COMET.Web.Common/Components/BookEditor/InputEditor.razor
Original file line number Diff line number Diff line change
Expand Up @@ -27,67 +27,59 @@
@using CDP4Common.ReportingData
@typeparam TItem

<div>
<DxTabs>
<DxTabPage Text="Basic" CssClass="basic-tab">
<div class="tab-content">
@if (this.Item is INamedThing namedThing)
{
<div class="w-100 editor-row">
<p>Name:</p>
<DxTextBox CssClass="w-100" @bind-Text="@namedThing.Name" />
</div>
}
<div class="input-content">
@if (this.Item is INamedThing namedThing && this.showName)
{
<div class="w-100 editor-row">
<p>Name:</p>
<DxTextBox CssClass="w-100" @bind-Text="@namedThing.Name" />
</div>
}

@if (this.Item is IShortNamedThing shortNamedThing)
{
<div class="w-100 editor-row">
<p>ShortName:</p>
<DxTextBox CssClass="w-100" @bind-Text="@shortNamedThing.ShortName" />
</div>
}
@if (this.Item is IShortNamedThing shortNamedThing && this.showShortName)
{
<div class="w-100 editor-row">
<p>ShortName:</p>
<DxTextBox CssClass="w-100" @bind-Text="@shortNamedThing.ShortName" />
</div>
}

@if (this.Item is IOwnedThing ownedThing)
{
<div class="w-100 editor-row">
<p>Owner:</p>
<DxComboBox @bind-Value="@ownedThing.Owner"
Data="@this.ActiveDomains"
TData="DomainOfExpertise"
TValue="DomainOfExpertise"
TextFieldName="@nameof(DomainOfExpertise.Name)"
CssClass="w-100" />
</div>
}
@if (this.Item is IOwnedThing ownedThing)
{
<div class="w-100 editor-row">
<p>Owner:</p>
<DxComboBox @bind-Value="@ownedThing.Owner"
Data="@this.ActiveDomains"
TData="DomainOfExpertise"
TValue="DomainOfExpertise"
TextFieldName="@nameof(DomainOfExpertise.Name)"
CssClass="w-100" />
</div>
}

@if (this.Item is TextualNote textualNote)
{
<div class="w-100 editor-row">
<p>Content:</p>
<DxMemo @bind-Text="textualNote.Content"
CssClass="w-100"
Rows="4" />
</div>
}
</div>
</DxTabPage>
<DxTabPage Text="Category" CssClass="category-tab">
<div class="tab-content">
@if (this.Item is ICategorizableThing categorizableThing)
{
<DxListBox Values="@categorizableThing.Category"
Data="@this.AvailableCategories"
TData="Category"
TValue="Category"
ValuesChanged="@this.OnCategoryChange"
TextFieldName="@nameof(Category.Name)"
SelectionMode="ListBoxSelectionMode.Multiple"
ShowCheckboxes="true"
CssClass="w-auto mt-1 me-1 flex-grow-1 chi-220"
style="flex-basis: 240px">
</DxListBox>
}
</div>
</DxTabPage>
</DxTabs>
@if (this.Item is TextualNote textualNote)
{
<div class="w-100 editor-row">
<p>Content:</p>
<DxMemo @bind-Text="textualNote.Content"
CssClass="w-100"
Rows="4" />
</div>
}

@if (this.Item is ICategorizableThing categorizableThing)
{
<div class="w-100 editor-row category-row">
<p>Category:</p>
<MultiComboBox TItem="Category"
Values="@categorizableThing.Category"
Data="@this.AvailableCategories"
ShowCheckBoxes="true"
ValuesChanged="@this.OnCategoryChange">
<RowTemplate>
<span>@context.Name</span>
</RowTemplate>
</MultiComboBox>
</div>
}
</div>
78 changes: 75 additions & 3 deletions COMET.Web.Common/Components/BookEditor/InputEditor.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,42 @@
// --------------------------------------------------------------------------------------------------------------------

namespace COMET.Web.Common.Components.BookEditor
{
using CDP4Common.EngineeringModelData;
{
using System.Text.Json;

using CDP4Common.EngineeringModelData;
using CDP4Common.SiteDirectoryData;

using COMET.Web.Common.Model;
using COMET.Web.Common.Utilities;

using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

/// <summary>
/// Support class for the InputEditor component
/// </summary>
public partial class InputEditor<TItem>
{
/// <summary>
/// Gets or sets the <see cref="ILogger"/>
/// </summary>
[Inject]
ILogger<InputEditor<TItem>> Logger { get; set; }

/// <summary>
/// Gets or sets the <see cref="HttpClient"/>
/// </summary>
[Inject]
HttpClient HttpClient { get; set; }

/// <summary>
/// Gets or sets the <see cref="IOptions{GlobalOptions}"/>
/// </summary>
[Inject]
public IOptions<GlobalOptions> Options { get; set; }

/// <summary>
/// Gets or sets the item for which the input is being provided
/// </summary>
Expand All @@ -52,7 +77,54 @@ public partial class InputEditor<TItem>
/// </summary>
[Parameter]
public IEnumerable<Category> AvailableCategories { get; set; }


/// <summary>
/// Sets if the component should show the name field
/// </summary>
private bool showName;

/// <summary>
/// Sets if the component should show the shorname field
/// </summary>
private bool showShortName;

/// <summary>
/// Method invoked when the component is ready to start, having received its
/// initial parameters from its parent in the render tree.
///
/// Override this method if you will perform an asynchronous operation and
/// want the component to refresh when that operation is completed.
/// </summary>
/// <returns>A <see cref="Task"/> representing any asynchronous operation.</returns>
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();

var jsonFile = this.Options.Value.JsonConfigurationFile ?? "BookInputConfiguration.json";

try
{
var path = ContentPathBuilder.BuildPath(jsonFile);
var jsonContent = await this.HttpClient.GetStreamAsync(path);
var configurations = JsonSerializer.Deserialize<Dictionary<string, bool>>(jsonContent);

if (configurations.TryGetValue("ShowName", out var showNameValue))
{
this.showName = showNameValue;
}

if (configurations.TryGetValue("ShowShortName", out var showShortNameValue))
{
this.showShortName = showShortNameValue;
}
}
catch (Exception e)
{
this.Logger.LogError(e, "Error while getting the configuration file.");
return;
}
}

/// <summary>
/// Handler for when the selected categories changed
/// </summary>
Expand Down
73 changes: 73 additions & 0 deletions COMET.Web.Common/Components/MultiComboBox.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!------------------------------------------------------------------------------
// Copyright (c) 2023 RHEA System S.A.
//
// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar
//
// This file is part of COMET WEB Community Edition
// The COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25
// Annex A and Annex C.
//
// 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.
------------------------------------------------------------------------------->
@typeparam TItem

<DxComboBox TValue="TItem"
TData="TItem"
Data="@this.Data"
ValueChanged="@this.ItemSelected"
Enabled="@this.Enabled"
CssClass="w-100">
<ItemTemplate>
<div class="multi-combo-item-template">
@if (this.ShowCheckBoxes)
{
var isSelected = this.Values.Contains(context);
<DxCheckBox Checked="@isSelected"></DxCheckBox>
}

@if (this.RowTemplate != null)
{
@this.RowTemplate(context)
}
else
{
<span>@context.ToString()</span>
}
</div>
</ItemTemplate>

<EditBoxTemplate>
@if(this.Values.Count <= 2)
{
<div class="chips-container">
@foreach(var value in this.Values)
{
<button class="chip" @onclick="@(() => this.ItemSelected(value))">
@if (this.RowTemplate != null)
{
@this.RowTemplate(value)
}
else
{
@value
}
</button>
}
</div>
}
else
{
<div>@(this.Values.Count) items are selected</div>
}
</EditBoxTemplate>
</DxComboBox>
78 changes: 78 additions & 0 deletions COMET.Web.Common/Components/MultiComboBox.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// -----------------------------------------------------------------------------------
// <copyright file="MultiComboBox.razor.cs" company="RHEA System S.A.">
// Copyright (c) 2023 RHEA System S.A.
//
// Authors: Sam Gerené, Jaime Bernar
//
// This file is part of AIDA
// European Space Agency Community License – v2.4 Permissive (Type 3)
// See LICENSE file for details
//
// </copyright>
// -----------------------------------------------------------------------------------

namespace COMET.Web.Common.Components
{
using Microsoft.AspNetCore.Components;

/// <summary>
/// Support class for the multicombobox component
/// </summary>
public partial class MultiComboBox<TItem>
{
/// <summary>
/// Gets or sets if the checkboxes for the selected items should be drawn
/// </summary>
[Parameter]
public bool ShowCheckBoxes { get; set; }

/// <summary>
/// Gets or sets the item template for the selected items
/// </summary>
[Parameter]
public RenderFragment<TItem> RowTemplate { get; set; }

/// <summary>
/// Gets or sets the data of the combobox
/// </summary>
[Parameter]
public IEnumerable<TItem> Data { get; set; } = Enumerable.Empty<TItem>();

/// <summary>
/// Gets or sets if the component should show all the fields as readonly
/// </summary>
[Parameter]
public bool Enabled { get; set; } = true;

/// <summary>
/// Gets or sets the value of the selected items
/// </summary>
[Parameter]
public List<TItem> Values { get; set; } = new();

/// <summary>
/// Gets or sets the callback used to update the component value
/// </summary>
[Parameter]
public EventCallback<List<TItem>> ValuesChanged { get; set; }

/// <summary>
/// Handler for when the value of the component has changed
/// </summary>
/// <param name="newValue">the new value</param>
/// <returns>an asynchronous operation</returns>
private async Task ItemSelected(TItem newValue)
{
if(this.Values.Contains(newValue))
{
this.Values.Remove(newValue);
}
else
{
this.Values.Add(newValue);
}

await this.ValuesChanged.InvokeAsync(this.Values);
}
}
}
Loading

0 comments on commit 29e3eed

Please sign in to comment.