-
Notifications
You must be signed in to change notification settings - Fork 480
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
279 additions
and
344 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
@inject IJSRuntime JS | ||
|
||
<div class="@GetContainerClass()"> | ||
@if (EnableMasking && IsMasked) | ||
{ | ||
<span class="cellText"> | ||
●●●●●●●● | ||
</span> | ||
} | ||
else | ||
{ | ||
<span class="cellText" title="@Value"> | ||
<FluentHighlighter HighlightedText="@HighlightText" | ||
Text="@Value" /> | ||
</span> | ||
} | ||
@if (EnableMasking) | ||
{ | ||
<FluentButton Appearance="Appearance.Lightweight" | ||
IconEnd="@(IsMasked ? _unmaskIcon : _maskIcon)" | ||
Title="@(IsMasked ? "Show Value" : "Hide Value")" | ||
OnClick="ToggleMaskStateAsync" | ||
aria-label="@(IsMasked ? "Show Value" : "Hide Value")" /> | ||
} | ||
<FluentButton Appearance="Appearance.Lightweight" | ||
Id="@_anchorId" | ||
IconEnd="@(new Icons.Regular.Size16.Copy())" | ||
Class="defaultHidden" | ||
@onclick="@(() => CopyTextToClipboardAsync(Value, @_anchorId))" | ||
aria-label="Copy to Clipboard" /> | ||
<FluentTooltip Anchor="@_anchorId" Position="TooltipPosition.Top">@PreCopyText</FluentTooltip> | ||
</div> |
51 changes: 51 additions & 0 deletions
51
src/Aspire.Dashboard/Components/Controls/GridValue.razor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using Microsoft.AspNetCore.Components; | ||
using Microsoft.Fast.Components.FluentUI; | ||
using Microsoft.JSInterop; | ||
|
||
namespace Aspire.Dashboard.Components.Controls; | ||
|
||
public partial class GridValue | ||
{ | ||
[Parameter, EditorRequired] | ||
public string? Value { get; set; } | ||
|
||
/// <summary> | ||
/// Determines whether or not masking support is enabled for this value | ||
/// </summary> | ||
[Parameter] | ||
public bool EnableMasking { get; set; } | ||
|
||
/// <summary> | ||
/// Determines whether or not the value should currently be masked | ||
/// </summary> | ||
[Parameter] | ||
public bool IsMasked { get; set; } | ||
|
||
/// <summary> | ||
/// The text to highlight within the value when the value is displayed unmasked | ||
/// </summary> | ||
[Parameter] | ||
public string? HighlightText { get; set; } | ||
|
||
[Parameter] | ||
public EventCallback<bool> IsMaskedChanged { get; set; } | ||
|
||
private const string PreCopyText = "Copy to clipboard"; | ||
private const string PostCopyText = "Copied!"; | ||
|
||
private readonly Icon _maskIcon = new Icons.Regular.Size16.EyeOff(); | ||
private readonly Icon _unmaskIcon = new Icons.Regular.Size16.Eye(); | ||
private readonly string _anchorId = $"copy-{Guid.NewGuid():N}"; | ||
|
||
private string GetContainerClass() | ||
=> EnableMasking ? "container masking-enabled" : "container"; | ||
|
||
private async Task ToggleMaskStateAsync() | ||
=> await IsMaskedChanged.InvokeAsync(!IsMasked); | ||
|
||
private async Task CopyTextToClipboardAsync(string? text, string id) | ||
=> await JS.InvokeVoidAsync("copyTextToClipboard", id, text, PreCopyText, PostCopyText); | ||
} |
22 changes: 22 additions & 0 deletions
22
src/Aspire.Dashboard/Components/Controls/GridValue.razor.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
.container { | ||
display: grid; | ||
grid-template-columns: 1fr auto; | ||
gap: calc((6 + (var(--design-unit) * var(--density))) * 1px); | ||
} | ||
|
||
.masking-enabled { | ||
grid-template-columns: 1fr auto auto; | ||
} | ||
|
||
::deep .cellText { | ||
text-overflow: ellipsis; | ||
overflow: hidden; | ||
} | ||
|
||
::deep .defaultHidden { | ||
visibility: hidden; | ||
} | ||
|
||
::deep:hover .defaultHidden { | ||
visibility: visible; | ||
} |
17 changes: 17 additions & 0 deletions
17
src/Aspire.Dashboard/Components/Controls/PropertyGrid.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
@typeparam TItem | ||
|
||
<FluentDataGrid Items="@Items" | ||
ResizableColumns="true" | ||
Style="width:100%" | ||
GenerateHeader="GenerateHeaderOption.Sticky" | ||
GridTemplateColumns="@GridTemplateColumns"> | ||
<TemplateColumn Title="@NameColumnTitle" Class="nameColumn" SortBy="@NameSort" Sortable="@IsNameSortable"> | ||
<GridValue Value="@NameColumnValue(context)" HighlightText="@HighlightText" /> | ||
</TemplateColumn> | ||
<TemplateColumn Title="@ValueColumnTitle" Class="valueColumn" SortBy="@ValueSort" Sortable="@IsValueSortable"> | ||
<GridValue Value="@ValueColumnValue(context)" HighlightText="@HighlightText" | ||
EnableMasking="@EnableValueMasking" IsMasked="@GetIsItemMasked(context)" | ||
IsMaskedChanged="(newValue) => OnIsMaskedChanged(context, newValue)" /> | ||
</TemplateColumn> | ||
</FluentDataGrid> | ||
|
63 changes: 63 additions & 0 deletions
63
src/Aspire.Dashboard/Components/Controls/PropertyGrid.razor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using Microsoft.AspNetCore.Components; | ||
using Microsoft.Fast.Components.FluentUI; | ||
|
||
namespace Aspire.Dashboard.Components.Controls; | ||
|
||
public partial class PropertyGrid<TItem> | ||
{ | ||
[Parameter, EditorRequired] | ||
public IQueryable<TItem>? Items { get; set; } | ||
|
||
[Parameter] | ||
public string GridTemplateColumns { get; set; } = "1fr 1fr"; | ||
|
||
[Parameter] | ||
public string NameColumnTitle { get; set; } = "Name"; | ||
|
||
[Parameter] | ||
public string ValueColumnTitle { get; set; } = "Value"; | ||
|
||
[Parameter] | ||
public GridSort<TItem>? NameSort { get; set; } | ||
|
||
[Parameter] | ||
public GridSort<TItem>? ValueSort { get; set; } | ||
|
||
[Parameter] | ||
public bool IsNameSortable { get; set; } = true; | ||
|
||
[Parameter] | ||
public bool IsValueSortable { get; set; } = true; | ||
|
||
[Parameter] | ||
public bool EnableValueMasking { get; set; } | ||
|
||
[Parameter] | ||
public Func<TItem, string?> NameColumnValue { get; set; } = item => item?.ToString(); | ||
|
||
[Parameter] | ||
public Func<TItem, string?> ValueColumnValue { get; set; } = item => item?.ToString(); | ||
|
||
[Parameter] | ||
public Func<TItem, bool> GetIsItemMasked { get; set; } = item => false; | ||
|
||
[Parameter] | ||
public Action<TItem, bool> SetIsItemMasked { get; set; } = (item, newValue) => { }; | ||
|
||
[Parameter] | ||
public string? HighlightText { get; set; } | ||
|
||
[Parameter] | ||
public EventCallback<TItem> IsMaskedChanged { get; set; } | ||
|
||
public readonly record struct PropertyGridIsMaskedChangedArgs(TItem Item, bool NewValue); | ||
|
||
private async Task OnIsMaskedChanged(TItem item, bool newValue) | ||
{ | ||
SetIsItemMasked(item, newValue); | ||
await IsMaskedChanged.InvokeAsync(item); | ||
} | ||
} |
Empty file.
110 changes: 33 additions & 77 deletions
110
src/Aspire.Dashboard/Components/Dialogs/EnvironmentVariables.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,90 +1,46 @@ | ||
@using Aspire.Dashboard.Model | ||
@implements IDialogContentComponent<EnvironmentVariablesDialogViewModel> | ||
@inject IJSRuntime JS | ||
|
||
<FluentDialogBody> | ||
<div class="GridContainer"> | ||
<div> | ||
<FluentDialogBody> | ||
<FluentStack Orientation="Orientation.Vertical"> | ||
<FluentToolbar Orientation="Orientation.Horizontal"> | ||
@if (Content?.ShowSpecOnlyToggle == true) | ||
{ | ||
<FluentButton Appearance="Appearance.Lightweight" | ||
IconEnd="@(_showAll ? _showSpecOnlyIcon : _showAllIcon)" | ||
Title="@(_showAll ? "Show Spec Only" : "Show All")" | ||
aria-label="@(_showAll ? "Show Spec Only" : "Show All")" | ||
OnClick="() => _showAll = !_showAll" | ||
slot="end" /> | ||
IconEnd="@(_showAll ? _showSpecOnlyIcon : _showAllIcon)" | ||
Title="@(_showAll ? "Show Spec Only" : "Show All")" | ||
aria-label="@(_showAll ? "Show Spec Only" : "Show All")" | ||
OnClick="() => _showAll = !_showAll" | ||
slot="end" /> | ||
} | ||
<FluentButton Appearance="Appearance.Lightweight" | ||
IconEnd="@(_defaultMasked ? _unmaskIcon : _maskIcon)" | ||
Title="@(_defaultMasked ? "Show Values" : "Hide Values")" | ||
aria-label="@(_defaultMasked ? "Show Values" : "Hide Values")" | ||
OnClick="ToggleMaskState" | ||
slot="end" /> | ||
IconEnd="@(_defaultMasked ? _unmaskIcon : _maskIcon)" | ||
Title="@(_defaultMasked ? "Show Values" : "Hide Values")" | ||
aria-label="@(_defaultMasked ? "Show Values" : "Hide Values")" | ||
OnClick="ToggleMaskState" | ||
slot="end" /> | ||
<FluentSearch Placeholder="Filter..." | ||
Immediate="true" | ||
Autofocus="true" | ||
@bind-Value="_filter" | ||
@oninput="HandleFilter" | ||
AfterBindValue="HandleClear" | ||
slot="end" /> | ||
Immediate="true" | ||
Autofocus="true" | ||
@bind-Value="_filter" | ||
@oninput="HandleFilter" | ||
AfterBindValue="HandleClear" | ||
slot="end" /> | ||
</FluentToolbar> | ||
<FluentDataGrid Items="@FilteredItems" | ||
ResizableColumns="true" | ||
Style="width:100%" | ||
GenerateHeader="GenerateHeaderOption.Sticky" | ||
GridTemplateColumns="1fr 1fr"> | ||
<TemplateColumn Title="Name" Class="nameColumn" SortBy="@_nameSort" Sortable="true" Tooltip="true" > | ||
<FluentStack Orientation="Orientation.Horizontal"> | ||
<span class="cellText" title="@context.Name"> | ||
<FluentHighlighter HighlightedText="@_filter" | ||
Text="@context.Name" /> | ||
</span> | ||
@{ | ||
var anchor = "name-" + context.Name; | ||
} | ||
<FluentButton Appearance="Appearance.Lightweight" | ||
Id="@anchor" | ||
IconEnd="@(new Icons.Regular.Size16.Copy())" | ||
Class="defaultHidden" | ||
@onclick="@(() => CopyTextToClipboardAsync(context.Name, @anchor))" /> | ||
<FluentTooltip Anchor="@anchor" Position="TooltipPosition.Top">@PreCopyText</FluentTooltip> | ||
</FluentStack> | ||
</TemplateColumn> | ||
<TemplateColumn Title="Value" Class="valueColumn" SortBy="@_valueSort" Sortable="true"> | ||
<FluentStack Orientation="Orientation.Horizontal" Width="400px;"> | ||
@if (context.IsValueMasked) | ||
{ | ||
<span class="cellText"> | ||
●●●●●●●● | ||
</span> | ||
} | ||
else | ||
{ | ||
<span class="cellText" title="@context.Value"> | ||
<FluentHighlighter HighlightedText="@_filter" | ||
Text="@context.Value" /> | ||
</span> | ||
} | ||
<FluentButton Appearance="Appearance.Lightweight" | ||
IconEnd="@(context.IsValueMasked ? _unmaskIcon : _maskIcon)" | ||
Title="@(context.IsValueMasked ? "Show Value" : "Hide Value")" | ||
OnClick="() => ToggleMaskState(context)" | ||
aria-label="@(context.IsValueMasked ? "Show Value" : "Hide Value")" /> | ||
@{ | ||
var anchor = "copy-" + context.Name; | ||
} | ||
<FluentButton Appearance="Appearance.Lightweight" | ||
Id="@anchor" | ||
IconEnd="@(new Icons.Regular.Size16.Copy())" | ||
Class="defaultHidden" | ||
@onclick="@(() => CopyTextToClipboardAsync(context.Value, @anchor))" | ||
aria-label="Copy to Clipboard" /> | ||
<FluentTooltip Anchor="@anchor" Position="TooltipPosition.Top">@PreCopyText</FluentTooltip> | ||
</FluentStack> | ||
</TemplateColumn> | ||
</FluentDataGrid> | ||
<div class="dialog-grid-container"> | ||
<PropertyGrid TItem="EnvironmentVariableViewModel" | ||
Items="@FilteredItems" | ||
NameColumnValue="(vm) => vm.Name" | ||
ValueColumnValue="(vm) => vm.Value" | ||
NameSort="_nameSort" | ||
ValueSort="_valueSort" | ||
EnableValueMasking="true" | ||
GetIsItemMasked="(vm) => vm.IsValueMasked" | ||
SetIsItemMasked="(vm, newValue) => vm.IsValueMasked = newValue" | ||
IsMaskedChanged="@CheckAllMaskStates" | ||
HighlightText="@_filter" /> | ||
</div> | ||
</FluentStack> | ||
|
||
</div> | ||
</FluentDialogBody> | ||
</FluentDialogBody> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 0 additions & 35 deletions
35
src/Aspire.Dashboard/Components/Dialogs/EnvironmentVariables.razor.css
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.