UI Work
Package Loading via directory support. Comparison includes extensions. Comparison includes source items that do not have a matching target.
This commit is contained in:
Родитель
516fb0fd84
Коммит
200e8cb10a
|
@ -190,4 +190,5 @@ public record class PackageComparison
|
|||
public required Dictionary<string, List<StructureComparison>> ComplexTypes { get; init; }
|
||||
public required Dictionary<string, List<StructureComparison>> Resources { get; init; }
|
||||
//public required Dictionary<string, ComparisonRecord<StructureInfoRec, ElementInfoRec, ElementTypeInfoRec>> LogicalModels { get; init; }
|
||||
public required Dictionary<string, List<StructureComparison>> Extensions { get; init; }
|
||||
}
|
||||
|
|
|
@ -111,6 +111,15 @@ public class PackageComparer
|
|||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares this optional bool object to another to determine their relative ordering.
|
||||
/// </summary>
|
||||
/// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
|
||||
/// <param name="compareExtensions">(Optional) The bool to compare to this object.</param>
|
||||
/// <returns>
|
||||
/// Negative if 'compareExtensions' is less than '', 0 if they are equal, or positive if it is
|
||||
/// greater.
|
||||
/// </returns>
|
||||
public PackageComparison Compare()
|
||||
{
|
||||
Console.WriteLine(
|
||||
|
@ -136,7 +145,7 @@ public class PackageComparer
|
|||
}
|
||||
|
||||
string outputDir = string.IsNullOrEmpty(_config.CrossVersionMapDestinationPath)
|
||||
? Path.Combine(_config.OutputDirectory, $"{_sourceRLiteral}_{_targetRLiteral}")
|
||||
? _config.OutputDirectory
|
||||
: Path.Combine(_config.CrossVersionMapDestinationPath, $"{_sourceRLiteral}_{_targetRLiteral}");
|
||||
|
||||
if (!Directory.Exists(outputDir))
|
||||
|
@ -314,6 +323,33 @@ public class PackageComparer
|
|||
}
|
||||
}
|
||||
|
||||
Dictionary<string, List<StructureComparison>> extensions = CompareStructures(_source.ExtensionsByUrl, _target.ExtensionsByUrl);
|
||||
if (mdWriter != null)
|
||||
{
|
||||
WriteComparisonOverview(mdWriter, "Extensions", extensions);
|
||||
|
||||
string mdSubDir = Path.Combine(pageDir, "Extensions");
|
||||
if (!Directory.Exists(mdSubDir))
|
||||
{
|
||||
Directory.CreateDirectory(mdSubDir);
|
||||
}
|
||||
|
||||
foreach (List<StructureComparison> vcs in extensions.Values)
|
||||
{
|
||||
foreach (StructureComparison c in vcs)
|
||||
{
|
||||
//string name = GetName(c.Left, c.Right);
|
||||
//string filename = Path.Combine(subDir, $"{name}.md");
|
||||
string filename = Path.Combine(mdSubDir, $"{c.CompositeName}.md");
|
||||
|
||||
using ExportStreamWriter writer = CreateMarkdownWriter(filename);
|
||||
{
|
||||
WriteComparisonFile(writer, string.Empty, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(ginoc): Logical models are tracked by URL in collections, but structure mapping is done by name.
|
||||
//Dictionary<string, ComparisonRecord<StructureInfoRec, ElementInfoRec, ElementTypeInfoRec>> logical = Compare(FhirArtifactClassEnum.LogicalModel, _left.LogicalModelsByUrl, _right.LogicalModelsByUrl);
|
||||
//if (mdWriter != null)
|
||||
|
@ -349,6 +385,7 @@ public class PackageComparer
|
|||
ComplexTypes = complexTypeComparisons,
|
||||
Resources = resources,
|
||||
//LogicalModels = logical,
|
||||
Extensions = extensions,
|
||||
};
|
||||
|
||||
if (mdWriter != null)
|
||||
|
@ -1163,6 +1200,27 @@ public class PackageComparer
|
|||
comparisons.Add(directComparison);
|
||||
}
|
||||
}
|
||||
|
||||
// check for something that has no counterpart
|
||||
if (comparisons.Count == 0)
|
||||
{
|
||||
comparisons.Add(new()
|
||||
{
|
||||
Relationship = null,
|
||||
Message = $"{sourceVs.Url} does not exist in target and has no mapping",
|
||||
Source = new()
|
||||
{
|
||||
Url = sourceVs.Url,
|
||||
Name = sourceVs.Name,
|
||||
NamePascal = sourceVs.Name.ToPascalCase(),
|
||||
Title = sourceVs.Title,
|
||||
Description = sourceVs.Description,
|
||||
},
|
||||
Target = null,
|
||||
CompositeName = $"{_sourceRLiteral}-{sourceVs.Name}",
|
||||
ConceptComparisons = [],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
|
@ -1628,6 +1686,29 @@ public class PackageComparer
|
|||
comparisons.Add(directComparison);
|
||||
}
|
||||
}
|
||||
|
||||
// check for something that has no counterpart
|
||||
if (comparisons.Count == 0)
|
||||
{
|
||||
comparisons.Add(new()
|
||||
{
|
||||
Relationship = null,
|
||||
Message = $"{sourceSdName} does not exist in target and has no mapping",
|
||||
Source = new()
|
||||
{
|
||||
Name = sourceSd.Name,
|
||||
Url = sourceSd.Url,
|
||||
Title = sourceSd.Title,
|
||||
Description = sourceSd.Description,
|
||||
Purpose = sourceSd.Purpose,
|
||||
SnapshotCount = sourceSd.Snapshot.Element.Count,
|
||||
DifferentialCount = sourceSd.Differential.Element.Count,
|
||||
},
|
||||
Target = null,
|
||||
CompositeName = $"{_sourceRLiteral}-{sourceSd.Name}",
|
||||
ElementComparisons = [],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
|
|
|
@ -222,6 +222,24 @@ public class ConfigRoot : ICodeGenConfig
|
|||
},
|
||||
};
|
||||
|
||||
[ConfigOption(
|
||||
ArgName = "--fhir-version",
|
||||
EnvName = "Fhir_Version",
|
||||
Description = "FHIR version to use.")]
|
||||
public string FhirVersion { get; set; } = string.Empty;
|
||||
|
||||
private static ConfigurationOption FhirVersionParameter { get; } = new()
|
||||
{
|
||||
Name = "FhirVersion",
|
||||
EnvVarName = "Fhir_Version",
|
||||
DefaultValue = string.Empty,
|
||||
CliOption = new System.CommandLine.Option<string>("--fhir-version", "FHIR version to use.")
|
||||
{
|
||||
Arity = System.CommandLine.ArgumentArity.ZeroOrOne,
|
||||
IsRequired = false,
|
||||
},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the configuration options.
|
||||
/// </summary>
|
||||
|
@ -237,6 +255,7 @@ public class ConfigRoot : ICodeGenConfig
|
|||
AutoLoadExpansionsParameter,
|
||||
ResolvePackageDependenciesParameter,
|
||||
OfflineModeParameter,
|
||||
FhirVersionParameter,
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
|
@ -498,6 +517,9 @@ public class ConfigRoot : ICodeGenConfig
|
|||
case "ResolvePackageDependencies":
|
||||
ResolvePackageDependencies = GetOpt(parseResult, opt.CliOption, ResolvePackageDependencies);
|
||||
break;
|
||||
case "FhirVersion":
|
||||
FhirVersion = GetOpt(parseResult, opt.CliOption, FhirVersion);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,9 @@ public record class LoaderOptions
|
|||
/// </summary>
|
||||
public bool OfflineMode { get; init; } = false;
|
||||
|
||||
/// <summary>Gets or initializes the FHIR version.</summary>
|
||||
public string FhirVersion { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the JSON model.
|
||||
/// </summary>
|
||||
|
|
|
@ -66,6 +66,8 @@ public class PackageLoader : IDisposable
|
|||
/// <summary>True to load dependencies when loading packages.</summary>
|
||||
private bool _loadDependencies;
|
||||
|
||||
private FhirReleases.FhirSequenceCodes _defaultFhirVersion;
|
||||
|
||||
/// <summary>The JSON model.</summary>
|
||||
private LoaderOptions.JsonDeserializationModel _jsonModel;
|
||||
|
||||
|
@ -118,6 +120,8 @@ public class PackageLoader : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
_defaultFhirVersion = FhirReleases.FhirVersionToSequence(opts.FhirVersion);
|
||||
|
||||
_jsonOptions = opts.FhirJsonOptions;
|
||||
_jsonParser = new(opts.FhirJsonSettings);
|
||||
|
||||
|
@ -420,14 +424,146 @@ public class PackageLoader : IDisposable
|
|||
return false;
|
||||
}
|
||||
|
||||
private void CreateConverterIfRequired(FhirReleases.FhirSequenceCodes fhirSequence)
|
||||
{
|
||||
// create the converter we need
|
||||
switch (fhirSequence)
|
||||
{
|
||||
case FhirReleases.FhirSequenceCodes.DSTU2:
|
||||
{
|
||||
if (_converter_20_50 == null)
|
||||
{
|
||||
lock (_convertLockObject)
|
||||
{
|
||||
_converter_20_50 ??= new();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FhirReleases.FhirSequenceCodes.STU3:
|
||||
{
|
||||
if (_converter_30_50 == null)
|
||||
{
|
||||
lock (_convertLockObject)
|
||||
{
|
||||
_converter_30_50 ??= new();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FhirReleases.FhirSequenceCodes.R4:
|
||||
case FhirReleases.FhirSequenceCodes.R4B:
|
||||
{
|
||||
if (_converter_43_50 == null)
|
||||
{
|
||||
lock (_convertLockObject)
|
||||
{
|
||||
_converter_43_50 ??= new();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case FhirReleases.FhirSequenceCodes.R5:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private bool LoadFromDirectory(ref DefinitionCollection? definitions, string sourcePath, string? fhirVersion)
|
||||
{
|
||||
FhirReleases.FhirSequenceCodes fhirSequence = string.IsNullOrEmpty(fhirVersion)
|
||||
? _defaultFhirVersion
|
||||
: FhirReleases.FhirVersionToSequence(fhirVersion!);
|
||||
|
||||
if (fhirSequence == FhirReleases.FhirSequenceCodes.Unknown)
|
||||
{
|
||||
throw new Exception("Cannot load from a directory with an unknown FHIR version");
|
||||
}
|
||||
|
||||
CreateConverterIfRequired(fhirSequence);
|
||||
|
||||
string? name = Path.GetFileName(sourcePath);
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
throw new Exception($"Failed to get directory name from '{sourcePath}'");
|
||||
}
|
||||
|
||||
string canonical = $"file://{sourcePath}";
|
||||
|
||||
definitions ??= new()
|
||||
{
|
||||
Name = name,
|
||||
FhirSequence = fhirSequence,
|
||||
FhirVersionLiteral = fhirSequence.ToLiteral(),
|
||||
MainPackageId = name,
|
||||
MainPackageVersion = "dev",
|
||||
MainPackageCanonical = canonical,
|
||||
};
|
||||
|
||||
// get files in the directory
|
||||
string[] files = Directory.GetFiles(sourcePath, "*.json", SearchOption.TopDirectoryOnly);
|
||||
foreach (string path in files)
|
||||
{
|
||||
string fileExtension = Path.GetExtension(path);
|
||||
|
||||
object? r;
|
||||
|
||||
switch (fhirSequence)
|
||||
{
|
||||
case FhirReleases.FhirSequenceCodes.DSTU2:
|
||||
{
|
||||
r = ParseContents20(fileExtension, path: path);
|
||||
}
|
||||
break;
|
||||
|
||||
case FhirReleases.FhirSequenceCodes.STU3:
|
||||
{
|
||||
r = ParseContents30(fileExtension, path: path);
|
||||
}
|
||||
break;
|
||||
|
||||
case FhirReleases.FhirSequenceCodes.R4:
|
||||
case FhirReleases.FhirSequenceCodes.R4B:
|
||||
{
|
||||
r = ParseContents43(fileExtension, path: path);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case FhirReleases.FhirSequenceCodes.R5:
|
||||
{
|
||||
r = ParseContentsPoco(fileExtension, path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (r == null)
|
||||
{
|
||||
throw new Exception($"Failed to parse '{path}'");
|
||||
}
|
||||
|
||||
definitions.AddResource(r, _defaultFhirVersion, name, "dev", canonical);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Loads a package.</summary>
|
||||
/// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
|
||||
/// <param name="name"> The name.</param>
|
||||
/// <param name="packages">The cached package.</param>
|
||||
/// <param name="packages"> The cached package.</param>
|
||||
/// <param name="definitions">(Optional) The definitions.</param>
|
||||
/// <param name="fhirVersion">(Optional) The FHIR version.</param>
|
||||
/// <returns>An asynchronous result that yields the package.</returns>
|
||||
public async Task<DefinitionCollection?> LoadPackages(
|
||||
IEnumerable<string> packages,
|
||||
DefinitionCollection? definitions = null)
|
||||
DefinitionCollection? definitions = null,
|
||||
string? fhirVersion = null)
|
||||
{
|
||||
if (!packages.Any())
|
||||
{
|
||||
|
@ -436,6 +572,26 @@ public class PackageLoader : IDisposable
|
|||
|
||||
foreach (string inputDirective in packages)
|
||||
{
|
||||
if (string.IsNullOrEmpty(inputDirective))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check to see if this is actually a directory
|
||||
if ((inputDirective.IndexOfAny(Path.GetInvalidPathChars()) == -1) &&
|
||||
Directory.Exists(inputDirective))
|
||||
{
|
||||
Console.WriteLine($"Processing directory {inputDirective}...");
|
||||
|
||||
if (!LoadFromDirectory(ref definitions, inputDirective, fhirVersion))
|
||||
{
|
||||
throw new Exception($"Failed to load package from directory: {inputDirective}");
|
||||
}
|
||||
|
||||
// if we loaded from the directory, just continue
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO(ginoc): PR in to Parse FHIR-style directives, remove when added.
|
||||
string directive = inputDirective.Contains('@')
|
||||
? inputDirective
|
||||
|
@ -546,52 +702,7 @@ public class PackageLoader : IDisposable
|
|||
? definitions.FhirSequence
|
||||
: FhirReleases.FhirVersionToSequence(packageFhirVersionLiteral ?? string.Empty);
|
||||
|
||||
// create the converter we need
|
||||
switch (definitions.FhirSequence)
|
||||
{
|
||||
case FhirReleases.FhirSequenceCodes.DSTU2:
|
||||
{
|
||||
if (_converter_20_50 == null)
|
||||
{
|
||||
lock (_convertLockObject)
|
||||
{
|
||||
_converter_20_50 ??= new();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FhirReleases.FhirSequenceCodes.STU3:
|
||||
{
|
||||
if (_converter_30_50 == null)
|
||||
{
|
||||
lock (_convertLockObject)
|
||||
{
|
||||
_converter_30_50 ??= new();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FhirReleases.FhirSequenceCodes.R4:
|
||||
case FhirReleases.FhirSequenceCodes.R4B:
|
||||
{
|
||||
if (_converter_43_50 == null)
|
||||
{
|
||||
lock (_convertLockObject)
|
||||
{
|
||||
_converter_43_50 ??= new();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case FhirReleases.FhirSequenceCodes.R5:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
CreateConverterIfRequired(definitions.FhirSequence);
|
||||
|
||||
// if we are resolving dependencies, check them now
|
||||
if (_loadDependencies && (manifest.Dependencies?.Any() ?? false))
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
// <copyright file="FileSystemUtils.cs" company="Microsoft Corporation">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Microsoft.Health.Fhir.CodeGen.Utils;
|
||||
|
||||
public abstract class FileSystemUtils
|
||||
{
|
||||
/// <summary>Searches for the FHIR specification directory.</summary>
|
||||
/// <exception cref="DirectoryNotFoundException">Thrown when the requested directory is not
|
||||
/// present.</exception>
|
||||
/// <param name="startDir"> The start directory.</param>
|
||||
/// <param name="dirName"> The name of the directory we are searching for.</param>
|
||||
/// <param name="throwIfNotFound">(Optional) True to throw if not found.</param>
|
||||
/// <returns>The found FHIR directory.</returns>
|
||||
public static string FindRelativeDir(
|
||||
string startDir,
|
||||
string dirName,
|
||||
bool throwIfNotFound = true)
|
||||
{
|
||||
string currentDir = startDir switch
|
||||
{
|
||||
null => Path.GetDirectoryName(AppContext.BaseDirectory) ?? string.Empty,
|
||||
"" => Path.GetDirectoryName(AppContext.BaseDirectory) ?? string.Empty,
|
||||
"." => Path.GetDirectoryName(AppContext.BaseDirectory) ?? string.Empty,
|
||||
"./" => Path.GetDirectoryName(AppContext.BaseDirectory) ?? string.Empty,
|
||||
"~" => Path.GetDirectoryName(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)) ?? string.Empty,
|
||||
"~/" => Path.GetDirectoryName(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)) ?? string.Empty,
|
||||
_ => startDir,
|
||||
};
|
||||
string testDir = Path.Combine(currentDir, dirName);
|
||||
|
||||
while (!Directory.Exists(testDir))
|
||||
{
|
||||
currentDir = Path.GetFullPath(Path.Combine(currentDir, ".."));
|
||||
|
||||
if (currentDir == Path.GetPathRoot(currentDir))
|
||||
{
|
||||
if (throwIfNotFound)
|
||||
{
|
||||
throw new DirectoryNotFoundException($"Could not find directory {dirName}!");
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
testDir = Path.Combine(currentDir, dirName);
|
||||
}
|
||||
|
||||
return testDir;
|
||||
}
|
||||
}
|
|
@ -10,8 +10,8 @@
|
|||
<Application.Styles>
|
||||
<!--<FluentTheme />-->
|
||||
<themes:MaterialTheme BaseTheme="Dark" PrimaryColor="Indigo" SecondaryColor="Green" />
|
||||
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
|
||||
<StyleInclude Source="avares://fhir-codegen/Icons.axaml" />
|
||||
<!--<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>-->
|
||||
<!--<StyleInclude Source="avares://fhir-codegen/Icons.axaml" />-->
|
||||
<materialIcons:MaterialIconStyles />
|
||||
<Style Selector="AutoCompleteBox">
|
||||
<Setter Property="Margin" Value="8"/>
|
||||
|
@ -20,12 +20,20 @@
|
|||
<Style Selector="Button">
|
||||
<Setter Property="Margin" Value="8"/>
|
||||
</Style>
|
||||
<Style Selector="Border.cgIconBorder32">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="Padding" Value="8"/>
|
||||
<Setter Property="Width" Value="32"/>
|
||||
<Setter Property="Height" Value="32"/>
|
||||
<Setter Property="Background" Value="#5665be"/>
|
||||
<Setter Property="CornerRadius" Value="4"/>
|
||||
</Style>
|
||||
<Style Selector="Button.cgIconButton">
|
||||
<Setter Property="Margin" Value="8"/>
|
||||
<Setter Property="Width" Value="32"/>
|
||||
<Setter Property="Height" Value="32"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="Background" Value="Indigo"/>
|
||||
<!--<Setter Property="Background" Value="Indigo"/>-->
|
||||
</Style>
|
||||
<Style Selector="ComboBox">
|
||||
<Setter Property="Margin" Value="8"/>
|
||||
|
@ -36,6 +44,25 @@
|
|||
</Style>
|
||||
<Style Selector="Label">
|
||||
<Setter Property="Margin" Value="8"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
<Style Selector="materialIcons|MaterialIcon.cgIcon24">
|
||||
<Setter Property="Margin" Value="8"/>
|
||||
<!--<Setter Property="Width" Value="32"/>
|
||||
<Setter Property="Height" Value="32"/>-->
|
||||
|
||||
<Setter Property="Width" Value="24"/>
|
||||
<Setter Property="Height" Value="24"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
</Style>
|
||||
<Style Selector="Panel.cgIconPanel">
|
||||
<Setter Property="Margin" Value="8"/>
|
||||
<Setter Property="Width" Value="32"/>
|
||||
<Setter Property="Height" Value="32"/>
|
||||
<Setter Property="Background" Value="#5665be"/>
|
||||
</Style>
|
||||
<!--<Style Selector="Grid">
|
||||
<Style Selector="^:Grid.RowDefinition">
|
||||
|
@ -44,7 +71,9 @@
|
|||
</Style>-->
|
||||
<Style Selector="TextBox">
|
||||
<Setter Property="Margin" Value="8"/>
|
||||
<Setter Property="Width" Value="200"/>
|
||||
<Setter Property="MinWidth" Value="400"/>
|
||||
<!--<Setter Property="HorizontalAlignment" Value="Stretch"/>-->
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</Application.Styles>
|
||||
|
||||
|
|
|
@ -550,6 +550,7 @@ public class Program
|
|||
JsonModel = LoaderOptions.JsonDeserializationModel.SystemTextJson,
|
||||
AutoLoadExpansions = rootConfig.AutoLoadExpansions,
|
||||
ResolvePackageDependencies = rootConfig.ResolvePackageDependencies,
|
||||
FhirVersion = rootConfig.FhirVersion,
|
||||
});
|
||||
|
||||
DefinitionCollection? loaded = await loader.LoadPackages(rootConfig.Packages)
|
||||
|
@ -655,6 +656,7 @@ public class Program
|
|||
JsonModel = LoaderOptions.JsonDeserializationModel.SystemTextJson,
|
||||
AutoLoadExpansions = config.AutoLoadExpansions,
|
||||
ResolvePackageDependencies = config.ResolvePackageDependencies,
|
||||
FhirVersion = config.FhirVersion,
|
||||
});
|
||||
|
||||
|
||||
|
@ -695,6 +697,7 @@ public class Program
|
|||
JsonModel = LoaderOptions.JsonDeserializationModel.SystemTextJson,
|
||||
AutoLoadExpansions = config.AutoLoadExpansions,
|
||||
ResolvePackageDependencies = config.ResolvePackageDependencies,
|
||||
FhirVersion = config.FhirVersion,
|
||||
});
|
||||
|
||||
DefinitionCollection? loadedRight = await loaderLeft.LoadPackages(config.ComparePackages)
|
||||
|
@ -999,37 +1002,37 @@ public class Program
|
|||
}
|
||||
|
||||
|
||||
/// <summary>Searches for the FHIR specification directory.</summary>
|
||||
/// <exception cref="DirectoryNotFoundException">Thrown when the requested directory is not
|
||||
/// present.</exception>
|
||||
/// <param name="dirName"> The name of the directory we are searching for.</param>
|
||||
/// <param name="throwIfNotFound">(Optional) True to throw if not found.</param>
|
||||
/// <returns>The found FHIR directory.</returns>
|
||||
public static string FindRelativeDir(
|
||||
string startDir,
|
||||
string dirName,
|
||||
bool throwIfNotFound = true)
|
||||
{
|
||||
string currentDir = string.IsNullOrEmpty(startDir) ? Path.GetDirectoryName(AppContext.BaseDirectory) ?? string.Empty : startDir;
|
||||
string testDir = Path.Combine(currentDir, dirName);
|
||||
///// <summary>Searches for the FHIR specification directory.</summary>
|
||||
///// <exception cref="DirectoryNotFoundException">Thrown when the requested directory is not
|
||||
///// present.</exception>
|
||||
///// <param name="dirName"> The name of the directory we are searching for.</param>
|
||||
///// <param name="throwIfNotFound">(Optional) True to throw if not found.</param>
|
||||
///// <returns>The found FHIR directory.</returns>
|
||||
//public static string FindRelativeDir(
|
||||
// string startDir,
|
||||
// string dirName,
|
||||
// bool throwIfNotFound = true)
|
||||
//{
|
||||
// string currentDir = string.IsNullOrEmpty(startDir) ? Path.GetDirectoryName(AppContext.BaseDirectory) ?? string.Empty : startDir;
|
||||
// string testDir = Path.Combine(currentDir, dirName);
|
||||
|
||||
while (!Directory.Exists(testDir))
|
||||
{
|
||||
currentDir = Path.GetFullPath(Path.Combine(currentDir, ".."));
|
||||
// while (!Directory.Exists(testDir))
|
||||
// {
|
||||
// currentDir = Path.GetFullPath(Path.Combine(currentDir, ".."));
|
||||
|
||||
if (currentDir == Path.GetPathRoot(currentDir))
|
||||
{
|
||||
if (throwIfNotFound)
|
||||
{
|
||||
throw new DirectoryNotFoundException($"Could not find directory {dirName}!");
|
||||
}
|
||||
// if (currentDir == Path.GetPathRoot(currentDir))
|
||||
// {
|
||||
// if (throwIfNotFound)
|
||||
// {
|
||||
// throw new DirectoryNotFoundException($"Could not find directory {dirName}!");
|
||||
// }
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
// return string.Empty;
|
||||
// }
|
||||
|
||||
testDir = Path.Combine(currentDir, dirName);
|
||||
}
|
||||
// testDir = Path.Combine(currentDir, dirName);
|
||||
// }
|
||||
|
||||
return testDir;
|
||||
}
|
||||
// return testDir;
|
||||
//}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,17 @@ using CommunityToolkit.Mvvm.Input;
|
|||
using Hl7.Fhir.Utility;
|
||||
using Material.Icons;
|
||||
using Microsoft.Health.Fhir.CodeGen._ForPackages;
|
||||
using Microsoft.Health.Fhir.CodeGen.CompareTool;
|
||||
using Microsoft.Health.Fhir.CodeGen.Configuration;
|
||||
using Microsoft.Health.Fhir.CodeGen.Loader;
|
||||
using Microsoft.Health.Fhir.CodeGen.Models;
|
||||
using Microsoft.Health.Fhir.CodeGenCommon.Packaging;
|
||||
|
||||
namespace fhir_codegen.ViewModels;
|
||||
|
||||
public partial class CoreComparisonViewModel : ViewModelBase, INavigableViewModel
|
||||
{
|
||||
public static string Label => "Compare FHIR Releases";
|
||||
public static string Label => "Compare FHIR Definitions";
|
||||
public static MaterialIconKind IconKind => MaterialIconKind.Compare;
|
||||
//public static StreamGeometry? IconGeometry => (Application.Current?.TryGetResource("book_question_mark_regular", out object? icon) ?? false) && icon is StreamGeometry sg
|
||||
// ? sg
|
||||
|
@ -51,10 +55,43 @@ public partial class CoreComparisonViewModel : ViewModelBase, INavigableViewMode
|
|||
private string _crossVersionDirectory = "git/fhir-cross-version";
|
||||
|
||||
[ObservableProperty]
|
||||
private int _sourceIndex = 0;
|
||||
private int _sourceReleaseIndex = 0;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _targetIndex = 0;
|
||||
private int _targetReleaseIndex = 0;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _sourceDirectory = "C:\\git\\version-modeling\\20191231\\hl7.fhir.r5.core#4.2.0"; // string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _sourceDirectoryFhirVersionIndex = 2;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _targetDirectory = "C:\\git\\version-modeling\\20181227\\hl7.fhir.r4.core#4.0.1"; // string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _targetDirectoryFhirVersionIndex = 2;
|
||||
|
||||
[ObservableProperty]
|
||||
private string[] _fhirVersions = [ "DSTU2", "STU3", "R4", "R4B", "R5", "R6" ];
|
||||
|
||||
[ObservableProperty]
|
||||
private string _saveDirectory = "C:\\git\\version-modeling\\20191231\\_prev_02_down";
|
||||
|
||||
[ObservableProperty]
|
||||
private List<ValueSetComparison> _valueSetComparisons = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private List<PrimitiveTypeComparison> _primitiveComparisons = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private List<StructureComparison> _complexTypeComparisons = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private List<StructureComparison> _resourceComparisons = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private List<StructureComparison> _extensionComparisons = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private List<string> _corePackages = [];
|
||||
|
@ -65,7 +102,8 @@ public partial class CoreComparisonViewModel : ViewModelBase, INavigableViewMode
|
|||
private static readonly Regex _corePackageRegex = new Regex("^hl7\\.fhir\\.r\\d+[A-Za-z]?\\.(core)$", RegexOptions.Compiled);
|
||||
private static readonly HashSet<string> _releaseVersions = [ "1.0.2", "3.0.2", "4.0.1", "4.3.0", "5.0.0", ];
|
||||
|
||||
public CoreComparisonViewModel()
|
||||
public CoreComparisonViewModel(object? args = null)
|
||||
: base()
|
||||
{
|
||||
// get the current configuration
|
||||
ConfigGui? config = Gui.RunningConfiguration;
|
||||
|
@ -105,7 +143,7 @@ public partial class CoreComparisonViewModel : ViewModelBase, INavigableViewMode
|
|||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void RunComparison()
|
||||
private void RunReleaseComparison()
|
||||
{
|
||||
if (Processing == true)
|
||||
{
|
||||
|
@ -115,7 +153,7 @@ public partial class CoreComparisonViewModel : ViewModelBase, INavigableViewMode
|
|||
Processing = true;
|
||||
ErrorMessage = null;
|
||||
|
||||
if (SourceIndex == TargetIndex)
|
||||
if (SourceReleaseIndex == TargetReleaseIndex)
|
||||
{
|
||||
ErrorMessage = "Source and target cannot be the same";
|
||||
Processing = false;
|
||||
|
@ -124,12 +162,84 @@ public partial class CoreComparisonViewModel : ViewModelBase, INavigableViewMode
|
|||
|
||||
ConfigCompare compareOptions = new()
|
||||
{
|
||||
Packages = [ CorePackages[SourceIndex] ],
|
||||
ComparePackages = [ CorePackages[TargetIndex] ],
|
||||
Packages = [ CorePackages[SourceReleaseIndex] ],
|
||||
ComparePackages = [ CorePackages[TargetReleaseIndex] ],
|
||||
CrossVersionMapSourcePath = CrossVersionDirectory,
|
||||
MapSaveStyle = ConfigCompare.ComparisonMapSaveStyle.None,
|
||||
NoOutput = true,
|
||||
};
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void RunDirectoryComparison()
|
||||
{
|
||||
if (Processing == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(DoDirectoryComparison);
|
||||
}
|
||||
private async void DoDirectoryComparison()
|
||||
{
|
||||
Processing = true;
|
||||
ErrorMessage = null;
|
||||
ValueSetComparisons = [];
|
||||
PrimitiveComparisons = [];
|
||||
ComplexTypeComparisons = [];
|
||||
ResourceComparisons = [];
|
||||
ExtensionComparisons = [];
|
||||
|
||||
if (string.IsNullOrEmpty(SourceDirectory) || string.IsNullOrEmpty(TargetDirectory) || (SourceDirectory == TargetDirectory))
|
||||
{
|
||||
ErrorMessage = "Source and target are required and cannot be the same";
|
||||
Processing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
PackageLoader loader = new(new());
|
||||
DefinitionCollection? source = await loader.LoadPackages([SourceDirectory], fhirVersion: FhirVersions[SourceDirectoryFhirVersionIndex]);
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
ErrorMessage = "Failed to load source definitions";
|
||||
Processing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
DefinitionCollection? target = await loader.LoadPackages([TargetDirectory], fhirVersion: FhirVersions[TargetDirectoryFhirVersionIndex]);
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
ErrorMessage = "Failed to load target definitions";
|
||||
Processing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigCompare compareOptions = string.IsNullOrEmpty(SaveDirectory)
|
||||
? new()
|
||||
{
|
||||
MapSaveStyle = ConfigCompare.ComparisonMapSaveStyle.None,
|
||||
NoOutput = true,
|
||||
}
|
||||
: new()
|
||||
{
|
||||
OutputDirectory = SaveDirectory,
|
||||
//CrossVersionMapDestinationPath = SaveDirectory,
|
||||
MapSaveStyle = ConfigCompare.ComparisonMapSaveStyle.Source,
|
||||
NoOutput = false,
|
||||
};
|
||||
|
||||
PackageComparer comparer = new(compareOptions, source, target);
|
||||
|
||||
PackageComparison results = comparer.Compare();
|
||||
ValueSetComparisons = results.ValueSets.Values.SelectMany(l => l.Select(v => v)).ToList();
|
||||
PrimitiveComparisons = results.PrimitiveTypes.Values.SelectMany(l => l.Select(v => v)).ToList();
|
||||
ComplexTypeComparisons = results.ComplexTypes.Values.SelectMany(l => l.Select(v => v)).ToList();
|
||||
ResourceComparisons = results.Resources.Values.SelectMany(l => l.Select(v => v)).ToList();
|
||||
ExtensionComparisons = results.Extensions.Values.SelectMany(l => l.Select(v => v)).ToList();
|
||||
|
||||
Processing = false;
|
||||
ErrorMessage = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,17 +9,18 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Media;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using fhir_codegen.Views;
|
||||
using Material.Icons;
|
||||
using Material.Styles.Themes;
|
||||
|
||||
namespace fhir_codegen.ViewModels;
|
||||
|
||||
public partial class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isPaneOpen;
|
||||
|
||||
|
@ -29,6 +30,14 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||
[ObservableProperty]
|
||||
private NavigationItemTemplate? _selectedNavigationItem;
|
||||
|
||||
//[ObservableProperty]
|
||||
//private MaterialTheme? _theme = Avalonia.Application.Current?.LocateMaterialTheme<MaterialTheme>();
|
||||
|
||||
public MainWindowViewModel(object? args = null)
|
||||
:base()
|
||||
{
|
||||
}
|
||||
|
||||
partial void OnSelectedNavigationItemChanged(NavigationItemTemplate? value)
|
||||
{
|
||||
if (value == null)
|
||||
|
@ -36,8 +45,12 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||
return;
|
||||
}
|
||||
|
||||
ViewModelBase? target = (ViewModelBase?)Activator.CreateInstance(value.Target);
|
||||
NavigateTo(value.Target);
|
||||
}
|
||||
|
||||
public void NavigateTo(Type targetViewModel, object? args = null)
|
||||
{
|
||||
ViewModelBase? target = (ViewModelBase?)Activator.CreateInstance(targetViewModel, args);
|
||||
if (target == null)
|
||||
{
|
||||
return;
|
||||
|
|
|
@ -93,7 +93,8 @@ public partial class WelcomePageViewModel : ViewModelBase, INavigableViewModel
|
|||
FilteredInstalledPackages = new(packages.Where(p => p.Moniker.Contains(filterValue, StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
|
||||
public WelcomePageViewModel()
|
||||
public WelcomePageViewModel(object? args = null)
|
||||
:base()
|
||||
{
|
||||
// get the current configuration
|
||||
ConfigGui? config = Gui.RunningConfiguration;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
</StackPanel>
|
||||
|
||||
<TabControl Grid.Row="1">
|
||||
<TabItem Header="Configuration">
|
||||
<TabItem Header="FHIR Releases">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="200"/>
|
||||
|
@ -40,8 +40,8 @@
|
|||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="64" /> <!-- ReleasesOnly -->
|
||||
<RowDefinition Height="64" /> <!-- SourcePackage -->
|
||||
<RowDefinition Height="64" /> <!-- RowTargetPacakge -->
|
||||
<RowDefinition Height="64" /> <!-- SourceReleaseIndex -->
|
||||
<RowDefinition Height="64" /> <!-- TargetReleaseIndex -->
|
||||
<RowDefinition Height="64" /> <!-- RowRunComparison -->
|
||||
<RowDefinition Height="64" /> <!-- RowErrorMessage -->
|
||||
<RowDefinition Height="64" /> <!-- RowSourceMaps -->
|
||||
|
@ -49,26 +49,117 @@
|
|||
|
||||
<CheckBox Grid.Row="0" Grid.Column="1" IsChecked="{Binding OnlyReleaseVersions}">Only Show Official Releases</CheckBox>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="Source (left) Package:" VerticalAlignment="Center"/>
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" SelectedIndex="{Binding SourceIndex}" ItemsSource="{Binding CorePackages}"/>
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="Source (left) Package:" HorizontalAlignment="Right"/>
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" SelectedIndex="{Binding SourceReleaseIndex}" ItemsSource="{Binding CorePackages}" HorizontalAlignment="Left"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="Target (right) Package:" VerticalAlignment="Center"/>
|
||||
<ComboBox Grid.Row="2" Grid.Column="1" SelectedIndex="{Binding TargetIndex}" ItemsSource="{Binding CorePackages}"/>
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="Target (right) Package:" HorizontalAlignment="Right"/>
|
||||
<ComboBox Grid.Row="2" Grid.Column="1" SelectedIndex="{Binding TargetReleaseIndex}" ItemsSource="{Binding CorePackages}" HorizontalAlignment="Left"/>
|
||||
|
||||
<StackPanel Grid.Row="3" Grid.Column="1" Orientation="Horizontal">
|
||||
<Button Content="Run Comparison" Command="{Binding RunComparisonCommand}" />
|
||||
<!--<ProgressBar Classes="Circle"/>-->
|
||||
<StackPanel Grid.Row="3" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<Button Content="Run Comparison" Command="{Binding RunReleaseComparisonCommand}" />
|
||||
<ProgressBar Classes="Circle" IsVisible="{Binding Processing}"/>
|
||||
</StackPanel>
|
||||
|
||||
<Label Grid.Row="4" Grid.Column="1" Content="{Binding ErrorMessage}" Foreground="Red" />
|
||||
<Label Grid.Row="4" Grid.Column="1" Content="{Binding ErrorMessage}" Foreground="Red" HorizontalAlignment="Left"/>
|
||||
|
||||
<Label Grid.Row="5" Grid.Column="0" Content="Map source path"/>
|
||||
<TextBox Grid.Row="5" Grid.Column="1" Text="{Binding CrossVersionDirectory}" />
|
||||
<Label Grid.Row="5" Grid.Column="0" Content="Map source path" HorizontalAlignment="Right"/>
|
||||
<TextBox Grid.Row="5" Grid.Column="1" Text="{Binding CrossVersionDirectory}" HorizontalAlignment="Left"/>
|
||||
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="Directories">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="200"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="64" /> <!-- 0 SourceDirectory -->
|
||||
<RowDefinition Height="64" /> <!-- 1 SourceDirectoryFhirVersion -->
|
||||
<RowDefinition Height="64" /> <!-- 2 TargetDirectory -->
|
||||
<RowDefinition Height="64" /> <!-- 3 TargetDirectoryFhirVersion -->
|
||||
<RowDefinition Height="64" /> <!-- 4 SaveDirectory -->
|
||||
<RowDefinition Height="64" /> <!-- 5 RowRunComparison -->
|
||||
<RowDefinition Height="64" /> <!-- 6 RowErrorMessage -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="Source (left) Package:" HorizontalAlignment="Right"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding SourceDirectory}" HorizontalAlignment="Left"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="Source (left) FHIR Version:" HorizontalAlignment="Right"/>
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" SelectedIndex="{Binding SourceDirectoryFhirVersionIndex}" ItemsSource="{Binding FhirVersions}" HorizontalAlignment="Left"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="Target (right) Package:" HorizontalAlignment="Right"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding TargetDirectory}" HorizontalAlignment="Left"/>
|
||||
|
||||
<Label Grid.Row="3" Grid.Column="0" Content="Target (right) FHIR Version:" HorizontalAlignment="Right"/>
|
||||
<ComboBox Grid.Row="3" Grid.Column="1" SelectedIndex="{Binding TargetDirectoryFhirVersionIndex}" ItemsSource="{Binding FhirVersions}" HorizontalAlignment="Left"/>
|
||||
|
||||
<Label Grid.Row="4" Grid.Column="0" Content="Save Directory:" HorizontalAlignment="Right"/>
|
||||
<TextBox Grid.Row="4" Grid.Column="1" Text="{Binding SaveDirectory}" HorizontalAlignment="Left"/>
|
||||
|
||||
<StackPanel Grid.Row="5" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<Button Content="Run Comparison" Command="{Binding RunDirectoryComparisonCommand}" />
|
||||
<ProgressBar Classes="Circle" IsVisible="{Binding Processing}"/>
|
||||
</StackPanel>
|
||||
|
||||
<Label Grid.Row="5" Grid.Column="1" Content="{Binding ErrorMessage}" Foreground="Red" HorizontalAlignment="Left"/>
|
||||
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="Results">
|
||||
|
||||
<TabControl>
|
||||
<TabItem Header="Value Sets">
|
||||
<DataGrid ItemsSource="{Binding ValueSetComparisons}" IsReadOnly="True">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Resource" Binding="{Binding Path=Source.Name}" Width="*"/>
|
||||
<DataGridTextColumn Header="Title" Binding="{Binding Path=Source.Title}" Width="*"/>
|
||||
<DataGridTextColumn Header="Relationship" Binding="{Binding Path=Relationship}" Width="*"/>
|
||||
<DataGridTextColumn Header="Message" Binding="{Binding Path=Message}" Width="3*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</TabItem>
|
||||
<TabItem Header="Primitives">
|
||||
<DataGrid ItemsSource="{Binding PrimitiveComparisons}" IsReadOnly="True">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Resource" Binding="{Binding Path=Source.Name}" Width="*"/>
|
||||
<DataGridTextColumn Header="Title" Binding="{Binding Path=Source.Title}" Width="*"/>
|
||||
<DataGridTextColumn Header="Relationship" Binding="{Binding Path=Relationship}" Width="*"/>
|
||||
<DataGridTextColumn Header="Message" Binding="{Binding Path=Message}" Width="3*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</TabItem>
|
||||
<TabItem Header="Complex Types">
|
||||
<DataGrid ItemsSource="{Binding ComplexTypeComparisons}" IsReadOnly="True">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Resource" Binding="{Binding Path=Source.Name}" Width="*"/>
|
||||
<DataGridTextColumn Header="Title" Binding="{Binding Path=Source.Title}" Width="*"/>
|
||||
<DataGridTextColumn Header="Relationship" Binding="{Binding Path=Relationship}" Width="*"/>
|
||||
<DataGridTextColumn Header="Message" Binding="{Binding Path=Message}" Width="3*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</TabItem>
|
||||
<TabItem Header="Resources">
|
||||
<DataGrid ItemsSource="{Binding ResourceComparisons}" IsReadOnly="True">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Resource" Binding="{Binding Path=Source.Name}" Width="*"/>
|
||||
<DataGridTextColumn Header="Title" Binding="{Binding Path=Source.Title}" Width="*"/>
|
||||
<DataGridTextColumn Header="Relationship" Binding="{Binding Path=Relationship}" Width="*"/>
|
||||
<DataGridTextColumn Header="Message" Binding="{Binding Path=Message}" Width="3*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</TabItem>
|
||||
<TabItem Header="Extensions">
|
||||
<DataGrid ItemsSource="{Binding ExtensionComparisons}" IsReadOnly="True">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Resource" Binding="{Binding Path=Source.Name}" Width="*"/>
|
||||
<DataGridTextColumn Header="Title" Binding="{Binding Path=Source.Title}" Width="*"/>
|
||||
<DataGridTextColumn Header="Relationship" Binding="{Binding Path=Relationship}" Width="*"/>
|
||||
<DataGridTextColumn Header="Message" Binding="{Binding Path=Message}" Width="3*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
|
||||
|
|
|
@ -34,12 +34,15 @@
|
|||
</Button>
|
||||
|
||||
<ListBox ItemsSource="{Binding NavigationItems}"
|
||||
SelectedItem="{Binding SelectedNavigationItem}">
|
||||
SelectedItem="{Binding SelectedNavigationItem}"
|
||||
Margin="0">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type vm:NavigationItemTemplate}">
|
||||
<StackPanel Spacing="12" Margin="4 4" Orientation="Horizontal">
|
||||
<materialIcons:MaterialIcon Kind="{Binding IconKind}" Classes="cgInlineIcon" />
|
||||
<TextBlock Text="{Binding Label}" />
|
||||
<StackPanel Spacing="12" Margin="0" Orientation="Horizontal">
|
||||
<Border Classes="cgIconBorder32">
|
||||
<materialIcons:MaterialIcon Kind="{Binding IconKind}" Classes="cgIcon24"/>
|
||||
</Border>
|
||||
<TextBlock Text="{Binding Label}" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using fhir_codegen;
|
||||
using fhir_codegen.ViewModels;
|
||||
|
||||
namespace fhir_codegen.Views;
|
||||
|
||||
|
|
|
@ -40,9 +40,6 @@
|
|||
<DataGrid
|
||||
Grid.Row="1"
|
||||
ItemsSource="{Binding FilteredInstalledPackages}"
|
||||
GridLinesVisibility="All"
|
||||
BorderBrush="Gray"
|
||||
BorderThickness="1"
|
||||
IsReadOnly="True"
|
||||
CanUserSortColumns="True"
|
||||
VerticalAlignment="Stretch"
|
||||
|
|
Загрузка…
Ссылка в новой задаче