Skip to content

Commit

Permalink
Roughing in some CdsHooks features
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeShook committed Oct 11, 2024
1 parent d23c070 commit 56cbec6
Show file tree
Hide file tree
Showing 20 changed files with 434 additions and 13 deletions.
2 changes: 2 additions & 0 deletions Client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using UdapEd.Shared;
using UdapEd.Shared.Services;
using UdapEd.Shared.Services.Search;
using CdsService = UdapEd.Client.Services.CdsService;


var builder = WebAssemblyHostBuilder.CreateDefault(args);
Expand All @@ -43,6 +44,7 @@
builder.Services.AddSingleton<ICapabilityLookup, CapabilityLookup>();
builder.Services.AddScoped<IClipboardService, ClipboardService>();
builder.Services.AddScoped<IMutualTlsService, MutualTlsService>();
builder.Services.AddScoped<ICdsService, CdsService>();

// Add this so that the resolve() extension will be available when including in FhirPath
Hl7.FhirPath.FhirPathCompiler.DefaultSymbolTable.AddFhirExtensions();
Expand Down
20 changes: 20 additions & 0 deletions Client/Services/CdsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Net.Http.Json;
using UdapEd.Shared.Model.CdsHooks;
using UdapEd.Shared.Services;

namespace UdapEd.Client.Services;

public class CdsService : ICdsService
{
private readonly HttpClient _httpClient;

public CdsService(HttpClient httpClient)
{
_httpClient = httpClient;
}

public Task<List<CdsServiceViewModel>?> FetchCdsServices()
{
return _httpClient.GetFromJsonAsync<List<CdsServiceViewModel>> ("CdsServices/FetchCdsServices");
}
}
8 changes: 0 additions & 8 deletions Client/UdapEd.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@
<PublishTrimmed>false</PublishTrimmed>
</PropertyGroup>


<ItemGroup>
<None Include="..\..\..\..\artwork\UDAP_Ecosystem_Gears 48X48.jpg" Link="UDAP_Ecosystem_Gears 48X48.jpg">
<PackagePath>\</PackagePath>
<Pack>true</Pack>
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
<PackageReference Include="BQuery" Version="3.1.0" />
Expand Down
34 changes: 34 additions & 0 deletions Server/Controllers/CdsServicesController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#region (c) 2024 Joseph Shook. All rights reserved.
// /*
// Authors:
// Joseph Shook [email protected]
//
// See LICENSE in the project root for license information.
// */
#endregion

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using UdapEd.Server.Extensions;
using UdapEd.Shared.Services;

namespace UdapEd.Server.Controllers;

[Route("[controller]")]
[EnableRateLimiting(RateLimitExtensions.Policy)]
public class CdsServicesController : Controller
{
private readonly ICdsService _cdsService;

public CdsServicesController(ICdsService cdsService)
{
_cdsService = cdsService;
}

[HttpGet("FetchCdsServices")]
public async Task<IActionResult> FetchCdsServices()
{
var services = await _cdsService.FetchCdsServices();
return Ok(services);
}
}
5 changes: 3 additions & 2 deletions Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#endregion

using System.Net;
using Hl7.Fhir.Model.CdsHooks;
using Hl7.Fhir.Rest;
using Microsoft.Extensions.Options;
using Serilog;
Expand Down Expand Up @@ -111,8 +112,8 @@
.AddHttpMessageHandler(sp => new HeaderAugmentationHandler(sp.GetRequiredService<IOptionsMonitor<UdapClientOptions>>()));

builder.Services.AddTransient<IClientCertificateProvider, ClientCertificateProvider>();
builder.Services.AddScoped<IInfrastructure, UdapEd.Shared.Services.Infrastructure>();

builder.Services.AddScoped<IInfrastructure, Infrastructure>();
builder.Services.AddHttpClient<ICdsService, CdsService>();
//
// This does not allow you to let the client dynamically load new mTLS certificates. The HttpHandler doesn't reenter.
//
Expand Down
9 changes: 9 additions & 0 deletions Shared/CdsComponents/CardList.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@code {
[Parameter]
public EventCallback TakeSuggestion { get; set; }
}

