diff --git a/DigitalLearningSolutions.Web/Controllers/Support/RequestSupportTicketController.cs b/DigitalLearningSolutions.Web/Controllers/Support/RequestSupportTicketController.cs
index ceedb79af8..3895b3dca2 100644
--- a/DigitalLearningSolutions.Web/Controllers/Support/RequestSupportTicketController.cs
+++ b/DigitalLearningSolutions.Web/Controllers/Support/RequestSupportTicketController.cs
@@ -137,7 +137,7 @@ public IActionResult SetRequestSummary(DlsSubApplication dlsSubApplication, Requ
// Check if RequestDescription is null or contains any default empty tags ("
").
// This ensures that when a user navigates to the submit page and returns to SetRequestSummary,
// removing the description completely results in an actual empty value rather than leftover HTML tags.
- if (requestDetailsmodel.RequestDescription == "
")
+ if (string.IsNullOrEmpty(StringHelper.StripHtmlTags(requestDetailsmodel.RequestDescription)))
{
ModelState.AddModelError("RequestDescription", "Please enter request description");
}
@@ -246,7 +246,7 @@ public IActionResult SupportSummary(DlsSubApplication dlsSubApplication, Support
var data = multiPageFormService.GetMultiPageFormData(
MultiPageFormDataFeature.AddCustomWebForm("RequestSupportTicketCWF"),
TempData
- ).GetAwaiter().GetResult();
+ ).GetAwaiter().GetResult();
var model = new SupportSummaryViewModel(data);
return View("SupportTicketSummaryPage", model);
}
@@ -262,7 +262,7 @@ public IActionResult SubmitSupportSummary(DlsSubApplication dlsSubApplication, S
var data = multiPageFormService.GetMultiPageFormData(
MultiPageFormDataFeature.AddCustomWebForm("RequestSupportTicketCWF"),
TempData
- ).GetAwaiter().GetResult();
+ ).GetAwaiter().GetResult();
data.GroupId = configuration.GetFreshdeskCreateTicketGroupId();
data.ProductId = configuration.GetFreshdeskCreateTicketProductId();
List RequestAttachmentList = new List();
@@ -354,7 +354,7 @@ private void setRequestSupportTicketData(RequestSupportTicketData requestSupport
{
foreach (var item in requestAttachmentmodel.RequestAttachment)
{
- totalFileSize = totalFileSize + item.SizeMb??0;
+ totalFileSize = totalFileSize + item.SizeMb ?? 0;
}
}
foreach (var item in requestAttachmentmodel.ImageFiles)
diff --git a/DigitalLearningSolutions.Web/Helpers/StringHelper.cs b/DigitalLearningSolutions.Web/Helpers/StringHelper.cs
index c2affb6f74..82809fb671 100644
--- a/DigitalLearningSolutions.Web/Helpers/StringHelper.cs
+++ b/DigitalLearningSolutions.Web/Helpers/StringHelper.cs
@@ -26,8 +26,8 @@ public static string StripHtmlTags(string input)
// Remove HTML tags
string result = Regex.Replace(input, "<.*?>", string.Empty).Trim();
-
- return string.IsNullOrEmpty(result) ? string.Empty : result;
+ result = System.Net.WebUtility.HtmlDecode(result);
+ return string.IsNullOrEmpty(result.Trim()) ? string.Empty : result;
}
}
}
diff --git a/DigitalLearningSolutions.Web/Scripts/frameworks/htmleditor.ts b/DigitalLearningSolutions.Web/Scripts/frameworks/htmleditor.ts
index 8577474744..129697c0af 100644
--- a/DigitalLearningSolutions.Web/Scripts/frameworks/htmleditor.ts
+++ b/DigitalLearningSolutions.Web/Scripts/frameworks/htmleditor.ts
@@ -1,4 +1,4 @@
-import { Jodit } from 'jodit';
+import { Jodit } from 'jodit';
import DOMPurify from 'dompurify';
let jodited = false;
@@ -70,5 +70,31 @@ if (jodited === false) {
const clean = DOMPurify.sanitize(editor.editor.innerHTML);
editor.editor.innerHTML = clean;
});
+ const textarea = document.querySelector('.nhsuk-textarea.html-editor.nhsuk-input--error') as HTMLTextAreaElement | null;
+ if (textarea) {
+ const editorDiv = document.querySelector('.jodit-container.jodit.jodit_theme_default.jodit-wysiwyg_mode') as HTMLDivElement | null;
+ editorDiv?.classList.add('jodit-container', 'jodit', 'jodit_theme_default', 'jodit-wysiwyg_mode', 'jodit-error');
+ }
+
+ const summary = document.querySelector('.nhsuk-list.nhsuk-error-summary__list') as HTMLDivElement | null;
+
+ if (summary) {
+ summary.addEventListener('click', (e: Event) => {
+ if (textarea) {
+ const textareaId = textarea.id.toString();
+ const target = e.target as HTMLElement;
+ if (target.tagName.toLowerCase() === 'a') {
+ const href = (target as HTMLAnchorElement).getAttribute('href');
+
+ if (href && href.includes(textareaId)) {
+ const editorArea = document.querySelector('.jodit-wysiwyg') as HTMLDivElement | null;
+ editorArea?.focus();
+ editorArea?.scrollIntoView({ behavior: 'smooth', block: 'center' });
+ e.preventDefault();
+ }
+ }
+ }
+ });
+ }
}
}
diff --git a/DigitalLearningSolutions.Web/Services/ImportCompetenciesFromFileService.cs b/DigitalLearningSolutions.Web/Services/ImportCompetenciesFromFileService.cs
index 66ff813868..dcb388f3ae 100644
--- a/DigitalLearningSolutions.Web/Services/ImportCompetenciesFromFileService.cs
+++ b/DigitalLearningSolutions.Web/Services/ImportCompetenciesFromFileService.cs
@@ -74,11 +74,14 @@ private void PreProcessCompetencyRow(CompetencyTableRow competencyRow, List
else
{
var groupName = (string)(competencyRow?.CompetencyGroup);
- originalIndex = existingGroups.IndexOf(groupName);
- newIndex = newGroups.IndexOf(groupName);
- if (originalIndex != newIndex)
+ if (!string.IsNullOrWhiteSpace(groupName))
{
- competencyRow.Reordered = true;
+ originalIndex = existingGroups.IndexOf(groupName);
+ newIndex = newGroups.IndexOf(groupName);
+ if (originalIndex != newIndex)
+ {
+ competencyRow.Reordered = true;
+ }
}
}
}
diff --git a/DigitalLearningSolutions.Web/Styles/jodit.scss b/DigitalLearningSolutions.Web/Styles/jodit.scss
index 8e0ed889dd..076a7f0053 100644
--- a/DigitalLearningSolutions.Web/Styles/jodit.scss
+++ b/DigitalLearningSolutions.Web/Styles/jodit.scss
@@ -1 +1,6 @@
@use "jodit/build/jodit.min";
+
+.jodit-error {
+ border: 2px solid red !important;
+ border-radius: 4px;
+}
diff --git a/DigitalLearningSolutions.Web/ViewModels/Support/RequestSupportTicket/RequestSummaryViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Support/RequestSupportTicket/RequestSummaryViewModel.cs
index 04371b7998..54b5598e23 100644
--- a/DigitalLearningSolutions.Web/ViewModels/Support/RequestSupportTicket/RequestSummaryViewModel.cs
+++ b/DigitalLearningSolutions.Web/ViewModels/Support/RequestSupportTicket/RequestSummaryViewModel.cs
@@ -21,7 +21,6 @@ public RequestSummaryViewModel(RequestSupportTicketData data)
[Required(ErrorMessage = "Please enter request summary")]
public string? RequestSubject { get; set; }
- [Required(ErrorMessage = "Please enter request description")]
public string? RequestDescription { get; set; }
public int? RequestTypeId { get; set; }
diff --git a/DigitalLearningSolutions.Web/Views/Support/RequestSupportTicket/RequestSummary.cshtml b/DigitalLearningSolutions.Web/Views/Support/RequestSupportTicket/RequestSummary.cshtml
index 316f30e547..a66ce2019f 100644
--- a/DigitalLearningSolutions.Web/Views/Support/RequestSupportTicket/RequestSummary.cshtml
+++ b/DigitalLearningSolutions.Web/Views/Support/RequestSupportTicket/RequestSummary.cshtml
@@ -40,17 +40,15 @@
autocomplete="given-name"
css-class=""
required="true" />
-
-
-
-
+
+