feat: advance legacy UI behavior parity
This commit is contained in:
@@ -3,6 +3,12 @@ using MMoneyCoderSharp.Data;
|
||||
|
||||
namespace MBN_STOCK_WEBVIEW.LegacyApplication;
|
||||
|
||||
public enum LegacyIndustryComparisonSlot
|
||||
{
|
||||
First,
|
||||
Second
|
||||
}
|
||||
|
||||
public sealed record LegacyIndustrySelectionSnapshot(
|
||||
long Revision,
|
||||
IndustryMarket? Market,
|
||||
@@ -11,7 +17,9 @@ public sealed record LegacyIndustrySelectionSnapshot(
|
||||
int? SelectedIndex,
|
||||
IndustrySelection? SelectedIndustry,
|
||||
IndustrySelection? FirstIndustry,
|
||||
IndustrySelection? SecondIndustry);
|
||||
IndustrySelection? SecondIndustry,
|
||||
string FirstText,
|
||||
string SecondText);
|
||||
|
||||
public sealed record LegacyIndustrySceneSelectionDraft(
|
||||
string GroupCode,
|
||||
@@ -52,6 +60,7 @@ public sealed class LegacyIndustryWorkflowException : Exception
|
||||
public sealed class LegacyIndustrySelectionWorkflow
|
||||
{
|
||||
private const int DefaultFadeDuration = 6;
|
||||
public const int MaximumComparisonTextLength = 128;
|
||||
|
||||
private static readonly IReadOnlyList<IndustrySelection> NoIndustries =
|
||||
Array.AsReadOnly(Array.Empty<IndustrySelection>());
|
||||
@@ -68,6 +77,8 @@ public sealed class LegacyIndustrySelectionWorkflow
|
||||
private IndustrySelection? _selectedIndustry;
|
||||
private IndustrySelection? _firstIndustry;
|
||||
private IndustrySelection? _secondIndustry;
|
||||
private string _firstText = string.Empty;
|
||||
private string _secondText = string.Empty;
|
||||
private long _revision;
|
||||
private long _loadGeneration;
|
||||
|
||||
@@ -98,6 +109,8 @@ public sealed class LegacyIndustrySelectionWorkflow
|
||||
_selectedIndustry = null;
|
||||
_firstIndustry = null;
|
||||
_secondIndustry = null;
|
||||
_firstText = string.Empty;
|
||||
_secondText = string.Empty;
|
||||
Touch();
|
||||
return CreateSnapshot();
|
||||
}
|
||||
@@ -128,6 +141,8 @@ public sealed class LegacyIndustrySelectionWorkflow
|
||||
var previousSelected = changingMarket ? null : _selectedIndustry;
|
||||
var previousFirst = changingMarket ? null : _firstIndustry;
|
||||
var previousSecond = changingMarket ? null : _secondIndustry;
|
||||
var previousFirstText = changingMarket ? string.Empty : _firstText;
|
||||
var previousSecondText = changingMarket ? string.Empty : _secondText;
|
||||
|
||||
_market = market;
|
||||
_industries = normalizedRows;
|
||||
@@ -138,6 +153,8 @@ public sealed class LegacyIndustrySelectionWorkflow
|
||||
: FindIdentityIndex(normalizedRows, _selectedIndustry);
|
||||
_firstIndustry = Reconcile(previousFirst, normalizedRows);
|
||||
_secondIndustry = Reconcile(previousSecond, normalizedRows);
|
||||
_firstText = previousFirstText;
|
||||
_secondText = previousSecondText;
|
||||
Touch();
|
||||
return CreateSnapshot();
|
||||
}
|
||||
@@ -168,26 +185,71 @@ public sealed class LegacyIndustrySelectionWorkflow
|
||||
// UC2.listbox_DoubleClick copied txt1 to txt2 before assigning the newly
|
||||
// double-clicked item to txt1.
|
||||
_secondIndustry = _firstIndustry;
|
||||
_secondText = _firstText;
|
||||
_firstIndustry = industry;
|
||||
_firstText = industry.IndustryName;
|
||||
Touch();
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
public LegacyIndustrySelectionSnapshot SetComparisonText(
|
||||
LegacyIndustryComparisonSlot slot,
|
||||
string text)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(text);
|
||||
if (slot is not (LegacyIndustryComparisonSlot.First or LegacyIndustryComparisonSlot.Second))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(slot), slot, "The comparison slot must be 1 or 2.");
|
||||
}
|
||||
|
||||
if (text.Length > MaximumComparisonTextLength ||
|
||||
text.Any(static character =>
|
||||
char.IsControl(character) || char.IsSurrogate(character) || character == '\uFFFD'))
|
||||
{
|
||||
throw new LegacyIndustryWorkflowException("The industry comparison text is invalid.");
|
||||
}
|
||||
|
||||
if (slot == LegacyIndustryComparisonSlot.First)
|
||||
{
|
||||
if (string.Equals(_firstText, text, StringComparison.Ordinal))
|
||||
{
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
_firstText = text;
|
||||
_firstIndustry = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.Equals(_secondText, text, StringComparison.Ordinal))
|
||||
{
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
_secondText = text;
|
||||
_secondIndustry = null;
|
||||
}
|
||||
|
||||
Touch();
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
public LegacyIndustrySelectionSnapshot SwapIndustries()
|
||||
{
|
||||
if (_firstIndustry is null && _secondIndustry is null)
|
||||
if (_firstText.Length == 0 && _secondText.Length == 0)
|
||||
{
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
(_firstIndustry, _secondIndustry) = (_secondIndustry, _firstIndustry);
|
||||
(_firstText, _secondText) = (_secondText, _firstText);
|
||||
Touch();
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
public LegacyIndustrySelectionSnapshot ClearSelections()
|
||||
{
|
||||
if (_selectedIndustry is null && _firstIndustry is null && _secondIndustry is null)
|
||||
if (_selectedIndustry is null && _firstText.Length == 0 && _secondText.Length == 0)
|
||||
{
|
||||
return CreateSnapshot();
|
||||
}
|
||||
@@ -196,6 +258,8 @@ public sealed class LegacyIndustrySelectionWorkflow
|
||||
_selectedIndustry = null;
|
||||
_firstIndustry = null;
|
||||
_secondIndustry = null;
|
||||
_firstText = string.Empty;
|
||||
_secondText = string.Empty;
|
||||
Touch();
|
||||
return CreateSnapshot();
|
||||
}
|
||||
@@ -315,15 +379,17 @@ public sealed class LegacyIndustrySelectionWorkflow
|
||||
LegacyIndustryActionDefinition definition,
|
||||
string groupCode)
|
||||
{
|
||||
if (_firstIndustry is not { } first || _secondIndustry is not { } second ||
|
||||
first.IndustryName.Contains('-', StringComparison.Ordinal) ||
|
||||
second.IndustryName.Contains('-', StringComparison.Ordinal))
|
||||
if (_selectedIndustry is null ||
|
||||
string.IsNullOrWhiteSpace(_firstText) ||
|
||||
string.IsNullOrWhiteSpace(_secondText) ||
|
||||
_firstText.Contains('-', StringComparison.Ordinal) ||
|
||||
_secondText.Contains('-', StringComparison.Ordinal))
|
||||
{
|
||||
throw new LegacyIndustryWorkflowException(
|
||||
$"The {definition.ActionId} action requires two delimiter-safe industries.");
|
||||
$"The {definition.ActionId} action requires a selected industry and two delimiter-safe industries.");
|
||||
}
|
||||
|
||||
var subject = $"{first.IndustryName}-{second.IndustryName}";
|
||||
var subject = $"{_firstText}-{_secondText}";
|
||||
return new IndustryProjection(
|
||||
subject,
|
||||
new LegacyIndustrySceneSelectionDraft(
|
||||
@@ -361,8 +427,6 @@ public sealed class LegacyIndustrySelectionWorkflow
|
||||
throw new LegacyIndustryWorkflowException("The industry list is invalid.");
|
||||
}
|
||||
|
||||
var names = new HashSet<string>(StringComparer.Ordinal);
|
||||
var codes = new HashSet<string>(StringComparer.Ordinal);
|
||||
var normalized = new IndustrySelection[rows.Count];
|
||||
for (var index = 0; index < rows.Count; index++)
|
||||
{
|
||||
@@ -380,12 +444,10 @@ public sealed class LegacyIndustrySelectionWorkflow
|
||||
name.Any(char.IsControl) ||
|
||||
string.IsNullOrEmpty(code) ||
|
||||
code.Length > 32 ||
|
||||
code.Any(character => !char.IsAsciiLetterOrDigit(character)) ||
|
||||
!names.Add(name) ||
|
||||
!codes.Add(code))
|
||||
code.Any(character => !char.IsAsciiLetterOrDigit(character)))
|
||||
{
|
||||
throw new LegacyIndustryWorkflowException(
|
||||
"The industry list contains an unsafe or ambiguous row.");
|
||||
"The industry list contains an unsafe row.");
|
||||
}
|
||||
|
||||
normalized[index] = new IndustrySelection(market, name, code);
|
||||
@@ -452,7 +514,9 @@ public sealed class LegacyIndustrySelectionWorkflow
|
||||
_selectedIndex,
|
||||
_selectedIndustry,
|
||||
_firstIndustry,
|
||||
_secondIndustry);
|
||||
_secondIndustry,
|
||||
_firstText,
|
||||
_secondText);
|
||||
|
||||
private void Touch() => _revision++;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user