From 489b569b298c5c3be37da4692392f5c1af029b96 Mon Sep 17 00:00:00 2001 From: Meet Raval Date: Wed, 6 May 2026 17:06:02 +0530 Subject: [PATCH 1/4] feat: enhance step notes configuration and UI interaction - Added a notes configuration dropdown in the StepNodeView component to allow users to specify the behavior of notes (Required, Optional, Optional for Failure). - Implemented logic to handle changes in notes configuration and updated the UI to reflect the current state of notes visibility based on the selected configuration. - Enhanced the StepNodeListItem component to conditionally display notes input fields based on the notes configuration. - Updated CSS for the notes input area to improve usability and appearance. - Adjusted the data model and database schema to support the new notes configuration feature. --- .../Components/Navigator/NavigationMenu.razor | 4 + .../Pages/Defects/DefectCheckboxPanel.razor | 52 ++ .../Defects/DefectCheckboxPanel.razor.css | 10 + .../Pages/Defects/DefectEditModal.razor | 67 ++ .../Components/Pages/Defects/Defects.razor | 651 ++++++++++++++++++ .../Pages/Defects/Defects.razor.css | 29 + .../WorkInstructionNodes/StepNodeView.razor | 15 +- .../StepNodeView.razor.cs | 9 + .../Pages/ProductionLog/RedTagDialog.razor | 14 + .../StepNodeListItem.razor | 302 ++++++-- .../WorkInstructionStepList.razor | 1 + .../Shared/SearchableDefectSelect.razor | 109 +++ MESS/MESS.Blazor/Components/_Imports.razor | 1 + MESS/MESS.Blazor/Program.cs | 2 + .../wwwroot/Scripts/RedTagDialog.js | 8 + MESS/MESS.Blazor/wwwroot/app.css | 59 ++ MESS/MESS.Data/Context/ApplicationContext.cs | 35 + ...0260420130000_AddStepNotesConfiguration.cs | 30 + ...260420130000_AddStepNotesConfiguration.sql | 31 + ...temptDefectCodesAndWorkInstructionNouns.cs | 114 +++ ...emptDefectCodesAndWorkInstructionNouns.sql | 53 ++ .../ApplicationContextModelSnapshot.cs | 61 ++ MESS/MESS.Data/Models/FailureNoun.cs | 5 + .../Models/ProductionLogStepAttempt.cs | 21 +- MESS/MESS.Data/Models/Step.cs | 7 +- .../Models/StepNotesConfiguration.cs | 16 + MESS/MESS.Data/Models/WorkInstruction.cs | 5 + .../CRUD/Defects/DefectCodeService.cs | 226 ++++++ .../CRUD/Defects/IDefectCodeService.cs | 47 ++ .../WorkInstructionUpdater.cs | 4 +- .../DTOs/Defects/DefectCodeOptionDto.cs | 11 + .../DTOs/Defects/FailureAdjectiveAdminDto.cs | 14 + .../DTOs/Defects/FailureNounAdminDto.cs | 14 + .../Attempts/Detail/StepAttemptDetailDTO.cs | 6 + .../Detail/StepAttemptDetailDTOMapper.cs | 4 +- .../Detail/StepAttemptDetailRequestMapper.cs | 4 +- .../Attempts/Form/StepAttemptFormDTO.cs | 6 + .../Attempts/Form/StepAttemptFormDTOMapper.cs | 8 +- .../Form/StepAttemptFormRequestMapper.cs | 4 +- .../UpdateRequest/StepAttemptUpdateRequest.cs | 6 + .../StepAttemptUpdateRequestMapper.cs | 6 +- .../Nodes/StepNodes/File/StepNodeFileDTO.cs | 5 + .../StepNodes/File/StepNodeFileDTOMapper.cs | 9 +- .../Nodes/StepNodes/Form/StepNodeFormDTO.cs | 6 + .../StepNodes/Form/StepNodeFormDTOMapper.cs | 9 +- .../Nodes/StepNodes/View/StepNodeViewDTO.cs | 4 + .../StepNodes/View/StepNodeViewDTOMapper.cs | 6 +- .../WorkInstructionEditorService.cs | 3 +- 48 files changed, 2048 insertions(+), 65 deletions(-) create mode 100644 MESS/MESS.Blazor/Components/Pages/Defects/DefectCheckboxPanel.razor create mode 100644 MESS/MESS.Blazor/Components/Pages/Defects/DefectCheckboxPanel.razor.css create mode 100644 MESS/MESS.Blazor/Components/Pages/Defects/DefectEditModal.razor create mode 100644 MESS/MESS.Blazor/Components/Pages/Defects/Defects.razor create mode 100644 MESS/MESS.Blazor/Components/Pages/Defects/Defects.razor.css create mode 100644 MESS/MESS.Blazor/Components/Shared/SearchableDefectSelect.razor create mode 100644 MESS/MESS.Data/Migrations/20260420130000_AddStepNotesConfiguration.cs create mode 100644 MESS/MESS.Data/Migrations/20260420130000_AddStepNotesConfiguration.sql create mode 100644 MESS/MESS.Data/Migrations/20260423120000_StepAttemptDefectCodesAndWorkInstructionNouns.cs create mode 100644 MESS/MESS.Data/Migrations/20260423120000_StepAttemptDefectCodesAndWorkInstructionNouns.sql create mode 100644 MESS/MESS.Data/Models/StepNotesConfiguration.cs create mode 100644 MESS/MESS.Services/CRUD/Defects/DefectCodeService.cs create mode 100644 MESS/MESS.Services/CRUD/Defects/IDefectCodeService.cs create mode 100644 MESS/MESS.Services/DTOs/Defects/DefectCodeOptionDto.cs create mode 100644 MESS/MESS.Services/DTOs/Defects/FailureAdjectiveAdminDto.cs create mode 100644 MESS/MESS.Services/DTOs/Defects/FailureNounAdminDto.cs diff --git a/MESS/MESS.Blazor/Components/Navigator/NavigationMenu.razor b/MESS/MESS.Blazor/Components/Navigator/NavigationMenu.razor index 5992beca..2bf92899 100644 --- a/MESS/MESS.Blazor/Components/Navigator/NavigationMenu.razor +++ b/MESS/MESS.Blazor/Components/Navigator/NavigationMenu.razor @@ -53,6 +53,10 @@ href="/tags" @onclick="OnToggleClicked"> Tags + + Defects + diff --git a/MESS/MESS.Blazor/Components/Pages/Defects/DefectCheckboxPanel.razor b/MESS/MESS.Blazor/Components/Pages/Defects/DefectCheckboxPanel.razor new file mode 100644 index 00000000..da7afd6b --- /dev/null +++ b/MESS/MESS.Blazor/Components/Pages/Defects/DefectCheckboxPanel.razor @@ -0,0 +1,52 @@ +@using MESS.Services.DTOs.Defects + +@* Scrollable checkbox list for defect noun/adjective associations (shared styling + a11y). *@ +
+ @Legend + @if (Items.Count == 0) + { +

@EmptyMessage

+ } + else + { +
+ @foreach (var item in Items) + { + var id = $"{Prefix}-{item.Id}"; +
+ + +
+ } +
+ } +
+ +@code { + /// Visible legend / group label (fieldset). + [Parameter] + public string Legend { get; set; } = "Options"; + + /// Stable prefix for checkbox ids (unique per page section). + [Parameter] + public string Prefix { get; set; } = "cb"; + + /// Message when there are no items. + [Parameter] + public string EmptyMessage { get; set; } = "No items yet."; + + [Parameter] + public IReadOnlyList Items { get; set; } = []; + + /// Currently selected ids (hash set or list from edit DTOs). + [Parameter] + public IReadOnlyCollection SelectedIds { get; set; } = []; + + /// Called with (id, change event) when a checkbox toggles. + [Parameter] + public EventCallback<(int Id, ChangeEventArgs Args)> OnToggle { get; set; } +} diff --git a/MESS/MESS.Blazor/Components/Pages/Defects/DefectCheckboxPanel.razor.css b/MESS/MESS.Blazor/Components/Pages/Defects/DefectCheckboxPanel.razor.css new file mode 100644 index 00000000..0574cc6c --- /dev/null +++ b/MESS/MESS.Blazor/Components/Pages/Defects/DefectCheckboxPanel.razor.css @@ -0,0 +1,10 @@ +.defect-checkbox-panel__scroll { + max-height: 10.5rem; + overflow-y: auto; +} + +/* body.dark-mode does not set data-bs-theme=dark, so avoid Bootstrap .text-body (light-theme ink). */ +body.dark-mode .defect-checkbox-panel .defect-checkbox-panel__legend, +body.dark-mode .defect-checkbox-panel .form-check-label { + color: rgba(255, 255, 255, 0.95); +} diff --git a/MESS/MESS.Blazor/Components/Pages/Defects/DefectEditModal.razor b/MESS/MESS.Blazor/Components/Pages/Defects/DefectEditModal.razor new file mode 100644 index 00000000..b7a7736d --- /dev/null +++ b/MESS/MESS.Blazor/Components/Pages/Defects/DefectEditModal.razor @@ -0,0 +1,67 @@ +@* Bootstrap modal shell for edit noun / edit adjective (keyboard: Escape closes via parent). *@ +@if (Show) +{ + +} + +@code { + private readonly string _titleId = $"defect-modal-title-{Guid.NewGuid():N}"; + + [Parameter] + public bool Show { get; set; } + + [Parameter] + public string Title { get; set; } = "Edit"; + + [Parameter] + public RenderFragment? ChildContent { get; set; } + + [Parameter] + public bool Disabled { get; set; } + + [Parameter] + public EventCallback OnClose { get; set; } + + [Parameter] + public EventCallback OnSave { get; set; } + + private async Task CloseAsync() => await OnClose.InvokeAsync(); + + private async Task SaveAsync() => await OnSave.InvokeAsync(); + + private async Task OnBackdropClick(MouseEventArgs _) + { + await CloseAsync(); + } +} diff --git a/MESS/MESS.Blazor/Components/Pages/Defects/Defects.razor b/MESS/MESS.Blazor/Components/Pages/Defects/Defects.razor new file mode 100644 index 00000000..e841f18e --- /dev/null +++ b/MESS/MESS.Blazor/Components/Pages/Defects/Defects.razor @@ -0,0 +1,651 @@ +@page "/defects" +@layout PhoebeLayout +@attribute [Authorize(Roles = "Technician, Administrator")] +@using MESS.Blazor.Components.Layout +@using MESS.Services.CRUD.Defects +@using MESS.Services.CRUD.WorkInstructions +@using MESS.Services.DTOs.Defects +@using MESS.Services.DTOs.FailureAdjectives +@using MESS.Services.DTOs.FailureNouns +@using MESS.Services.DTOs.WorkInstructions.Summary +@using Microsoft.AspNetCore.Authorization +@using Microsoft.FluentUI.AspNetCore.Components +@inject IDefectCodeService DefectCodeService +@inject IWorkInstructionService WorkInstructionService +@inject IToastService ToastService + +Defect codes + +
+
+
+

Defect codes

+

+ Configure defect locations (nouns), defect types (adjectives), their links, and which locations appear for each work instruction in production. +

+
+
+ + @if (_loading) + { +
+ +

Loading defect codes…

+
+ } + else + { + + +
+
+ + @if (_activeTab == "nouns") + { +
+

Add noun

+
+
+ + +
+
+ +
+
+ +
+
+ +

All nouns

+ + + Name + Adjectives + Actions + + + @context.Name + + @FormatNounRowAdjectives(context) + + + + + + + + + + +
+ } + else if (_activeTab == "adjectives") + { +
+

Add adjective

+
+
+ + +
+
+ +
+
+ +
+
+ +

All adjectives

+ + + Name + Nouns + Actions + + + @context.Name + + @FormatAdjectiveRowNouns(context) + + + + + + + + + + +
+ } + else + { +
+

+ Choose a work instruction, load its current noun list, then choose which defect locations operators see during production. +

+
+
+ + +
+
+ +
+
+ + @if (_selectedWorkInstructionId > 0 && _wiNounSelection.Count > 0) + { +
+

Nouns for this instruction

+
+ @foreach (var n in _nouns) + { + var wid = $"wi-noun-{n.Id}"; +
+
+ + +
+
+ } +
+ + } + else if (_selectedWorkInstructionId > 0 && _nouns.Count == 0) + { +
+ Create at least one noun under the Nouns tab before assigning work instructions. +
+ } +
+ } + +
+
+ } +
+ + + @if (_editNoun is not null) + { +
+ + +
+ + } +
+ + + @if (_editAdjective is not null) + { +
+ + +
+ + } +
+ +@code { + private bool _loading = true; + private bool _saving; + private string _activeTab = "nouns"; + + private List _nouns = []; + private List _adjectives = []; + private List _workInstructions = []; + + private string _newNounName = ""; + private HashSet _newNounAdjectiveIds = []; + private string _newAdjectiveName = ""; + private HashSet _newAdjectiveNounIds = []; + + private int _selectedWorkInstructionId; + private Dictionary _wiNounSelection = new(); + + private FailureNounAdminDto? _editNoun; + private FailureAdjectiveAdminDto? _editAdjective; + + private IReadOnlyList AdjectiveSelectOptions => + _adjectives.Select(a => new DefectCodeOptionDto { Id = a.Id, Name = a.Name }).ToList(); + + private IReadOnlyList NounSelectOptions => + _nouns.Select(n => new DefectCodeOptionDto { Id = n.Id, Name = n.Name }).ToList(); + + /// + protected override async Task OnInitializedAsync() + { + await ReloadAsync(); + var wis = await WorkInstructionService.GetAllLatestSummariesAsync(); + _workInstructions = wis.OrderBy(w => w.Title).ToList(); + _loading = false; + } + + private string TabClass(string id) => _activeTab == id ? "active" : ""; + + private void SetTab(string tab) + { + _activeTab = tab; + } + + private static string FormatWiLabel(WorkInstructionSummaryDTO wi) + { + var v = string.IsNullOrWhiteSpace(wi.Version) ? "" : $" v{wi.Version}"; + return $"{wi.Title}{v}"; + } + + private string FormatNounRowAdjectives(FailureNounAdminDto row) + { + if (row.AdjectiveIds.Count == 0) + return "—"; + return string.Join(", ", + _adjectives.Where(a => row.AdjectiveIds.Contains(a.Id)).OrderBy(a => a.Name).Select(a => a.Name)); + } + + private string FormatAdjectiveRowNouns(FailureAdjectiveAdminDto row) + { + if (row.NounIds.Count == 0) + return "—"; + return string.Join(", ", + _nouns.Where(n => row.NounIds.Contains(n.Id)).OrderBy(n => n.Name).Select(n => n.Name)); + } + + private Task OnNewNounAdjectiveToggle((int Id, ChangeEventArgs Args) arg) + { + ToggleHash(_newNounAdjectiveIds, arg.Id, arg.Args); + return Task.CompletedTask; + } + + private Task OnNewAdjectiveNounToggle((int Id, ChangeEventArgs Args) arg) + { + ToggleHash(_newAdjectiveNounIds, arg.Id, arg.Args); + return Task.CompletedTask; + } + + private Task OnEditNounAdjectiveToggle((int Id, ChangeEventArgs Args) arg) + { + ToggleEditNounAdjective(arg.Id, arg.Args); + return Task.CompletedTask; + } + + private Task OnEditAdjectiveNounToggle((int Id, ChangeEventArgs Args) arg) + { + ToggleEditAdjectiveNoun(arg.Id, arg.Args); + return Task.CompletedTask; + } + + private async Task ReloadAsync() + { + _nouns = (await DefectCodeService.GetAllNounsAsync()).OrderBy(n => n.Name).ToList(); + _adjectives = (await DefectCodeService.GetAllAdjectivesAsync()).OrderBy(a => a.Name).ToList(); + } + + private static void ToggleHash(HashSet set, int id, ChangeEventArgs e) + { + var on = e.Value is bool b && b; + if (on) + set.Add(id); + else + set.Remove(id); + } + + private void ToggleEditNounAdjective(int adjectiveId, ChangeEventArgs e) + { + if (_editNoun is null) return; + var on = e.Value is bool b && b; + if (on) + { + if (!_editNoun.AdjectiveIds.Contains(adjectiveId)) + _editNoun.AdjectiveIds.Add(adjectiveId); + } + else + _editNoun.AdjectiveIds.Remove(adjectiveId); + } + + private void ToggleEditAdjectiveNoun(int nounId, ChangeEventArgs e) + { + if (_editAdjective is null) return; + var on = e.Value is bool b && b; + if (on) + { + if (!_editAdjective.NounIds.Contains(nounId)) + _editAdjective.NounIds.Add(nounId); + } + else + _editAdjective.NounIds.Remove(nounId); + } + + private async Task CreateNounAsync() + { + if (string.IsNullOrWhiteSpace(_newNounName)) + return; + _saving = true; + try + { + await DefectCodeService.CreateNounAsync(new FailureNounCreateRequest + { + Name = _newNounName.Trim(), + AdjectiveIds = _newNounAdjectiveIds.ToList() + }); + _newNounName = ""; + _newNounAdjectiveIds.Clear(); + await ReloadAsync(); + ToastService.ShowSuccess("Noun created."); + } + finally + { + _saving = false; + } + } + + private async Task CreateAdjectiveAsync() + { + if (string.IsNullOrWhiteSpace(_newAdjectiveName)) + return; + _saving = true; + try + { + await DefectCodeService.CreateAdjectiveAsync(new FailureAdjectiveCreateRequest + { + Name = _newAdjectiveName.Trim(), + NounIds = _newAdjectiveNounIds.ToList() + }); + _newAdjectiveName = ""; + _newAdjectiveNounIds.Clear(); + await ReloadAsync(); + ToastService.ShowSuccess("Adjective created."); + } + finally + { + _saving = false; + } + } + + private void StartEditNoun(FailureNounAdminDto n) + { + _editNoun = new FailureNounAdminDto { Id = n.Id, Name = n.Name, AdjectiveIds = [..n.AdjectiveIds] }; + } + + private void StartEditAdjective(FailureAdjectiveAdminDto a) + { + _editAdjective = new FailureAdjectiveAdminDto { Id = a.Id, Name = a.Name, NounIds = [..a.NounIds] }; + } + + private Task CloseEditNounAsync() + { + _editNoun = null; + return Task.CompletedTask; + } + + private Task CloseEditAdjectiveAsync() + { + _editAdjective = null; + return Task.CompletedTask; + } + + private async Task SaveEditNounAsync() + { + if (_editNoun is null) return; + _saving = true; + try + { + await DefectCodeService.UpdateNounAsync(new FailureNounUpdateRequest + { + Id = _editNoun.Id, + Name = _editNoun.Name.Trim(), + AdjectiveIds = _editNoun.AdjectiveIds + }); + _editNoun = null; + await ReloadAsync(); + ToastService.ShowSuccess("Noun updated."); + } + finally + { + _saving = false; + } + } + + private async Task SaveEditAdjectiveAsync() + { + if (_editAdjective is null) return; + _saving = true; + try + { + await DefectCodeService.UpdateAdjectiveAsync(new FailureAdjectiveUpdateRequest + { + Id = _editAdjective.Id, + Name = _editAdjective.Name.Trim(), + NounIds = _editAdjective.NounIds + }); + _editAdjective = null; + await ReloadAsync(); + ToastService.ShowSuccess("Adjective updated."); + } + finally + { + _saving = false; + } + } + + private async Task DeleteNounAsync(FailureNounAdminDto n) + { + _saving = true; + try + { + await DefectCodeService.DeleteNounAsync(n.Id); + await ReloadAsync(); + ToastService.ShowSuccess("Noun deleted."); + } + finally + { + _saving = false; + } + } + + private async Task DeleteAdjectiveAsync(FailureAdjectiveAdminDto a) + { + _saving = true; + try + { + await DefectCodeService.DeleteAdjectiveAsync(a.Id); + await ReloadAsync(); + ToastService.ShowSuccess("Adjective deleted."); + } + finally + { + _saving = false; + } + } + + private async Task LoadWiNounSelectionAsync() + { + if (_selectedWorkInstructionId <= 0) + return; + var ids = await DefectCodeService.GetNounIdsForWorkInstructionAsync(_selectedWorkInstructionId); + _wiNounSelection = _nouns.ToDictionary(n => n.Id, n => ids.Contains(n.Id)); + StateHasChanged(); + } + + private void ToggleWiNoun(int nounId, ChangeEventArgs e) + { + var on = e.Value is bool b && b; + _wiNounSelection[nounId] = on; + } + + private async Task SaveWiNounsAsync() + { + if (_selectedWorkInstructionId <= 0) + return; + var ids = _wiNounSelection.Where(kv => kv.Value).Select(kv => kv.Key).ToList(); + _saving = true; + try + { + await DefectCodeService.SetNounsForWorkInstructionAsync(_selectedWorkInstructionId, ids); + ToastService.ShowSuccess("Work instruction nouns saved."); + } + finally + { + _saving = false; + } + } +} diff --git a/MESS/MESS.Blazor/Components/Pages/Defects/Defects.razor.css b/MESS/MESS.Blazor/Components/Pages/Defects/Defects.razor.css new file mode 100644 index 00000000..a34f37d8 --- /dev/null +++ b/MESS/MESS.Blazor/Components/Pages/Defects/Defects.razor.css @@ -0,0 +1,29 @@ +/* Page-specific layout tweaks; inherits global Bootstrap / app.css. + App uses body.dark-mode without data-bs-theme=dark, so BS CSS vars stay "light" + while inactive tabs must stay readable on dark chrome. */ +.defects-page .nav-tabs .nav-link:not(.active) { + color: var(--bs-secondary-color, #6c757d); +} + +body.dark-mode .defects-page .nav-tabs .nav-link:not(.active) { + color: rgba(255, 255, 255, 0.88); +} + +body.dark-mode .defects-page .nav-tabs .nav-link:not(.active):hover, +body.dark-mode .defects-page .nav-tabs .nav-link:not(.active):focus { + color: #ffffff; +} + +.defects-page .nav-tabs .nav-link.active { + color: var(--bs-body-color, #212529); + font-weight: 600; +} + +body.dark-mode .defects-page .form-check-label { + color: rgba(255, 255, 255, 0.95); +} + +.defects-page .defects-tab-card { + border-top-left-radius: 0; + border-top-right-radius: 0; +} diff --git a/MESS/MESS.Blazor/Components/Pages/Phoebe/WorkInstruction/WorkInstructionNodes/StepNodeView.razor b/MESS/MESS.Blazor/Components/Pages/Phoebe/WorkInstruction/WorkInstructionNodes/StepNodeView.razor index 0022bf6d..b22920aa 100644 --- a/MESS/MESS.Blazor/Components/Pages/Phoebe/WorkInstruction/WorkInstructionNodes/StepNodeView.razor +++ b/MESS/MESS.Blazor/Components/Pages/Phoebe/WorkInstruction/WorkInstructionNodes/StepNodeView.razor @@ -1,3 +1,4 @@ +@using MESS.Data.Models @using MESS.Blazor.Components.Pages.Phoebe.WorkInstruction.WorkInstructionNodes.ImageList @inject IJSRuntime JS @@ -21,9 +22,21 @@ - + +
+ + +
diff --git a/MESS/MESS.Blazor/Components/Pages/Phoebe/WorkInstruction/WorkInstructionNodes/StepNodeView.razor.cs b/MESS/MESS.Blazor/Components/Pages/Phoebe/WorkInstruction/WorkInstructionNodes/StepNodeView.razor.cs index 9cdbf263..8e88ea1e 100644 --- a/MESS/MESS.Blazor/Components/Pages/Phoebe/WorkInstruction/WorkInstructionNodes/StepNodeView.razor.cs +++ b/MESS/MESS.Blazor/Components/Pages/Phoebe/WorkInstruction/WorkInstructionNodes/StepNodeView.razor.cs @@ -307,6 +307,15 @@ private async Task OnNameChanged(ChangeEventArgs e) Step.Name = e.Value?.ToString() ?? ""; await NotifyChangeAsync(); } + + private async Task OnNotesConfigurationChanged(ChangeEventArgs e) + { + if (int.TryParse(e.Value?.ToString(), out var v) && Enum.IsDefined(typeof(StepNotesConfiguration), v)) + { + Step.NotesConfiguration = (StepNotesConfiguration)v; + await NotifyChangeAsync(); + } + } private async Task NotifyChangeAsync() { diff --git a/MESS/MESS.Blazor/Components/Pages/ProductionLog/RedTagDialog.razor b/MESS/MESS.Blazor/Components/Pages/ProductionLog/RedTagDialog.razor index 88d902eb..e14932e8 100644 --- a/MESS/MESS.Blazor/Components/Pages/ProductionLog/RedTagDialog.razor +++ b/MESS/MESS.Blazor/Components/Pages/ProductionLog/RedTagDialog.razor @@ -20,6 +20,8 @@
Work Instruction: @ProductionLogEventService.CurrentWorkInstructionName
Step: @StepName
Operator: @OperatorName
+
Defect location: @DefectLocationName
+
Defect: @DefectAdjectiveName
Failure Note: @FailureNotes
@@ -50,6 +52,18 @@ [Parameter] public string StepName { get; set; } = string.Empty; + /// + /// Selected defect location (failure noun) label for print. + /// + [Parameter] + public string DefectLocationName { get; set; } = ""; + + /// + /// Selected defect description (failure adjective) label for print. + /// + [Parameter] + public string DefectAdjectiveName { get; set; } = ""; + /// /// Notes entered by the operator describing the failure condition. /// Displayed in the red tag. diff --git a/MESS/MESS.Blazor/Components/Pages/ProductionLog/WorkInstructionNodes/StepNodeListItem.razor b/MESS/MESS.Blazor/Components/Pages/ProductionLog/WorkInstructionNodes/StepNodeListItem.razor index a3e6709e..5031745b 100644 --- a/MESS/MESS.Blazor/Components/Pages/ProductionLog/WorkInstructionNodes/StepNodeListItem.razor +++ b/MESS/MESS.Blazor/Components/Pages/ProductionLog/WorkInstructionNodes/StepNodeListItem.razor @@ -1,11 +1,16 @@ @using System.Text.RegularExpressions @using MESS.Data.Models @using MESS.Blazor.Components.Carousel +@using MESS.Services.CRUD.Defects +@using MESS.Services.DTOs.Defects @using MESS.Services.DTOs.ProductionLogs.LogSteps.Attempts.Form @using MESS.Services.DTOs.ProductionLogs.LogSteps.Form @using MESS.Services.UI.ProductionLogEvent +@using Microsoft.FluentUI.AspNetCore.Components +@inject IDefectCodeService DefectCodeService @inject IProductionLogEventService ProductionLogEventService @inject IJSRuntime JsRuntime +@inject IToastService ToastService
@@ -36,6 +41,8 @@ - - - - +
+
+ @if (Step.NotesConfiguration == StepNotesConfiguration.Required) + { + + } +