<div class="card-list">
<!-- Add your card items here -->
<button @onclick="TakeSuggestion">Take Suggestion</button>
</div>
34 changes: 34 additions & 0 deletions Shared/CdsComponents/ConfigureServicesDialog.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@using UdapEd.Shared.Model.CdsHooks

<MudDialog Style="margin: 20px">
<DialogContent>
<MudText Typo="Typo.h6" GutterBottom="true">Configure CDS Services</MudText>
@if (Services != null)
{
foreach (var service in Services)
{
<ServiceDisplay CdsServiceModel="service" />
}
}
</DialogContent>
<DialogActions>
<MudButton Color="Color.Primary" OnClick="Submit">Close</MudButton>
</DialogActions>
</MudDialog>

@code {
[CascadingParameter]
MudDialogInstance MudDialog { get; set; } = null!;

[Inject] ICdsService CdaService { get; set; } = null!;

[Parameter]
public List<CdsServiceViewModel>? Services { get; set; }

void Submit() => MudDialog.Close();

protected override async Task OnInitializedAsync()
{
Services = await CdaService.FetchCdsServices();
}
}
13 changes: 13 additions & 0 deletions Shared/CdsComponents/ContextView.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@using Microsoft.Fast.Components.FluentUI
@code {
[Parameter]
public string Class { get; set; } = string.Empty;
}

<FluentCard class="@Class">
<div>
<!-- Your ContextView content goes here -->
<h1>CDS Developer Panel</h1>
<!-- Add more content as needed -->
</div>
</FluentCard>
49 changes: 49 additions & 0 deletions Shared/CdsComponents/HookView.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@using Microsoft.Fast.Components.FluentUI

@inject NavigationManager Navigation


@code {

[Parameter]
public string Class { get; set; } = string.Empty;

private string? _firstQueryParam;

protected override void OnInitialized()
{
var uri = Navigation.ToAbsoluteUri(Navigation.Uri);
var query = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query);
_firstQueryParam = query.Keys.FirstOrDefault();
}
}




@code {

}

<FluentCard class="@Class">
@if (_firstQueryParam == "PatientView")
{
<PatientView />
}
else if (_firstQueryParam == "RxView")
{
<PatientView />
}
else if (_firstQueryParam == "RxSign")
{
<PatientView />
}
else if (_firstQueryParam == "PamaImaging")
{
<PatientView />
}
else
{
<p>Component not found</p>
}
</FluentCard>
27 changes: 27 additions & 0 deletions Shared/CdsComponents/PatientView.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@using Hl7.Fhir.Model
@inject IJSRuntime JSRuntime

@code {
[Parameter]
public Patient Patient { get; set; }

[Parameter]
public bool IsContextVisible { get; set; }

private string Name => Patient?.Name?.FirstOrDefault()?.Given.FirstOrDefault() ?? "Missing Name";
private string Dob => Patient?.BirthDate ?? "Missing DOB";
private string Pid => Patient?.Id ?? "Missing Patient ID";

private string IsHalfView => IsContextVisible ? "half-view" : string.Empty;
}

<div class="@(IsHalfView)">
<h1 class="view-title">Patient View</h1>
<h2>@Name</h2>
<div class="patient-data-text">
<p>
<strong>ID: </strong> @Pid <strong>Birthdate: </strong> @Dob
</p>
</div>
<CardList TakeSuggestion="() => {}" />
</div>
55 changes: 55 additions & 0 deletions Shared/CdsComponents/ServiceDisplay.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
@using UdapEd.Shared.Model.CdsHooks
@inject IJSRuntime Js

<MudGrid>
<MudItem xs="6" Style="margin-top: auto;">
<MudText Typo="Typo.h6">@CdsServiceModel.Url</MudText>
</MudItem>
<MudItem xs="6" Class="d-flex flex-column align-items-end">
<MudCheckBox LabelPosition="LabelPosition.Start" @bind-Value="CdsServiceModel.CdsService.Enabled" Color="Color.Primary" Label="Enabled?" Class="ml-auto" />
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="RemoveService" Class="ml-auto mt-2">
Delete
</MudButton>
</MudItem>
</MudGrid>
<MudPaper Outlined="true" Square="true"><pre>@_serviceMetadata</pre></MudPaper>



