|
- {input.Body} - |
-
| - View Comment - | -
*Note - Please do not reply to this email as it is an automated notification.
- - "; + string htmlBody = await RenderCommentNotificationTemplateAsync(currentUserText, input.Body, commentLink); foreach (var email in input.MentionNamesEmail) { @@ -274,4 +246,68 @@ private async Task UpdateTenantSettings(string settingKey, string valueString) await settingManager.SetForCurrentTenantAsync(settingKey, valueString); } } + + ///|
+ @Html.Raw(Model.CommentBody) + |
+
| + View Comment + | +
*Note - Please do not reply to this email as it is an automated notification.
+ + diff --git a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/Default.cshtml b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/Default.cshtml index 1fc31ed1c2..015e4a3e13 100644 --- a/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/Default.cshtml +++ b/applications/Unity.GrantManager/modules/Unity.Notifications/src/Unity.Notifications.Web/Views/Settings/NotificationsSettingGroup/Default.cshtml @@ -63,7 +63,7 @@ + + diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/CustomFields/Default.css b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/CustomFields/Default.css index b401b9d45c..e5511e4b19 100644 --- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/CustomFields/Default.css +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/CustomFields/Default.css @@ -111,3 +111,203 @@ overflow: auto; height: calc(100vh - 250px); } + +.ai-worksheet-review { + border: 0; + border-radius: 10px; + overflow: hidden; +} + +.ai-worksheet-review__panel { + display: flex; + flex-direction: column; + gap: 12px; + padding: 20px; +} + +.ai-worksheet-review__panel > .modal-header, +.ai-worksheet-review__panel > .modal-body, +.ai-worksheet-review__panel > .modal-footer { + margin: 0; + padding: 0; +} + +.ai-worksheet-review__body { + display: flex; + flex: 0 1 auto; + flex-direction: column; + gap: 12px; + max-height: min(65vh, 42rem); +} + +.ai-worksheet-review__list { + flex: 0 1 auto; + min-height: 0; + overflow-y: auto; +} + +.ai-worksheet-review__header { + border-bottom: 0; +} + +.ai-worksheet-review .modal-title { + color: #1f2933; + font-size: 1.25rem; + font-weight: 600; + line-height: 1.3; + margin: 0; +} + +.ai-worksheet-review__title-group .form-label { + color: #334e68; + font-size: 0.875rem; + font-weight: 600; + margin-bottom: 0.25rem; +} + +.ai-worksheet-review__title-group .form-control { + border-color: #b8c7d6; + font-size: 0.9375rem; +} + +.ai-worksheet-review__title-group .form-control:focus { + border-color: var(--bc-colors-blue-primary, #255a90); + box-shadow: 0 0 0 0.2rem rgb(37 90 144 / 15%); +} + +.ai-worksheet-review__table-header, +.ai-worksheet-review__field { + display: grid; + grid-template-columns: minmax(0, 1fr) 2rem minmax(0, 1fr) auto; +} + +.ai-worksheet-review__table-header { + align-items: center; + background: #f4f7fa; + border-bottom: 1px solid #d8e1eb; + color: #486581; + font-size: 0.75rem; + font-weight: 700; + letter-spacing: 0.05em; + min-height: 2.5rem; + padding-inline: 0.75rem; + position: sticky; + top: 0; + z-index: 1; + text-transform: uppercase; +} + +.ai-worksheet-review__field { + align-items: center; + min-height: 3.5rem; + padding-inline: 0.75rem; +} + +.ai-worksheet-review__field + .ai-worksheet-review__field { + border-top: 1px solid #edf1f5; +} + +.ai-worksheet-review__field-name { + color: #1f2933; + font-size: 0.9375rem; + font-weight: 600; + line-height: 1.4; + overflow-wrap: anywhere; +} + +.ai-worksheet-review__arrow { + color: #52789d; + justify-self: center; +} + +.ai-worksheet-review__switch { + justify-self: end; +} + +.ai-worksheet-review__field:hover { + background: #f9fbfd; +} + +.ai-worksheet-review__select-all { + align-items: center; + display: flex; + justify-self: end; +} + +.ai-worksheet-review__empty { + color: #486581; + text-align: center; +} + +.ai-worksheet-review__footer { + border-top: 0; + gap: 0.5rem; + justify-content: flex-start; +} + +.ai-worksheet-review__footer > * { + margin: 0; +} + +.ai-worksheet-review__footer .btn { + font-size: inherit; + font-weight: 400; +} + +.ai-worksheet-review__discard { + --bs-btn-color: #b42318; + --bs-btn-border-color: #b42318; + --bs-btn-hover-bg: #b42318; + --bs-btn-hover-border-color: #b42318; + --bs-btn-hover-color: #fff; +} + +@media (max-width: 767.98px) { + .ai-worksheet-review__body { + max-height: 70vh; + } + + .ai-worksheet-review__table-header { + display: flex; + justify-content: flex-end; + } + + .ai-worksheet-review__table-header > span { + display: none; + } + + .ai-worksheet-review__field { + grid-template-columns: minmax(0, 1fr) 1.5rem auto; + row-gap: 0.5rem; + } + + .ai-worksheet-review__field-name:first-child { + grid-column: 1 / 2; + } + + .ai-worksheet-review__field-name:nth-child(3) { + grid-column: 1 / 2; + } + + .ai-worksheet-review__field-name::before { + color: #596777; + content: attr(data-field-role); + display: block; + font-size: 0.6875rem; + font-weight: 700; + letter-spacing: 0.05em; + margin-bottom: 0.125rem; + text-transform: uppercase; + } + + .ai-worksheet-review__arrow { + grid-column: 2 / 3; + grid-row: 1 / 3; + } + + .ai-worksheet-review__switch { + grid-column: 3 / 4; + grid-row: 1 / 3; + } + +} diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailHistoryWidget/EmailHistory.css b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailHistoryWidget/EmailHistory.css index c98d1ae801..1a95daec66 100644 --- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailHistoryWidget/EmailHistory.css +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailHistoryWidget/EmailHistory.css @@ -30,7 +30,6 @@ /* Force fixed table layout to prevent column expansion */ #EmailHistoryTable { width: 100% !important; - table-layout: fixed !important; box-sizing: border-box; } @@ -51,6 +50,10 @@ white-space: normal; } +.btn-delete-delayed { + width: 30px !important; +} + @media (max-height: 768px) { .dt-scroll-body { max-height: inherit !important; diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js index 30b67ec0a3..1917dabff4 100644 --- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/EmailsWidget/Default.js @@ -2379,7 +2379,17 @@ const input = document.getElementById(inputId); if (!input?.files?.length) return; - const disallowedTypes = JSON.parse(decodeURIComponent($('#Extensions').val())); + let allowedTypes; + try { + allowedTypes = JSON.parse(decodeURIComponent($('#AllowedFileTypes').val())); + if (!Array.isArray(allowedTypes)) { + throw new TypeError('AllowedFileTypes did not parse to an array'); + } + } catch (e) { + console.warn('Unable to parse allowed file types configuration:', e); + abp.notify.error('Unable to determine allowed file types. Please contact support.'); + return; + } const maxFileSize = decodeURIComponent($('#EmailAttachmentMaxFileSize').val()); let isAllowedTypeError = false; @@ -2388,7 +2398,7 @@ for (let file of input.files) { const ext = file.name.slice(file.name.lastIndexOf('.') + 1).toLowerCase(); - if (disallowedTypes.includes(ext)) { + if (!allowedTypes.includes(ext)) { isAllowedTypeError = true; } if (file.size * 0.000001 > maxFileSize) { diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/appsettings.json b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/appsettings.json index e6a9930983..ec48801416 100644 --- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/appsettings.json +++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/appsettings.json @@ -77,7 +77,7 @@ "ApplicantS3Folder": "Unity/Applicant", "ApplicationS3Folder": "Unity/Application", "AssessmentS3Folder": "Unity/Adjudication", - "DisallowedFileTypes": "[ \"exe\",\"sh\",\"ksh\",\"bat\",\"cmd\" ]", + "AllowedFileTypes": "[ \"pdf\",\"doc\",\"docx\",\"xls\",\"xlsx\",\"ppt\",\"pptx\",\"jpg\",\"jpeg\",\"png\",\"gif\",\"txt\",\"csv\",\"zip\",\"odt\",\"ods\",\"odp\",\"rtf\",\"bmp\",\"tif\",\"tiff\",\"webp\",\"heic\",\"heif\",\"eml\",\"msg\" ]", "MaxFileSize": 25, "EmailAttachmentMaxFileSize": 20, "EmailAttachmentsTotalMaxFileSize": 25 diff --git a/applications/Unity.GrantManager/test/Unity.GrantManager.Application.Tests/AI/GenerateFormWorksheetJobTests.cs b/applications/Unity.GrantManager/test/Unity.GrantManager.Application.Tests/AI/GenerateFormWorksheetJobTests.cs index 009c08dbf6..1ea11d1bd6 100644 --- a/applications/Unity.GrantManager/test/Unity.GrantManager.Application.Tests/AI/GenerateFormWorksheetJobTests.cs +++ b/applications/Unity.GrantManager/test/Unity.GrantManager.Application.Tests/AI/GenerateFormWorksheetJobTests.cs @@ -1,5 +1,7 @@ using System; +using System.Linq; using Shouldly; +using Unity.Flex.Worksheets; using Unity.GrantManager.GrantApplications.Automation.BackgroundJobs; using Xunit; @@ -9,7 +11,12 @@ public class GenerateFormWorksheetJobTests { [Theory] [InlineData("{}")] - [InlineData("""{"Title":"Draft","Sections":[]}""")] + [InlineData("""{"fields":[{"key":"","label":"Project","type":"Text"}]}""")] + [InlineData("""{"fields":[{"key":"project","label":"","type":"Text"}]}""")] + [InlineData("""{"fields":[{"key":"project","label":"Project","type":"Radio"}]}""")] + [InlineData("""{"fields":[{"key":"project","label":"Project","type":2}]}""")] + [InlineData("""{"fields":[{"key":"project","label":"Project","type":" "}]}""")] + [InlineData("""{"fields":[{"key":"project","label":"Project","type":"Text"},{"key":"PROJECT","label":"Other","type":"Text"}]}""")] public void ParseWorksheetDefinition_Should_Reject_Incomplete_Ai_Response(string worksheetJson) { var exception = Should.Throw