@code {
string? _serviceMetadata;

[Parameter]
public CdsServiceViewModel CdsServiceModel { get; set; }

[Parameter]
public EventCallback<string> Toggle { get; set; }

[Parameter]
public EventCallback<string> Remove { get; set; }

private ElementReference _definitionBody;

protected override void OnInitialized()
{
var definitionCopy = JsonSerializer.Serialize(CdsServiceModel, new JsonSerializerOptions { WriteIndented = true });
_serviceMetadata = definitionCopy;
base.OnInitialized();
}

private async Task ToggleService()
{
if (Toggle.HasDelegate)
{
await Toggle.InvokeAsync(CdsServiceModel.Url);
}
}

private async Task RemoveService()
{
if (Remove.HasDelegate)
{
await Remove.InvokeAsync(CdsServiceModel.Url);
}
}
}
18 changes: 16 additions & 2 deletions Shared/Components/MainLayout.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@inherits LayoutComponentBase
@inject NavigationManager Navigation

<MudThemeProvider />
<MudDialogProvider />
<MudSnackbarProvider />
Expand All @@ -14,8 +16,20 @@
}
else
{
<MudMainContent Style="font-family: Candara" Class="px-8" MaxWidth="MaxWidth.False">
<MudMainContent Style="font-family: Candara" Class="@GetClass()" MaxWidth="MaxWidth.False">
@Body
</MudMainContent>
}
</MudLayout>
</MudLayout>

@code {
private string GetClass()
{
var uri = Navigation.Uri;
if (uri.Contains("cdshooks"))
{
return "px-0"; // No padding for specific page
}
return "px-8"; // Default padding
}
}
7 changes: 7 additions & 0 deletions Shared/Components/NavMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
<MudNavLink Href="/smart/launch?iss=https://launch.smarthealthit.org/v/r4/fhir&launch=WzAsIiIsIiIsIkFVVE8iLDAsMCwwLCIiLCIiLCIiLCIiLCJhdXRoX2ludmFsaWRfY2xpZW50X2lkIiwiIiwiIiwyLDFd">launch</MudNavLink>
</MudNavGroup>

<MudNavGroup Title="CdsHooks" Expanded="true">
<MudNavLink Href="/cdshooks/main-view?PatientView">Patient View</MudNavLink>
<MudNavLink Href="/cdshooks/main-view?RxView">Rx View</MudNavLink>
<MudNavLink Href="/cdshooks/main-view?RxSign">Rx Sign</MudNavLink>
<MudNavLink Href="/cdshooks/main-view?PamaImaging">PAMA Imaging</MudNavLink>
</MudNavGroup>

<MudNavGroup Title="mTLS" Expanded="true">
<MudNavLink Href="/mTlsClient">x509 Client</MudNavLink>
</MudNavGroup>
Expand Down
33 changes: 33 additions & 0 deletions Shared/Model/CdsHooks/CdsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#region (c) 2024 Joseph Shook. All rights reserved.
// /*
// Authors:
// Joseph Shook [email protected]
//
// See LICENSE in the project root for license information.
// */
#endregion

namespace UdapEd.Shared.Model.CdsHooks;

public class CdsServiceViewModel
{
public string Url { get; set; }
public CdsService CdsService {get; set; }
}

[Serializable]
public class CdsService : Udap.CdsHooks.Model.CdsService
{
public CdsService(){}

public CdsService(Udap.CdsHooks.Model.CdsService baseService)
{
foreach (var property in baseService.GetType().GetProperties())
{
var value = property.GetValue(baseService);
this.GetType().GetProperty(property.Name)?.SetValue(this, value);
}
}

public bool Enabled { get; set; }
}
Loading

0 comments on commit 56cbec6

Please sign in to comment.