From 0c326a1e29fc7e9ca76446f30909c0625f8c5d16 Mon Sep 17 00:00:00 2001 From: Shawn Jackson Date: Thu, 5 Mar 2026 14:32:31 -0800 Subject: [PATCH 1/5] RE1-T104 First stub of removal --- .../Areas/User/Views/Connect/Posts.cshtml | 6 +- .../User/Views/Department/TextSettings.cshtml | 6 - .../Department/_RecipientsGridPartial.cshtml | 11 +- .../_SmallStationGroupsGridPartial.cshtml | 6 +- .../User/Views/Dispatch/ArchivedCalls.cshtml | 20 +- .../User/Views/Dispatch/CallExport.cshtml | 7 +- .../User/Views/Dispatch/CallExportEx.cshtml | 8 +- .../User/Views/Dispatch/Dashboard.cshtml | 29 +- .../_SmallActiveCallsGridPartial.cshtml | 6 +- .../Dispatch/_SmallCallsGridPartial.cshtml | 6 +- .../Areas/User/Views/Inventory/History.cshtml | 5 +- .../User/Views/Inventory/ManageTypes.cshtml | 6 +- .../Areas/User/Views/Links/View.cshtml | 13 +- .../Areas/User/Views/Logs/Index.cshtml | 8 - .../Views/Logs/_UnitLogBlockPartial.cshtml | 16 +- .../Areas/User/Views/Messages/Inbox.cshtml | 5 - .../Areas/User/Views/Messages/Outbox.cshtml | 5 - .../Areas/User/Views/Orders/Index.cshtml | 3 - .../Areas/User/Views/Profile/Reporting.cshtml | 11 - .../User/Views/Profile/ViewSchedules.cshtml | 11 - .../User/Views/Reports/ActionLogs.cshtml | 8 +- .../Reports/ActiveCallsResourcesReport.cshtml | 17 - .../Views/Reports/CallSummaryReport.cshtml | 157 +--- .../Views/Reports/CertificationsReport.cshtml | 1 - .../Reports/DepartmentActivityReport.cshtml | 163 +--- .../Areas/User/Views/Reports/LogReport.cshtml | 8 +- .../Reports/PersonnelHoursDetailReport.cshtml | 17 +- .../Views/Reports/PersonnelHoursReport.cshtml | 17 +- .../User/Views/Reports/PersonnelReport.cshtml | 1 - .../PersonnelStaffingHistoryReport.cshtml | 17 +- .../User/Views/Reports/StaffingReport.cshtml | 1 - .../Views/Reports/UnitEventsReport.cshtml | 1 - .../Reports/UnitStateHistoryReport.cshtml | 17 +- .../UpcomingShiftReadinessReport.cshtml | 1 - .../Areas/User/Views/Security/Audits.cshtml | 5 +- .../User/Views/Shared/_UserLayout.cshtml | 1 + .../Areas/User/Views/Shifts/Index.cshtml | 41 +- .../User/Views/Shifts/ShiftCalendar.cshtml | 43 +- .../Views/Subscription/ViewInvoice.cshtml | 3 +- .../Views/Units/_SmallUnitsGridPartial.cshtml | 3 - Web/Resgrid.Web/Startup.cs | 11 +- .../Views/Account/CompletedInvite.cshtml | 3 +- Web/Resgrid.Web/Views/Account/Lockout.cshtml | 3 +- .../Views/Account/MissingCode.cshtml | 3 +- .../Views/Account/MissingInvite.cshtml | 3 +- Web/Resgrid.Web/Views/Shared/Error.cshtml | 3 +- .../Views/Shared/Unauthorized.cshtml | 3 +- Web/Resgrid.Web/libman.json | 8 + .../calendar/resgrid.calendar.editEntry.js | 23 +- .../calendar/resgrid.calendar.newEntry.js | 23 +- .../command/resgrid.commands.newcommand.js | 80 +- .../internal/connect/resgrid.connect.posts.js | 50 +- .../resgrid.department.callsettings.js | 64 +- .../resgrid.department.recipientsgrid.js | 50 +- .../department/resgrid.department.settings.js | 23 +- .../resgrid.department.smallstationsgrid.js | 54 +- .../resgrid.department.textsettings.js | 70 +- .../resgrid.dispatch.addArchivedCall.js | 302 ++----- .../dispatch/resgrid.dispatch.archive.js | 79 +- .../dispatch/resgrid.dispatch.dashboard.js | 132 +--- .../dispatch/resgrid.dispatch.editcall.js | 318 ++------ .../dispatch/resgrid.dispatch.newcall.js | 210 +---- .../resgrid.dispatch.smallallcallgrid.js | 72 +- .../resgrid.dispatch.smallcallgrid.js | 72 +- .../internal/dlist/resgrid.dlists.editlist.js | 24 +- .../internal/dlist/resgrid.dlists.newlist.js | 16 +- .../resgrid.documents.newdocument.js | 7 +- .../internal/files/resgrid.files.upload.js | 7 +- .../groups/resgrid.groups.editgroup.js | 63 +- .../groups/resgrid.groups.geofence.js | 2 +- .../groups/resgrid.groups.newgroup.js | 41 +- .../internal/home/resgrid.home.dashboard.js | 49 +- .../home/resgrid.home.edituserprofile.js | 30 +- .../inventory/resgrid.inventory.addType.js | 7 +- .../inventory/resgrid.inventory.adjust.js | 7 +- .../inventory/resgrid.inventory.history.js | 58 +- .../inventory/resgrid.inventory.index.js | 39 +- .../resgrid.inventory.manageTypes.js | 46 +- .../internal/links/resgrid.links.viewdata.js | 188 +---- .../app/internal/logs/resgrid.logs.index.js | 66 +- .../app/internal/logs/resgrid.logs.newlog.js | 131 +--- .../mapping/resgrid.mapping.importPois.js | 7 +- .../mapping/resgrid.mapping.viewType.js | 56 +- .../messages/resgrid.messages.compose.js | 151 ++-- .../messages/resgrid.messages.inbox.js | 124 ++- .../messages/resgrid.messages.outbox.js | 86 +- .../messages/resgrid.messages.topPartial.js | 4 +- .../resgrid.notifications.addNotification.js | 515 ++++-------- .../internal/orders/resgrid.orders.fill.js | 31 +- .../internal/orders/resgrid.orders.index.js | 184 +---- .../orders/resgrid.orders.settings.js | 33 +- .../personnel/resgrid.personnel.addperson.js | 16 +- .../personnel/resgrid.personnel.editRole.js | 27 +- .../resgrid.profile.addcertification.js | 7 +- .../resgrid.profile.addscheduledreport.js | 6 +- .../resgrid.profile.addstaffingschedule.js | 6 +- .../resgrid.profile.editcertification.js | 7 +- .../profile/resgrid.profile.reporting.js | 107 +-- .../profile/resgrid.profile.schedule.js | 107 +-- .../resgrid.protocols.newprotocol.js | 2 +- .../security/resgrid.security.audits.js | 82 +- .../security/resgrid.security.permissions.js | 738 ++---------------- .../shifts/resgrid.shifts.calendar.js | 124 +-- .../shifts/resgrid.shifts.editshiftdetails.js | 76 +- .../internal/shifts/resgrid.shifts.index.js | 126 +-- .../shifts/resgrid.shifts.newshift.js | 40 +- .../shifts/resgrid.shifts.processtrade.js | 16 +- .../shifts/resgrid.shifts.requesttrade.js | 16 +- .../shifts/resgrid.shifts.shiftStaffing.js | 107 ++- .../training/resgrid.training.newtraining.js | 83 +- .../units/resgrid.units.smallunitsgrid.js | 65 +- .../units/resgrid.units.viewevents.js | 157 ++-- .../workshifts/resgrid.workshifts.new.js | 24 +- Web/Resgrid.Web/wwwroot/js/app/resgrid.js | 22 + 114 files changed, 1581 insertions(+), 4721 deletions(-) diff --git a/Web/Resgrid.Web/Areas/User/Views/Connect/Posts.cshtml b/Web/Resgrid.Web/Areas/User/Views/Connect/Posts.cshtml index 682a4e40..97210cc4 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Connect/Posts.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Connect/Posts.cshtml @@ -43,13 +43,9 @@ @section Scripts { - -} \ No newline at end of file +} diff --git a/Web/Resgrid.Web/Areas/User/Views/Department/TextSettings.cshtml b/Web/Resgrid.Web/Areas/User/Views/Department/TextSettings.cshtml index 361b4392..62f865cd 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Department/TextSettings.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Department/TextSettings.cshtml @@ -209,12 +209,6 @@ @section Scripts { - } @@ -37,6 +45,17 @@ +
+
+
+ @localizer["Template"] + @if (!String.IsNullOrWhiteSpace(Model.NewCallFormData)) + { + @localizer["CallForm"] + } +
+
+
@@ -52,6 +71,7 @@ @Html.HiddenFor(m => m.Latitude) @Html.HiddenFor(m => m.Longitude) @Html.HiddenFor(m => m.Call.ReportingUserId) + @Html.HiddenFor(m => m.Call.CallFormData)
@if (!String.IsNullOrEmpty(Model.Message)) @@ -87,6 +107,24 @@
+
+ +
+ + + + +
+
+
+ +
+ + + + +
+
@@ -104,7 +142,7 @@
-
+
@Html.Raw(Model.Call.NatureOfCall)
@@ -114,7 +152,7 @@
-
+
@Html.Raw(Model.Call.Notes)
@@ -148,6 +186,21 @@
+
+ +
+ + + + + + + + + +
@commonLocalizer["Code"]@commonLocalizer["Name"]@commonLocalizer["Status"]
+
+
@@ -164,33 +217,34 @@
- +
+
+ +
+
+
+
@Html.DropDownListFor(m => m.CallState, Model.CallStates, new { @style = "width: 120px;" })
@@ -219,6 +273,66 @@
+ + + + + + + + + @section Scripts { + + @@ -269,4 +411,90 @@ } + + } diff --git a/Web/Resgrid.Web/Areas/User/Views/Dispatch/ArchivedCalls.cshtml b/Web/Resgrid.Web/Areas/User/Views/Dispatch/ArchivedCalls.cshtml index 2cf77a9d..3b055df5 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Dispatch/ArchivedCalls.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Dispatch/ArchivedCalls.cshtml @@ -51,7 +51,7 @@
-
+
diff --git a/Web/Resgrid.Web/Areas/User/Views/Dispatch/Dashboard.cshtml b/Web/Resgrid.Web/Areas/User/Views/Dispatch/Dashboard.cshtml index b1109547..39efb095 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Dispatch/Dashboard.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Dispatch/Dashboard.cshtml @@ -102,7 +102,6 @@ { - diff --git a/Web/Resgrid.Web/Areas/User/Views/Dispatch/UpdateCall.cshtml b/Web/Resgrid.Web/Areas/User/Views/Dispatch/UpdateCall.cshtml index 80121f07..174496d4 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Dispatch/UpdateCall.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Dispatch/UpdateCall.cshtml @@ -40,6 +40,17 @@ +
+
+
+ @localizer["Template"] + @if (!String.IsNullOrWhiteSpace(Model.NewCallFormData)) + { + @localizer["CallForm"] + } +
+
+
@@ -56,6 +67,7 @@ @Html.HiddenFor(m => m.Longitude) @Html.HiddenFor(m => m.Call.CallId) @Html.HiddenFor(m => m.Call.ReportingUserId) + @Html.HiddenFor(m => m.Call.CallFormData)
@if (!String.IsNullOrEmpty(Model.Message)) @@ -166,6 +178,21 @@
+
+ +
+ + + + + + + + + +
@commonLocalizer["Code"]@commonLocalizer["Name"]@commonLocalizer["Status"]
+
+
+
+ +
+
+
+
@@ -234,6 +262,66 @@
+ + + + + + + + + @@ -271,8 +384,11 @@ @section Scripts { + + @@ -280,85 +396,69 @@ diff --git a/Web/Resgrid.Web/Areas/User/Views/Dispatch/_SmallCallsGridPartial.cshtml b/Web/Resgrid.Web/Areas/User/Views/Dispatch/_SmallCallsGridPartial.cshtml index 4dce570d..1a5a02f2 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Dispatch/_SmallCallsGridPartial.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Dispatch/_SmallCallsGridPartial.cshtml @@ -1,3 +1,3 @@ -
+
diff --git a/Web/Resgrid.Web/Areas/User/Views/DistributionLists/EditList.cshtml b/Web/Resgrid.Web/Areas/User/Views/DistributionLists/EditList.cshtml index b580261d..29fa34b7 100644 --- a/Web/Resgrid.Web/Areas/User/Views/DistributionLists/EditList.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/DistributionLists/EditList.cshtml @@ -84,7 +84,7 @@
- +
diff --git a/Web/Resgrid.Web/Areas/User/Views/DistributionLists/NewList.cshtml b/Web/Resgrid.Web/Areas/User/Views/DistributionLists/NewList.cshtml index b81a99ef..34427a10 100644 --- a/Web/Resgrid.Web/Areas/User/Views/DistributionLists/NewList.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/DistributionLists/NewList.cshtml @@ -75,7 +75,7 @@
- +
diff --git a/Web/Resgrid.Web/Areas/User/Views/Groups/EditGroup.cshtml b/Web/Resgrid.Web/Areas/User/Views/Groups/EditGroup.cshtml index 02c9ce13..7fbeb6f5 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Groups/EditGroup.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Groups/EditGroup.cshtml @@ -207,7 +207,7 @@
-
+
@@ -216,7 +216,7 @@ Group Users
- +
diff --git a/Web/Resgrid.Web/Areas/User/Views/Groups/NewGroup.cshtml b/Web/Resgrid.Web/Areas/User/Views/Groups/NewGroup.cshtml index 718d82eb..99c11e11 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Groups/NewGroup.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Groups/NewGroup.cshtml @@ -181,7 +181,7 @@
-
+
@@ -190,7 +190,7 @@ Group Users
- +
diff --git a/Web/Resgrid.Web/Areas/User/Views/Home/EditUserProfile.cshtml b/Web/Resgrid.Web/Areas/User/Views/Home/EditUserProfile.cshtml index 5acf13c0..4a19ecd9 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Home/EditUserProfile.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Home/EditUserProfile.cshtml @@ -310,7 +310,7 @@ {
-
+
} diff --git a/Web/Resgrid.Web/Areas/User/Views/Inventory/AddType.cshtml b/Web/Resgrid.Web/Areas/User/Views/Inventory/AddType.cshtml index 4d9eff87..d9c8e4c9 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Inventory/AddType.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Inventory/AddType.cshtml @@ -1,24 +1,25 @@ @using Resgrid.Model @model Resgrid.Web.Areas.User.Models.Inventory.AddTypeView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Add Inventory Type"; + ViewBag.Title = "Resgrid | " + localizer["AddInventoryTypeHeader"]; }
-

Add Inventory Type

+

@localizer["AddInventoryTypeHeader"]

@@ -46,7 +47,7 @@
@@ -56,7 +57,7 @@
@@ -66,7 +67,7 @@
@@ -76,20 +77,20 @@
@Html.TextBoxFor(m => m.Type.ExpiresDays, new { onkeydown = "javascript:return false;" }) -

For items that don't expire enter 0

+

@localizer["ForItemsNoExpiry"]

- Cancel - + @commonLocalizer["Cancel"] +
@@ -102,4 +103,4 @@ @section Scripts { -} \ No newline at end of file +} diff --git a/Web/Resgrid.Web/Areas/User/Views/Inventory/Adjust.cshtml b/Web/Resgrid.Web/Areas/User/Views/Inventory/Adjust.cshtml index b2a81c82..d89fbea8 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Inventory/Adjust.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Inventory/Adjust.cshtml @@ -1,21 +1,22 @@ @using Resgrid.Model @model Resgrid.Web.Areas.User.Models.Inventory.AdjustView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Adjust Inventory"; + ViewBag.Title = "Resgrid | " + localizer["AdjustInventoryHeader"]; }
-

Adjust Inventory

+

@localizer["AdjustInventoryHeader"]

@@ -43,7 +44,7 @@
@Html.DropDownListFor(m => m.Inventory.TypeId, new SelectList(Model.Types, "InventoryTypeId", "Type"), new { style = "width: 325px" }) @@ -51,7 +52,7 @@
@Html.DropDownListFor(m => m.Inventory.GroupId, new SelectList(Model.Stations, "DepartmentGroupId", "Name"), new { style = "width: 265px" }) @@ -59,17 +60,17 @@
@Html.TextAreaFor(m => m.Inventory.Note, new { @class = "form-control" }) @@ -77,7 +78,7 @@
@Html.TextBoxFor(m => m.Inventory.Batch, new { @class = "form-control" }) @@ -85,7 +86,7 @@
@Html.TextBoxFor(m => m.Inventory.Location, new { @class = "form-control" }) @@ -93,7 +94,7 @@
@Html.TextBoxFor(m => m.Inventory.Amount) @@ -102,8 +103,8 @@
- Cancel - + @commonLocalizer["Cancel"] +
@@ -115,5 +116,10 @@ @section Scripts { + -} \ No newline at end of file +} diff --git a/Web/Resgrid.Web/Areas/User/Views/Inventory/EditType.cshtml b/Web/Resgrid.Web/Areas/User/Views/Inventory/EditType.cshtml index f30fdcad..3f24d838 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Inventory/EditType.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Inventory/EditType.cshtml @@ -1,25 +1,25 @@ @using Resgrid.Model @model Resgrid.Web.Areas.User.Models.Inventory.EditTypeView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Edit Inventory Type"; + ViewBag.Title = "Resgrid | " + localizer["EditInventoryTypeHeader"]; } -
-

Edit Inventory Type

+

@localizer["EditInventoryTypeHeader"]

@@ -48,7 +48,7 @@
@@ -58,7 +58,7 @@
@@ -68,7 +68,7 @@
@@ -78,20 +78,20 @@
@Html.TextBoxFor(m => m.Type.ExpiresDays, new { onkeydown = "javascript:return false;" }) -

For items that don't expire enter 0

+

@localizer["ForItemsNoExpiry"]

- Cancel - + @commonLocalizer["Cancel"] +
@@ -104,4 +104,4 @@ @section Scripts { -} \ No newline at end of file +} diff --git a/Web/Resgrid.Web/Areas/User/Views/Inventory/History.cshtml b/Web/Resgrid.Web/Areas/User/Views/Inventory/History.cshtml index c1bcfd0f..9d9c1a71 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Inventory/History.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Inventory/History.cshtml @@ -1,8 +1,9 @@ @using Resgrid.Model @using Resgrid.Web.Helpers @model Resgrid.Web.Areas.User.Models.Units.UnitsIndexView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Inventory History"; + ViewBag.Title = "Resgrid | " + localizer["InventoryHistoryHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @@ -14,16 +15,16 @@
-

Inventory History

+

@localizer["InventoryHistoryHeader"]

@@ -34,7 +35,7 @@
-
+
@@ -43,6 +44,17 @@ @section Scripts { - + } diff --git a/Web/Resgrid.Web/Areas/User/Views/Inventory/Index.cshtml b/Web/Resgrid.Web/Areas/User/Views/Inventory/Index.cshtml index 8e97576c..2907553e 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Inventory/Index.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Inventory/Index.cshtml @@ -1,8 +1,9 @@ @using Resgrid.Model @using Resgrid.Web.Helpers @model Resgrid.Web.Areas.User.Models.Units.UnitsIndexView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Inventory"; + ViewBag.Title = "Resgrid | " + commonLocalizer["InventoryModule"]; } + + +
+ + @* Header *@ +
+
+ Resgrid +
+
+

@localizer["LogReport"]

+
+
+ + @* Print button — hidden on print *@ +
+
+ +
+
+ + @* General Information *@ +
+
+
+ @localizer["GeneralInformation"] + @logType.ToString() +
+ + + + + + + + + + + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.ExternalId) && logType != LogTypes.Coroner) + { + + } + else + { + + } + @if (Model.WorkLog.StartedOn.HasValue) + { + + } + else + { + + } + @if (Model.WorkLog.EndedOn.HasValue) + { + + } + else if (Model.WorkLog.StartedOn.HasValue && Model.WorkLog.EndedOn.HasValue) + { + var duration = Model.WorkLog.EndedOn.Value - Model.WorkLog.StartedOn.Value; + + } + else + { + + } + + +
+ @localizer["LogId"] + #@Model.WorkLog.LogId + + @localizer["LogType"] + @logType.ToString() + + @localizer["LoggedOn"] + @Model.WorkLog.LoggedOn.TimeConverterToString(Model.Department) + + @localizer["LoggedBy"] + + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.LoggedByUserId) && Model.PersonnelNames.ContainsKey(Model.WorkLog.LoggedByUserId)) + { + @Model.PersonnelNames[Model.WorkLog.LoggedByUserId] + } + else + { + N/A + } + +
+ @commonLocalizer["Station"] + + @if (Model.WorkLog.StationGroup != null) + { + @Model.WorkLog.StationGroup.Name + } + else if (Model.WorkLog.StationGroupId.HasValue) + { + var grp = Model.Groups.FirstOrDefault(g => g.DepartmentGroupId == Model.WorkLog.StationGroupId.Value); + @(grp != null ? grp.Name : commonLocalizer["Unknown"].Value) + } + else + { + @Model.Department.Name + } + + + @localizer["ExternalId"] + @Model.WorkLog.ExternalId + + @commonLocalizer["Start"] + @Model.WorkLog.StartedOn.Value.TimeConverterToString(Model.Department) + + @commonLocalizer["End"] + @Model.WorkLog.EndedOn.Value.TimeConverterToString(Model.Department) + + @localizer["Duration"] + @($"{(int)duration.TotalHours}h {duration.Minutes}m") +
+
+
+ + @* Call Information (Run / Callback) *@ + @if ((logType == LogTypes.Run || logType == LogTypes.Callback) && Model.WorkLog.Call != null) + { +
+
+
@localizer["CallInformation"]
+ + + + + + + + + + + + + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Call.NatureOfCall)) + { + + + + } + +
+ @localizer["CallName"] + @Model.WorkLog.Call.Name + + @localizer["CallNumber"] + @Model.WorkLog.Call.Number + + @commonLocalizer["Type"] + + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Call.Type)) + { + @Model.WorkLog.Call.Type + } + else + { + @localizer["NoType"] + } + + + @localizer["CallPriority"] + @(((CallPriority)Model.WorkLog.Call.Priority).ToString()) +
+ @localizer["LoggedOn"] + @Model.WorkLog.Call.LoggedOn.TimeConverterToString(Model.Department) + + @localizer["CallAddress"] + + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Call.Address)) + { + @Model.WorkLog.Call.Address + } + else + { + @localizer["NotSupplied"] + } + +
+ @localizer["NatureOfCall"] +
@Html.Raw(Model.WorkLog.Call.NatureOfCall)
+
+
+
+ } + + @* Training Information *@ + @if (logType == LogTypes.Training) + { +
+
+
@localizer["TrainingInformation"]
+ + + + + + + + + + + @if (Model.WorkLog.StartedOn.HasValue && Model.WorkLog.EndedOn.HasValue) + { + var dur = Model.WorkLog.EndedOn.Value - Model.WorkLog.StartedOn.Value; + + } + else + { + + } + + +
+ @commonLocalizer["TrainingOrCourse"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.Course) ? "N/A" : Model.WorkLog.Course) + + @commonLocalizer["TrainingCode"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.CourseCode) ? "N/A" : Model.WorkLog.CourseCode) + + @commonLocalizer["Instructors"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.Instructors) ? "N/A" : Model.WorkLog.Instructors) +
+ @commonLocalizer["Start"] + @(Model.WorkLog.StartedOn.HasValue ? Model.WorkLog.StartedOn.Value.TimeConverterToString(Model.Department) : "N/A") + + @commonLocalizer["End"] + @(Model.WorkLog.EndedOn.HasValue ? Model.WorkLog.EndedOn.Value.TimeConverterToString(Model.Department) : "N/A") + + @localizer["Duration"] + @($"{(int)dur.TotalHours}h {dur.Minutes}m") +
+
+
+ } + + @* Meeting Information *@ + @if (logType == LogTypes.Meeting) + { +
+
+
@localizer["MeetingInformation"]
+ + + + + + + + + + + + @if (Model.WorkLog.StartedOn.HasValue && Model.WorkLog.EndedOn.HasValue) + { + var dur = Model.WorkLog.EndedOn.Value - Model.WorkLog.StartedOn.Value; + + } + else + { + + } + + +
+ @localizer["MeetingType"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.Type) ? "N/A" : Model.WorkLog.Type) + + @localizer["Location"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.Location) ? "N/A" : Model.WorkLog.Location) + + @localizer["Presiding"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.Instructors) ? "N/A" : Model.WorkLog.Instructors) + + @localizer["OtherAttendees"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.OtherPersonnel) ? "N/A" : Model.WorkLog.OtherPersonnel) +
+ @commonLocalizer["Start"] + @(Model.WorkLog.StartedOn.HasValue ? Model.WorkLog.StartedOn.Value.TimeConverterToString(Model.Department) : "N/A") + + @commonLocalizer["End"] + @(Model.WorkLog.EndedOn.HasValue ? Model.WorkLog.EndedOn.Value.TimeConverterToString(Model.Department) : "N/A") + + @localizer["Duration"] + @($"{(int)dur.TotalHours}h {dur.Minutes}m") +
+
+
+ } + + @* Coroner Information *@ + @if (logType == LogTypes.Coroner) + { +
+
+
@localizer["CoronerInformation"]
+ + + + + + + + + + + + + + +
+ @localizer["CaseNumber"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.ExternalId) ? "N/A" : Model.WorkLog.ExternalId) + + @localizer["Date"] + @(Model.WorkLog.StartedOn.HasValue ? Model.WorkLog.StartedOn.Value.TimeConverterToString(Model.Department) : "N/A") + + @localizer["PronouncedDeceasedBy"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.PronouncedDeceasedBy) ? "N/A" : Model.WorkLog.PronouncedDeceasedBy) + + @localizer["BodyLocation"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.BodyLocation) ? "N/A" : Model.WorkLog.BodyLocation) +
+ @localizer["SeniorOIC"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.Instructors) ? "N/A" : Model.WorkLog.Instructors) + + @localizer["DestinationLocation"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.Location) ? "N/A" : Model.WorkLog.Location) + + @localizer["OthersHavingContact"] + @(String.IsNullOrWhiteSpace(Model.WorkLog.OtherPersonnel) ? "N/A" : Model.WorkLog.OtherPersonnel) +
+
+
+ } + + @* Log Details — Narrative, Cause, Initial Report, Investigator *@ +
+
+
@localizer["LogDetails"]
+
+
+ + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.InitialReport) && (logType == LogTypes.Run || logType == LogTypes.Callback)) + { +
+
+ @localizer["ConditionInitialReport"] +
@Html.Raw(Model.WorkLog.InitialReport)
+
+
+ } + + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Narrative)) + { +
+
+ @localizer["Narrative"] +
@Html.Raw(Model.WorkLog.Narrative)
+
+
+ } + + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Cause) && (logType == LogTypes.Run || logType == LogTypes.Callback)) + { +
+
+ @localizer["Cause"] +
@Html.Raw(Model.WorkLog.Cause)
+
+
+ } + + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.InvestigatedByUserId) && (logType == LogTypes.Run || logType == LogTypes.Callback)) + { +
+
+ @localizer["Investigator"] + + @if (Model.PersonnelNames.ContainsKey(Model.WorkLog.InvestigatedByUserId)) + { + @Model.PersonnelNames[Model.WorkLog.InvestigatedByUserId] + } + else + { + N/A + } + +
+
+ } + + @* Units *@ + @if (Model.WorkLog.Units != null && Model.WorkLog.Units.Any()) + { +
+
+
@localizer["Units"]
+ + + + + + + + + + + + + + @foreach (var logUnit in Model.WorkLog.Units) + { + var unit = Model.Units.FirstOrDefault(u => u.UnitId == logUnit.UnitId); + var unitPersonnel = Model.WorkLog.Users != null + ? Model.WorkLog.Users.Where(p => p.UnitId == logUnit.UnitId).ToList() + : new List(); + + + + + + + + + + } + +
@commonLocalizer["Units"]@commonLocalizer["Dispatched"]@commonLocalizer["Enrotue"]@commonLocalizer["OnScene"]@commonLocalizer["Released"]@commonLocalizer["InQuarters"]@localizer["Personnel"]
@(unit != null ? unit.Name : $"Unit #{logUnit.UnitId}")@(logUnit.Dispatched.HasValue ? logUnit.Dispatched.Value.TimeConverterToString(Model.Department) : "—")@(logUnit.Enroute.HasValue ? logUnit.Enroute.Value.TimeConverterToString(Model.Department) : "—")@(logUnit.OnScene.HasValue ? logUnit.OnScene.Value.TimeConverterToString(Model.Department) : "—")@(logUnit.Released.HasValue ? logUnit.Released.Value.TimeConverterToString(Model.Department) : "—")@(logUnit.InQuarters.HasValue ? logUnit.InQuarters.Value.TimeConverterToString(Model.Department) : "—") + @if (unitPersonnel.Any()) + { + @string.Join(", ", unitPersonnel.Select(p => Model.PersonnelNames.ContainsKey(p.UserId) ? Model.PersonnelNames[p.UserId] : commonLocalizer["Unknown"].Value)) + } + else + { + + } +
+
+
+ } + + @* Non-unit Personnel *@ + @{ + var nonUnitPersonnel = Model.WorkLog.Users != null + ? Model.WorkLog.Users.Where(p => !p.UnitId.HasValue).ToList() + : new List(); + } + @if (nonUnitPersonnel.Any()) + { +
+
+
@localizer["Personnel"]
+ + + + + + + + @foreach (var p in nonUnitPersonnel) + { + + + + } + +
@commonLocalizer["Name"]
@(Model.PersonnelNames.ContainsKey(p.UserId) ? Model.PersonnelNames[p.UserId] : commonLocalizer["Unknown"].Value)
+
+
+ } + + @* Attachments *@ + @if (Model.Attachments != null && Model.Attachments.Any()) + { +
+
+
@localizer["Attachments"]
+ + + + + + + + + + + @foreach (var attachment in Model.Attachments) + { + + + + + + + } + +
@commonLocalizer["Name"]@commonLocalizer["Type"]@commonLocalizer["UploadedBy"]@commonLocalizer["Timestamp"]
@attachment.FileName@attachment.Type + @if (!String.IsNullOrWhiteSpace(attachment.UserId) && Model.PersonnelNames.ContainsKey(attachment.UserId)) + { + @Model.PersonnelNames[attachment.UserId] + } + else + { + + } + @attachment.Timestamp.TimeConverterToString(Model.Department)
+
+
+ } + + @* Footer *@ +
+ +
+ +
+ + + + + + + diff --git a/Web/Resgrid.Web/Areas/User/Views/Logs/ViewLog.cshtml b/Web/Resgrid.Web/Areas/User/Views/Logs/ViewLog.cshtml new file mode 100644 index 00000000..5274e0c6 --- /dev/null +++ b/Web/Resgrid.Web/Areas/User/Views/Logs/ViewLog.cshtml @@ -0,0 +1,650 @@ +@using Resgrid.Model +@using Resgrid.Model.Helpers +@using Resgrid.Web.Helpers +@model Resgrid.Web.Areas.User.Models.Logs.ViewLogsView +@inject IStringLocalizer localizer +@{ + ViewBag.Title = "Resgrid | " + localizer["ViewLogHeader"]; + var logType = Model.WorkLog.LogType.HasValue ? (LogTypes)Model.WorkLog.LogType.Value : LogTypes.Run; + var logTypeLabelClass = logType == LogTypes.Run ? "danger" + : logType == LogTypes.Training ? "primary" + : logType == LogTypes.Work ? "warning" + : logType == LogTypes.Meeting ? "info" + : logType == LogTypes.Coroner ? "default" + : "success"; +} + +
+
+

@localizer["ViewLogHeader"]

+ +
+ +
+ +
+
+
+ + @* General Information *@ +
+
+
@localizer["GeneralInformation"]
+
+
+
+
+
+ + @localizer["PrintExportView"] + + + @logType.ToString() + +

@localizer["LogId"] #@Model.WorkLog.LogId

+
+
+
+
+
+
+
@localizer["LogType"]:
+
@logType.ToString()
+ +
@localizer["LoggedOn"]:
+
@Model.WorkLog.LoggedOn.TimeConverterToString(Model.Department)
+ +
@localizer["LoggedBy"]:
+
+ @if (!String.IsNullOrWhiteSpace(Model.WorkLog.LoggedByUserId) && Model.PersonnelNames.ContainsKey(Model.WorkLog.LoggedByUserId)) + { + @Model.PersonnelNames[Model.WorkLog.LoggedByUserId] + } + else + { + N/A + } +
+ +
@commonLocalizer["Station"]:
+
+ @if (Model.WorkLog.StationGroup != null) + { + @Model.WorkLog.StationGroup.Name + } + else if (Model.WorkLog.StationGroupId.HasValue) + { + var grp = Model.Groups.FirstOrDefault(g => g.DepartmentGroupId == Model.WorkLog.StationGroupId.Value); + @(grp != null ? grp.Name : commonLocalizer["Unknown"].Value) + } + else + { + @Model.Department.Name + } +
+
+
+
+
+ @if (!String.IsNullOrWhiteSpace(Model.WorkLog.ExternalId) && logType != LogTypes.Coroner) + { +
@localizer["ExternalId"]:
+
@Model.WorkLog.ExternalId
+ } + + @if (Model.WorkLog.StartedOn.HasValue) + { +
@commonLocalizer["Start"]:
+
@Model.WorkLog.StartedOn.Value.TimeConverterToString(Model.Department)
+ } + + @if (Model.WorkLog.EndedOn.HasValue) + { +
@commonLocalizer["End"]:
+
@Model.WorkLog.EndedOn.Value.TimeConverterToString(Model.Department)
+ } + + @if (Model.WorkLog.StartedOn.HasValue && Model.WorkLog.EndedOn.HasValue) + { + var duration = Model.WorkLog.EndedOn.Value - Model.WorkLog.StartedOn.Value; +
@localizer["Duration"]:
+
@($"{(int)duration.TotalHours}h {duration.Minutes}m")
+ } +
+
+
+
+
+ + @* Call Information (Run / Callback log types) *@ + @if ((logType == LogTypes.Run || logType == LogTypes.Callback) && Model.WorkLog.Call != null) + { +
+
+
@localizer["CallInformation"]
+
+
+
+
+
+
@localizer["CallName"]:
+
@Model.WorkLog.Call.Name
+ +
@localizer["CallNumber"]:
+
@Model.WorkLog.Call.Number
+ + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Call.Type)) + { +
@commonLocalizer["Type"]:
+
@Model.WorkLog.Call.Type
+ } + +
@localizer["CallPriority"]:
+
@(((CallPriority)Model.WorkLog.Call.Priority).ToString())
+
+
+
+
+
@localizer["LoggedOn"]:
+
@Model.WorkLog.Call.LoggedOn.TimeConverterToString(Model.Department)
+ + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Call.Address)) + { +
@localizer["CallAddress"]:
+
@Model.WorkLog.Call.Address
+ } +
+
+
+ @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Call.NatureOfCall)) + { +
+
+ @localizer["NatureOfCall"]: +
@Html.Raw(Model.WorkLog.Call.NatureOfCall)
+
+
+ } + +
+
+ } + + @* Training Information *@ + @if (logType == LogTypes.Training) + { +
+
+
@localizer["TrainingInformation"]
+
+
+
+ @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Course)) + { +
@commonLocalizer["TrainingOrCourse"]:
+
@Model.WorkLog.Course
+ } + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.CourseCode)) + { +
@commonLocalizer["TrainingCode"]:
+
@Model.WorkLog.CourseCode
+ } + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Instructors)) + { +
@commonLocalizer["Instructors"]:
+
@Model.WorkLog.Instructors
+ } + @if (Model.WorkLog.StartedOn.HasValue) + { +
@commonLocalizer["Start"]:
+
@Model.WorkLog.StartedOn.Value.TimeConverterToString(Model.Department)
+ } + @if (Model.WorkLog.EndedOn.HasValue) + { +
@commonLocalizer["End"]:
+
@Model.WorkLog.EndedOn.Value.TimeConverterToString(Model.Department)
+ } +
+
+
+ } + + @* Meeting Information *@ + @if (logType == LogTypes.Meeting) + { +
+
+
@localizer["MeetingInformation"]
+
+
+
+ @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Type)) + { +
@localizer["MeetingType"]:
+
@Model.WorkLog.Type
+ } + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Location)) + { +
@localizer["Location"]:
+
@Model.WorkLog.Location
+ } + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Instructors)) + { +
@localizer["Presiding"]:
+
@Model.WorkLog.Instructors
+ } + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.OtherPersonnel)) + { +
@localizer["OtherAttendees"]:
+
@Model.WorkLog.OtherPersonnel
+ } + @if (Model.WorkLog.StartedOn.HasValue) + { +
@commonLocalizer["Start"]:
+
@Model.WorkLog.StartedOn.Value.TimeConverterToString(Model.Department)
+ } + @if (Model.WorkLog.EndedOn.HasValue) + { +
@commonLocalizer["End"]:
+
@Model.WorkLog.EndedOn.Value.TimeConverterToString(Model.Department)
+ } +
+
+
+ } + + @* Coroner Information *@ + @if (logType == LogTypes.Coroner) + { +
+
+
@localizer["CoronerInformation"]
+
+
+
+ @if (!String.IsNullOrWhiteSpace(Model.WorkLog.ExternalId)) + { +
@localizer["CaseNumber"]:
+
@Model.WorkLog.ExternalId
+ } + @if (Model.WorkLog.StartedOn.HasValue) + { +
@localizer["Date"]:
+
@Model.WorkLog.StartedOn.Value.TimeConverterToString(Model.Department)
+ } + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.PronouncedDeceasedBy)) + { +
@localizer["PronouncedDeceasedBy"]:
+
@Model.WorkLog.PronouncedDeceasedBy
+ } + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.BodyLocation)) + { +
@localizer["BodyLocation"]:
+
@Model.WorkLog.BodyLocation
+ } + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Instructors)) + { +
@localizer["SeniorOIC"]:
+
@Model.WorkLog.Instructors
+ } + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Location)) + { +
@localizer["DestinationLocation"]:
+
@Model.WorkLog.Location
+ } + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.OtherPersonnel)) + { +
@localizer["OthersHavingContact"]:
+
@Model.WorkLog.OtherPersonnel
+ } +
+
+
+ } + + @* Log Narrative and Details *@ +
+
+
@localizer["LogDetails"]
+
+
+ + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.InitialReport) && (logType == LogTypes.Run || logType == LogTypes.Callback)) + { +
+ +
@Html.Raw(Model.WorkLog.InitialReport)
+
+ } + + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Narrative)) + { +
+ +
@Html.Raw(Model.WorkLog.Narrative)
+
+ } + + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.Cause) && (logType == LogTypes.Run || logType == LogTypes.Callback)) + { +
+ +
@Html.Raw(Model.WorkLog.Cause)
+
+ } + + @if (!String.IsNullOrWhiteSpace(Model.WorkLog.InvestigatedByUserId) && (logType == LogTypes.Run || logType == LogTypes.Callback)) + { +
+ +

+ @if (Model.PersonnelNames.ContainsKey(Model.WorkLog.InvestigatedByUserId)) + { + @Model.PersonnelNames[Model.WorkLog.InvestigatedByUserId] + } +

+
+ } + +
+
+ + @* Units and Personnel *@ + @if ((Model.WorkLog.Units != null && Model.WorkLog.Units.Any()) || (Model.WorkLog.Users != null && Model.WorkLog.Users.Any())) + { +
+
+
@localizer["UnitsAndPersonnel"]
+
+
+ + @if (Model.WorkLog.Units != null && Model.WorkLog.Units.Any()) + { +

@localizer["Units"]

+
+ + + + + + + + + + + + + + @foreach (var logUnit in Model.WorkLog.Units) + { + var unit = Model.Units.FirstOrDefault(u => u.UnitId == logUnit.UnitId); + var unitPersonnel = Model.WorkLog.Users != null + ? Model.WorkLog.Users.Where(p => p.UnitId == logUnit.UnitId).ToList() + : new List(); + + + + + + + + + + } + +
@commonLocalizer["Units"]@commonLocalizer["Dispatched"]@commonLocalizer["Enrotue"]@commonLocalizer["OnScene"]@commonLocalizer["Released"]@commonLocalizer["InQuarters"]@localizer["Personnel"]
@(unit != null ? unit.Name : $"Unit #{logUnit.UnitId}") + @if (logUnit.Dispatched.HasValue) + { + @logUnit.Dispatched.Value.TimeConverterToString(Model.Department) + } + else + { + + } + + @if (logUnit.Enroute.HasValue) + { + @logUnit.Enroute.Value.TimeConverterToString(Model.Department) + } + else + { + + } + + @if (logUnit.OnScene.HasValue) + { + @logUnit.OnScene.Value.TimeConverterToString(Model.Department) + } + else + { + + } + + @if (logUnit.Released.HasValue) + { + @logUnit.Released.Value.TimeConverterToString(Model.Department) + } + else + { + + } + + @if (logUnit.InQuarters.HasValue) + { + @logUnit.InQuarters.Value.TimeConverterToString(Model.Department) + } + else + { + + } + + @if (unitPersonnel.Any()) + { +
    + @foreach (var p in unitPersonnel) + { +
  • + @if (Model.PersonnelNames.ContainsKey(p.UserId)) + { + @Model.PersonnelNames[p.UserId] + } + else + { + @commonLocalizer["Unknown"] + } +
  • + } +
+ } + else + { + + } +
+
+ } + + @{ + var nonUnitPersonnel = Model.WorkLog.Users != null + ? Model.WorkLog.Users.Where(p => !p.UnitId.HasValue).ToList() + : new List(); + } + @if (nonUnitPersonnel.Any()) + { +

@localizer["Personnel"] (@localizer["PersonnelNotAssignedUnit"])

+ + + + + + + + @foreach (var p in nonUnitPersonnel) + { + + + + } + +
@commonLocalizer["Name"]
+ @if (Model.PersonnelNames.ContainsKey(p.UserId)) + { + @Model.PersonnelNames[p.UserId] + } + else + { + @commonLocalizer["Unknown"] + } +
+ } + +
+
+ } + + @* Attachments *@ + @if (Model.Attachments != null && Model.Attachments.Any()) + { +
+
+
@localizer["Attachments"]
+
+
+ + + + + + + + + + + + @foreach (var attachment in Model.Attachments) + { + + + + + + + + } + +
@commonLocalizer["Name"]@commonLocalizer["Type"]@commonLocalizer["UploadedBy"]@commonLocalizer["Timestamp"]@commonLocalizer["Action"]
@attachment.FileName@attachment.Type + @if (!String.IsNullOrWhiteSpace(attachment.UserId) && Model.PersonnelNames.ContainsKey(attachment.UserId)) + { + @Model.PersonnelNames[attachment.UserId] + } + else + { + + } + @attachment.Timestamp.TimeConverterToString(Model.Department) + + @commonLocalizer["Download"] + +
+
+
+ } + +
+
+ + @* Sidebar *@ +
+
+ +
+
+
@localizer["LogSummary"]
+
+
+
    +
  • + @localizer["LogId"] + #@Model.WorkLog.LogId +
  • +
  • + @localizer["LogType"] + + @logType.ToString() + +
  • +
  • + @localizer["LoggedOn"] + @Model.WorkLog.LoggedOn.TimeConverterToString(Model.Department) +
  • + @if (Model.WorkLog.StartedOn.HasValue && Model.WorkLog.EndedOn.HasValue) + { + var dur = Model.WorkLog.EndedOn.Value - Model.WorkLog.StartedOn.Value; +
  • + @localizer["Duration"] + @($"{(int)dur.TotalHours}h {dur.Minutes}m") +
  • + } +
  • + @commonLocalizer["Units"] + @(Model.WorkLog.Units != null ? Model.WorkLog.Units.Count : 0) +
  • +
  • + @commonLocalizer["Personnel"] + @(Model.WorkLog.Users != null ? Model.WorkLog.Users.Count : 0) +
  • +
  • + @commonLocalizer["Attachments"] + @(Model.Attachments != null ? Model.Attachments.Count : 0) +
  • +
+
+
+ +
+
+
@commonLocalizer["Actions"]
+
+ +
+ +
+
+
+ + diff --git a/Web/Resgrid.Web/Areas/User/Views/Mapping/ViewType.cshtml b/Web/Resgrid.Web/Areas/User/Views/Mapping/ViewType.cshtml index 5ced8baf..df48d17c 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Mapping/ViewType.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Mapping/ViewType.cshtml @@ -106,7 +106,7 @@
-
+
diff --git a/Web/Resgrid.Web/Areas/User/Views/Messages/Compose.cshtml b/Web/Resgrid.Web/Areas/User/Views/Messages/Compose.cshtml index 3cc537bc..0c5d9c14 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Messages/Compose.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Messages/Compose.cshtml @@ -61,9 +61,9 @@
-
-
-
+
+
+
@@ -96,7 +96,7 @@
diff --git a/Web/Resgrid.Web/Areas/User/Views/Notifications/New.cshtml b/Web/Resgrid.Web/Areas/User/Views/Notifications/New.cshtml index b932660b..7abd930c 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Notifications/New.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Notifications/New.cshtml @@ -136,13 +136,13 @@
- +
- +
- +
@@ -188,4 +188,4 @@ @section Scripts { -} \ No newline at end of file +} diff --git a/Web/Resgrid.Web/Areas/User/Views/Personnel/ViewEvents.cshtml b/Web/Resgrid.Web/Areas/User/Views/Personnel/ViewEvents.cshtml new file mode 100644 index 00000000..70dc564a --- /dev/null +++ b/Web/Resgrid.Web/Areas/User/Views/Personnel/ViewEvents.cshtml @@ -0,0 +1,107 @@ +@model Resgrid.Web.Areas.User.Models.Personnel.ViewPersonEventsView +@inject IStringLocalizer localizer +@{ + ViewBag.Title = "Resgrid | " + @localizer["ViewPersonEventsHeader"]; +} +@section Styles + { + +} + +
+
+

@localizer["EventsFor"] @Model.PersonName

+ +
+
+
+ @if (ClaimsAuthorizationHelper.IsUserDepartmentAdmin()) + { + @localizer["ClearAllStatuses"] + } +
+
+
+ +@using (Html.BeginForm("GeneratePersonnelEventsReport", "Personnel", FormMethod.Post, new { area = "User", @class = "form-horizontal" })) +{ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+} + + + +@section Scripts + { + + +} diff --git a/Web/Resgrid.Web/Areas/User/Views/Personnel/ViewPerson.cshtml b/Web/Resgrid.Web/Areas/User/Views/Personnel/ViewPerson.cshtml index 926417c1..f1b4d8a2 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Personnel/ViewPerson.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Personnel/ViewPerson.cshtml @@ -22,6 +22,11 @@
+
diff --git a/Web/Resgrid.Web/Areas/User/Views/Profile/Reporting.cshtml b/Web/Resgrid.Web/Areas/User/Views/Profile/Reporting.cshtml index 71aab583..841ec759 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Profile/Reporting.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Profile/Reporting.cshtml @@ -36,7 +36,7 @@
-
+
diff --git a/Web/Resgrid.Web/Areas/User/Views/Profile/ViewSchedules.cshtml b/Web/Resgrid.Web/Areas/User/Views/Profile/ViewSchedules.cshtml index 5c3ff05b..e55bd7c0 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Profile/ViewSchedules.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Profile/ViewSchedules.cshtml @@ -53,7 +53,7 @@
-
+
diff --git a/Web/Resgrid.Web/Areas/User/Views/Reports/PersonnelEventsReport.cshtml b/Web/Resgrid.Web/Areas/User/Views/Reports/PersonnelEventsReport.cshtml new file mode 100644 index 00000000..27480174 --- /dev/null +++ b/Web/Resgrid.Web/Areas/User/Views/Reports/PersonnelEventsReport.cshtml @@ -0,0 +1,101 @@ +@using Resgrid.Model.Helpers +@using Resgrid.Web +@using Resgrid.Web.Helpers +@model Resgrid.Web.Areas.User.Models.Reports.Personnel.PersonnelEventsReportView +@{ + Layout = null; +} + + + + + + Resgrid Personnel Events Report + + + + + + + + + + + + + + + + + +
+
+
+ Resgrid Logo +
+
+ @if (Model.Rows != null && Model.Rows.Count > 0) + { +

@Model.Rows[0].PersonName Events Report

+ } + else + { +

Resgrid Personnel Events Report

+ } +
+
+
+
+ + + + + + + + + + + + @if (Model.Rows != null) + { + @foreach (var row in Model.Rows) + { + + + + + + + + } + } + +
StatusDestination\CallTimestampLocationNote
@row.State@row.DestinationName@row.Timestamp@row.Latitude,@row.Longitude@row.Note
+
+
+
+
+ @Model.RunOn.FormatForDepartment(Model.Department) +
+
+
+ + + + + + diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftDays.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftDays.cshtml index d5fc9110..4b6da4ab 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftDays.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftDays.cshtml @@ -1,8 +1,8 @@ - -@using Resgrid.Model +@using Resgrid.Model @model Resgrid.Web.Areas.User.Models.Shifts.EditShiftView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Edit Shift Calendar"; + ViewBag.Title = "Resgrid | " + localizer["EditShiftCalendarHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @@ -14,16 +14,16 @@
-

Edit Shift Calendar

+

@localizer["EditShiftCalendarHeader"]

@@ -60,8 +60,8 @@
- Cancel - + @localizer["CancelButton"] +
diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftDetails.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftDetails.cshtml index a2ac6ffe..7bb110b3 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftDetails.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftDetails.cshtml @@ -1,23 +1,23 @@ - -@using Resgrid.Model +@using Resgrid.Model @model Resgrid.Web.Areas.User.Models.Shifts.EditShiftView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Edit Shift Details"; + ViewBag.Title = "Resgrid | " + localizer["EditShiftDetailsHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; }
-

Edit Shift Details

+

@localizer["EditShiftDetailsHeader"]

@@ -48,45 +48,45 @@
- +
- - For example ("A Shift", "B Shift", "C Shift") + + @localizer["NameHelp"]
- +
- - Example ("A", "B", "C") + + @localizer["CodeHelp"]
- +
- Note the text on the Calendar is black, take that into account when picking a shift color as the color will be used as the background + @localizer["ShiftColorNote"]
- +
- When does the shift start for the first day (or only day) + @localizer["StartTimeHelp"]
- +
- When does the shift end for the last day (or only day) + @localizer["EndTimeHelp"]
- +
- - Personnel that are part of a shift but are not assigned to a group (i.e. floaters or roaming personnel) + + @localizer["NonGroupPersonnelHelpEdit"]
@foreach (var group in Model.Groups) @@ -94,15 +94,15 @@
- +
}
- Cancel - + @localizer["CancelButton"] +
@@ -116,4 +116,4 @@ @section Scripts { -} \ No newline at end of file +} diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftGroups.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftGroups.cshtml index 4611d492..2acc1dde 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftGroups.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/EditShiftGroups.cshtml @@ -1,8 +1,8 @@ - -@using Resgrid.Model +@using Resgrid.Model @model Resgrid.Web.Areas.User.Models.Shifts.EditShiftView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Edit Shift Groups"; + ViewBag.Title = "Resgrid | " + localizer["EditShiftGroupsHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @@ -10,16 +10,16 @@
-

Edit Shift Calendar

+

@localizer["EditShiftGroupsHeader"]

@@ -54,9 +54,9 @@ - - - + + + @@ -66,8 +66,8 @@
- Cancel - + @localizer["CancelButton"] +
@@ -86,5 +86,17 @@ $('#editShiftGroupForm').bootstrapValidator('addField', newField); } + } diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/FinishTrade.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/FinishTrade.cshtml index eaec5736..a4c369b3 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/FinishTrade.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/FinishTrade.cshtml @@ -1,7 +1,8 @@ @using Resgrid.Framework @model Resgrid.Web.Areas.User.Models.Shifts.FinishTradeView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Finish Trade Request"; + ViewBag.Title = "Resgrid | " + localizer["FinalizeTradeHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @section Styles @@ -245,19 +246,19 @@
-

Finalize Trade

+

@localizer["FinalizeTradeHeader"]

@@ -280,133 +281,55 @@
-
    -
  • - -
    -

    @Model.Trade.SourceShiftSignup.Shift.Name

    -

    Starts at @Model.Trade.SourceShiftSignup.Shift.StartTime

    -
    -
  • -
-
-
- -
-
-
-
-
Shift GroupShift Roles Add Group to Shift@localizer["ShiftGroupColumn"]@localizer["ShiftRolesColumn"] @localizer["AddGroupToShift"]
- - - - - - - - - - - - @{ var users = from u in Model.Trade.Users - let profile = Model.Profiles.FirstOrDefault(x => x.UserId == u.UserId) - where u.Declined == false && u.Offered == true - select new - { - Name = profile.FullName.AsFirstNameLastName, - TradeUser = u - }; - } - @foreach (var u in users) +
+
- Name - - Shift - - Group - - Date - - Time -
+ + + + + + + + + @if (Model.Trade.Users != null) + { + @foreach (var tradeUser in Model.Trade.Users) { - if (u.TradeUser.Declined == false && u.TradeUser.Offered == true) - { - if (u.TradeUser.Shifts != null && u.TradeUser.Shifts.Any()) - { - foreach (var shift in u.TradeUser.Shifts) + var profile = Model.Profiles?.FirstOrDefault(p => p.UserId == tradeUser.UserId); + var userShift = tradeUser.Shifts?.FirstOrDefault(); + + + + - - - - - - - + @localizer["NoneValue"] } - } - else - { - - - - - - - - - } - } + + + } - -
@localizer["NameColumn"]@localizer["DateColumn"]@localizer["ShiftColumn"]
@(profile != null ? profile.FullName.AsFirstNameLastName : tradeUser.UserId) + @if (userShift?.ShiftSignup != null) + { + @userShift.ShiftSignup.ShiftDay.ToShortDateString() + } + else + { + @localizer["NoneValue"] + } + + @if (userShift?.ShiftSignup != null) + { + @userShift.ShiftSignup.Shift.Name + } + else { -
- - - @u.Name - - @shift.ShiftSignup.Shift.Name - - @shift.ShiftSignup.Group.Name - - @shift.ShiftSignup.ShiftDay.ToShortDateString() - - @shift.ShiftSignup.Shift.StartTime -
- - - @u.Name - - None - - None - - None - - None -
+ +
-
+ } + +
- -
-
- Cancel - - @{ - var shifts = Model.Trade.Users.Select(x => x.Shifts).ToList(); - } - @if (Model.Trade.Users.Any() && shifts.Any()) - { - - } -
-
@@ -416,8 +339,5 @@ @section Scripts { - - -} \ No newline at end of file + +} diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/Index.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/Index.cshtml index b0e79a20..14018b11 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/Index.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/Index.cshtml @@ -1,8 +1,9 @@ @using Resgrid.Model @using Resgrid.Web.Helpers @model Resgrid.Web.Areas.User.Models.Shifts.ShiftsIndexModel +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Shifts"; + ViewBag.Title = "Resgrid | " + localizer["ShiftsHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @@ -29,22 +30,22 @@
-

Shifts

+

@localizer["ShiftsHeader"]

@@ -55,12 +56,12 @@
-
Recurring Group Shifts
+
@localizer["RecurringGroupShifts"]
@if (ClaimsAuthorizationHelper.CanCreateShift()) { }
@@ -70,23 +71,12 @@ - - - - - - + + + + + + @@ -99,33 +89,33 @@ @@ -173,19 +163,18 @@
-
Calendar
+
@localizer["CalendarSectionHeader"]
@if (ClaimsAuthorizationHelper.CanCreateShift()) { }
- @*
*@
diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/NewShift.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/NewShift.cshtml index 999fc7f7..e3ff782f 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/NewShift.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/NewShift.cshtml @@ -1,7 +1,8 @@ @using Resgrid.Model @model Resgrid.Web.Areas.User.Models.Shifts.NewShiftView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | New Shift"; + ViewBag.Title = "Resgrid | " + localizer["NewShiftHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @@ -20,16 +21,16 @@
-

New Shift

+

@localizer["NewShiftHeader"]

@@ -46,11 +47,11 @@ @@ -59,62 +60,62 @@
-

Welcome to the new Shift wizard. This wizard will guide you through creating a new shift for your department. Below specify your shifts name, code and optional shift color. To continue click the "Next" button in the lower right hand corner.

+

@localizer["NewShiftWizardIntro"]

- +
- - For example ("A Shift", "B Shift", "C Shift") + + @localizer["NameHelp"]
- +
- Example ("A", "B", "C") + @localizer["CodeHelp"]
- +
- For assigned you specify the personnel for the shift, for signup the personnel will assign themselves + @localizer["AssignmentTypeHelp"]
- +
- Note the text on the Calendar is black, take that into account when picking a shift color as the color will be used as the background + @localizer["ShiftColorNote"]
-

Below is where you specify which days the shift will on duty and the start time of shift for the first day. If your shift is contiguous the start time will be for the first shift day (i.e. Day 1 of a 48hour block).

+

@localizer["ScheduleTabIntro"]

- +
- When does the shift start for the first day (or only day) + @localizer["StartTimeHelp"]
- +
- When does the shift end for the last day (or only day) + @localizer["EndTimeHelp"]
@@ -127,15 +128,15 @@
-

Here you can configure the required roles for each group in your department for the shift. Click the "Add group to shift" button to add a group to the shift, your shift can have many groups both station and orginizational. After you select the group (witht he left hand drop down) you can click the "Add role to Group" button to add the required roles for the group.

+

@localizer["SlotsTabIntro"]

- Name - - Type - - Schedule - - Groups - - Personnel - - @localizer["NameColumn"]@localizer["TypeColumn"]@localizer["ScheduleColumn"]@localizer["GroupsColumn"]@localizer["PersonnelColumn"]
@if (g.AssignmentType == (int)ShiftAssignmentTypes.Assigned) { - @Html.Raw("Assigned") + @Html.Raw(localizer["AssignedType"].Value) } else { - @Html.Raw("Signup") + @Html.Raw(localizer["SignupType"].Value) } @if (g.ScheduleType == (int)ShiftScheduleTypes.Manual) { - @Html.Raw("Manual") + @Html.Raw(localizer["ManualSchedule"].Value) } else if (g.ScheduleType == (int)ShiftScheduleTypes.Custom) { - @Html.Raw("Custom") + @Html.Raw(localizer["CustomSchedule"].Value) } else if (g.ScheduleType == (int)ShiftScheduleTypes.FortyEightNintySix) { - @Html.Raw("48 on 96 off") + @Html.Raw(localizer["Schedule48_96"].Value) } else if (g.ScheduleType == (int)ShiftScheduleTypes.TwentyFourFortyEight) { - @Html.Raw("24 on 48 off") + @Html.Raw(localizer["Schedule24_48"].Value) } else if (g.ScheduleType == (int)ShiftScheduleTypes.TwentyFourSeventyTwo) { - @Html.Raw("24 on 72 off") + @Html.Raw(localizer["Schedule24_72"].Value) } @@ -149,13 +139,13 @@ } - View Calendar + @localizer["ViewCalendarButton"] @if (ClaimsAuthorizationHelper.IsUserDepartmentAdmin()) { - Edit Details - Edit Calendar - Edit Groups - Delete + @localizer["EditDetailsButton"] + @localizer["EditCalendarButton"] + @localizer["EditGroupsButton"] + @localizer["DeleteButton"] }
- - - + + + @@ -144,25 +145,24 @@
-

Now select the personnel that are working in this shift for your department. These personnel will dynamically fill the group role slot based upon what group they are in if shift group roles were supplied.

+

@localizer["PersonnelTabIntro"]

- +
- - Personnel assigned to the shift but not directly assigned to a station or organizational group (i.e. floaters or stand-bys) + + @localizer["NonGroupPersonnelHelp"]
- @foreach (var group in Model.Groups) {
- +
} @@ -171,7 +171,7 @@
-

Click the finish button below to create your new shift. If you need to add more days, or change any details you can always edit the shift latter from the Shifts list page.

+

@localizer["FinishTabIntro"]

@@ -180,10 +180,10 @@
@@ -237,21 +237,21 @@ Shift_Name: { validators: { notEmpty: { - message: 'Shift Name is required' + message: '@localizer["ShiftNameRequired"]' } } }, Shift_Code: { validators: { notEmpty: { - message: 'Shift Code is required' + message: '@localizer["ShiftCodeRequired"]' } } }, Shift_StartTime: { validators: { notEmpty: { - message: 'Shift start time is required.' + message: '@localizer["ShiftStartTimeRequired"]' } } } @@ -329,5 +329,22 @@ $('#new_shift').bootstrapValidator('addField', newField); } + } diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/ProcessTrade.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/ProcessTrade.cshtml index a8126706..6feaf260 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/ProcessTrade.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/ProcessTrade.cshtml @@ -1,7 +1,8 @@ -@using Resgrid.Framework +@using Resgrid.Framework @model Resgrid.Web.Areas.User.Models.Shifts.ProcessTradeView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Process Shift Trade Request"; + ViewBag.Title = "Resgrid | " + localizer["ProcessTradeHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @section Styles @@ -245,19 +246,19 @@
-

Process Trade Request

+

@localizer["ProcessTradeHeader"]

@@ -290,7 +291,7 @@

@Model.Trade.SourceShiftSignup.Shift.Name

-

Starts at @Model.Trade.SourceShiftSignup.Shift.StartTime

+

@localizer["StartsAtLabel"] @Model.Trade.SourceShiftSignup.Shift.StartTime

@@ -298,24 +299,24 @@
- +
- - Click inside the input to select the shifts you are already on to complete the trade for. If you don't specify any day it's an unbalanced trade. + + @localizer["DatesToTradeHelp"]
-
- -
+ +
+ +
@@ -327,8 +328,5 @@ @section Scripts { - -} \ No newline at end of file +} diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/RequestTrade.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/RequestTrade.cshtml index 562d33fa..260bd74b 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/RequestTrade.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/RequestTrade.cshtml @@ -1,7 +1,8 @@ @using Resgrid.Framework @model Resgrid.Web.Areas.User.Models.Shifts.RequestTradeView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Request Shift Trade"; + ViewBag.Title = "Resgrid | " + localizer["RequestTradeHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @section Styles @@ -244,19 +245,19 @@
-

Request Trade

+

@localizer["RequestTradeHeader"]

@@ -272,24 +273,23 @@
@Html.AntiForgeryToken() - @Html.HiddenFor(m => m.ShiftDay.ShiftDayId) @Html.HiddenFor(m => m.Signup.ShiftSignupId)
- -
+ +
- Click inside the input to select to request trade for (only users to meet the shit role needs are shown) + @localizer["UsersToRequestHelp"]
- Cancel - + @localizer["CancelButton"] +
@@ -301,9 +301,5 @@ @section Scripts { - -} \ No newline at end of file +} diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/ShiftCalendar.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/ShiftCalendar.cshtml index fb51de2a..ab91bf9d 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/ShiftCalendar.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/ShiftCalendar.cshtml @@ -1,8 +1,10 @@ -@using Resgrid.Model +@using Resgrid.Framework +@using Resgrid.Model @using Resgrid.Web.Helpers @model Resgrid.Web.Areas.User.Models.Shifts.ShiftCalendarView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | " + @Model.Shift.Name + " Calendar"; + ViewBag.Title = "Resgrid | " + Model.Shift.Name + " " + localizer["CalendarSuffix"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @@ -29,16 +31,16 @@
-

@Model.Shift.Name Calendar

+

@Model.Shift.Name @localizer["CalendarSuffix"]

diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/ShiftStaffing.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/ShiftStaffing.cshtml index a5e77c3c..1fe283fa 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/ShiftStaffing.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/ShiftStaffing.cshtml @@ -1,7 +1,8 @@ @using Resgrid.Framework @model Resgrid.Web.Areas.User.Models.Shifts.ShiftStaffingView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Shift Staffing"; + ViewBag.Title = "Resgrid | " + localizer["ShiftStaffingHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @section Styles @@ -11,16 +12,16 @@
-

Shift Staffing

+

@localizer["ShiftStaffingHeader"]

@@ -41,29 +42,29 @@
- +
@Html.DropDownListFor(m => m.ShiftId, new SelectList(Model.Shifts, "ShiftId", "Name"), new { @class = "sl2", style="width:30%;" }) - Select the shift to process staffing for. You will only see shifts you have access to (are the Group Admin of, or Department Admin) + @localizer["ShiftSelectHelp"]
- +
- Select the day to process the staffing for. + @localizer["ShiftDayHelp"]
- +
- +
- +
@@ -72,7 +73,7 @@
- +
@@ -82,8 +83,8 @@
- Cancel - + @localizer["CancelButton"] +
@@ -95,12 +96,17 @@ @section Scripts { - @if (Model.IsDepartmentAdmin) { } else @@ -108,6 +114,12 @@ } diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/Signup.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/Signup.cshtml index 89d215bd..5040246e 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/Signup.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/Signup.cshtml @@ -1,9 +1,9 @@ @using Resgrid.Framework @using Resgrid.Model -@using RestSharp.Extensions @model Resgrid.Web.Areas.User.Models.Shifts.ShiftSignupView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Shift Signup"; + ViewBag.Title = "Resgrid | " + localizer["ShiftSignupHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @section Styles @@ -13,16 +13,16 @@
-

Shift Signup

+

@localizer["ShiftSignupHeader"]

@@ -37,7 +37,7 @@
- Shift Start + @localizer["ShiftStart"]

-
Shift Day Detail
+
@localizer["ShiftDayDetail"]
@@ -59,34 +59,34 @@
-
Type:
+
@localizer["TypeLabel"]
@if (Model.Day.Shift.AssignmentType == (int)ShiftAssignmentTypes.Assigned) { -
Assigned
+
@localizer["AssignedType"]
} else { -
Signup
+
@localizer["SignupType"]
} -
Status:
+
@localizer["StatusLabel"]
@if (Model.Day.Day > DateTime.UtcNow) { -
Upcoming
+
@localizer["Upcoming"]
} else { -
Completed
+
@localizer["Completed"]
} -
Start:
+
@localizer["StartLabel"]
@Model.Day.Shift.StartTime
-
End:
+
@localizer["EndLabel"]
@if (!String.IsNullOrWhiteSpace(Model.Day.Shift.EndTime)) {
@Model.Day.Shift.EndTime
} else { -
No End Time
+
@localizer["NoEndTime"]
}
@@ -98,10 +98,9 @@
-
Groups
+
@localizer["GroupsSectionHeader"]
-
@foreach (var group in Model.Day.Shift.Groups) @@ -112,18 +111,10 @@
Shift GroupShift Roles Add Group to Shift@localizer["ShiftGroupColumn"]@localizer["ShiftRolesColumn"] @localizer["AddGroupToShift"]
- - - - + + + + @@ -132,20 +123,13 @@ @foreach (var role in group.Roles) { - - - + + +
- Role - - Required - - Optional - - Needed - @localizer["RoleColumn"]@localizer["RequiredColumn"]@localizer["OptionalColumn"]@localizer["NeededColumn"]
- @role.Role.Name - - @role.Required - - @role.Optional - @role.Role.Name@role.Required@role.Optional @if (Model.Needs != null && Model.Needs.ContainsKey(group.DepartmentGroupId)) { var needsForGroup = Model.Needs[group.DepartmentGroupId]; - if (needsForGroup.ContainsKey(role.PersonnelRoleId)) { @needsForGroup[role.PersonnelRoleId] @@ -157,16 +141,12 @@ }
-

Signups

+

@localizer["SignupsSectionHeader"]

- - + + @@ -176,29 +156,23 @@ var roles = Model.PersonnelRoles[signup.UserId]; - - + + }
- Name - - Roles - @localizer["NameColumn"]@localizer["RolesColumn"]
- @person.FullName.AsFirstNameLastName - - @string.Join(", ", roles.Select(x => x.Name)) - @person.FullName.AsFirstNameLastName@string.Join(", ", roles.Select(x => x.Name)) @if (ClaimsAuthorizationHelper.IsUserDepartmentOrGroupAdmin(group.DepartmentGroupId) || ClaimsAuthorizationHelper.GetUserId() == signup.UserId) { - Delete Shift Signup + @localizer["DeleteShiftSignup"] }
-

Trades

+

@localizer["TradesSectionHeader"]

- + @@ -211,27 +185,21 @@ if (!String.IsNullOrWhiteSpace(signup.Trade.UserId)) { person2 = Model.UserProfiles[signup.Trade.UserId]; - - message = String.Format("{0} tradded with {1}", person.FullName.AsFirstNameLastName, person2.FullName.AsFirstNameLastName); + message = String.Format(localizer["TradedWithFormat"].Value, person.FullName.AsFirstNameLastName, person2.FullName.AsFirstNameLastName); } else if (signup.GetTradeType() == ShiftTradeTypes.Source) { person2 = Model.UserProfiles[signup.Trade.TargetShiftSignup.UserId]; - - message = String.Format("{0} tradded with {1}", person.FullName.AsFirstNameLastName, person2.FullName.AsFirstNameLastName); + message = String.Format(localizer["TradedWithFormat"].Value, person.FullName.AsFirstNameLastName, person2.FullName.AsFirstNameLastName); } else if (signup.GetTradeType() == ShiftTradeTypes.Target) { person2 = Model.UserProfiles[signup.Trade.SourceShiftSignup.UserId]; - - message = String.Format("{0} tradded with {1}", person2.FullName.AsFirstNameLastName, person.FullName.AsFirstNameLastName); + message = String.Format(localizer["TradedWithFormat"].Value, person2.FullName.AsFirstNameLastName, person.FullName.AsFirstNameLastName); } - - + } @@ -241,14 +209,12 @@ { if (!Model.ShiftGroupSignups.ContainsKey(group.DepartmentGroupId) || Model.ShiftGroupSignups[group.DepartmentGroupId] == false) { - Signup for Shift
with @group.DepartmentGroup.Name
+ @localizer["SignupForShiftWith"]
@group.DepartmentGroup.Name
} } } - - diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/SignupSuccess.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/SignupSuccess.cshtml index 08ad1a80..abbc42f4 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/SignupSuccess.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/SignupSuccess.cshtml @@ -1,8 +1,8 @@ @using Resgrid.Framework -@using RestSharp.Extensions @model Resgrid.Web.Areas.User.Models.Shifts.ShiftSignupView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Shift Signup Success"; + ViewBag.Title = "Resgrid | " + localizer["ShiftSignupSuccessHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @@ -242,16 +242,16 @@
-

Shift Signup Success

+

@localizer["ShiftSignupSuccessHeader"]

@@ -263,7 +263,7 @@
- You have successfully signed up for this shift day. If you want to signup for more days of the shift you need to signup for each individual day. + @localizer["SignupSuccessMessage"]  

    @@ -279,11 +279,11 @@ @if (!String.IsNullOrWhiteSpace(Model.Signup.Shift.EndTime)) { -

    Starts at @Model.Signup.Shift.StartTime and Ends at @Model.Signup.Shift.EndTime

    +

    @String.Format(localizer["StartsAtEndsAt"].Value, Model.Signup.Shift.StartTime, Model.Signup.Shift.EndTime)

    } else { -

    Starts at @Model.Signup.Shift.StartTime

    +

    @String.Format(localizer["StartsAt"].Value, Model.Signup.Shift.StartTime)

    }
diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/ViewShift.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/ViewShift.cshtml index 32980af0..ed52ad79 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/ViewShift.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/ViewShift.cshtml @@ -1,9 +1,9 @@ @using Resgrid.Framework @using Resgrid.Model -@using RestSharp.Extensions @model Resgrid.Web.Areas.User.Models.Shifts.ShiftSignupView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | View Shift"; + ViewBag.Title = "Resgrid | " + localizer["ViewShiftHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } @section Styles @@ -11,19 +11,18 @@ } -
-

View Shift

+

@localizer["ViewShiftHeader"]

@@ -38,7 +37,7 @@
- Shift Start + @localizer["ShiftStart"]

-
Shift Day Detail
+
@localizer["ShiftDayDetail"]
@@ -60,39 +59,36 @@
-
Type:
- +
@localizer["TypeLabel"]
@if (Model.Day.Shift.AssignmentType == (int)ShiftAssignmentTypes.Assigned) { -
Assigned
+
@localizer["AssignedType"]
} else { -
Signup
+
@localizer["SignupType"]
} -
Status:
+
@localizer["StatusLabel"]
@if (Model.Day.Day > DateTime.UtcNow) { -
Upcoming
+
@localizer["Upcoming"]
} else { -
Completed
+
@localizer["Completed"]
} -
Start:
+
@localizer["StartLabel"]
@Model.Day.Shift.StartTime
-
End:
+
@localizer["EndLabel"]
@if (!String.IsNullOrWhiteSpace(Model.Day.Shift.EndTime)) {
@Model.Day.Shift.EndTime
} else { -
No End Time
+
@localizer["NoEndTime"]
}
- -
@@ -102,10 +98,9 @@
-
Groups
+
@localizer["GroupsSectionHeader"]
-
@foreach (var group in Model.Day.Shift.Groups) @@ -116,18 +111,10 @@
- Trade - @localizer["TradeColumn"]
- @message - @message
- - - - + + + + @@ -136,20 +123,13 @@ @foreach (var role in group.Roles) { - - - + + +
- Role - - Required - - Optional - - Needed - @localizer["RoleColumn"]@localizer["RequiredColumn"]@localizer["OptionalColumn"]@localizer["NeededColumn"]
- @role.Role.Name - - @role.Required - - @role.Optional - @role.Role.Name@role.Required@role.Optional @if (Model.Needs != null && Model.Needs.ContainsKey(group.DepartmentGroupId)) { var needsForGroup = Model.Needs[group.DepartmentGroupId]; - if (needsForGroup.ContainsKey(role.PersonnelRoleId)) { @needsForGroup[role.PersonnelRoleId] @@ -161,16 +141,12 @@ }
-

Signups

+

@localizer["SignupsSectionHeader"]

- - + + @@ -178,25 +154,18 @@ { var person = Model.UserProfiles[signup.UserId]; var roles = Model.PersonnelRoles[signup.UserId]; - - - + + }
- Name - - Roles - @localizer["NameColumn"]@localizer["RolesColumn"]
- @person.FullName.AsFirstNameLastName - - @string.Join(", ", roles.Select(x => x.Name)) - @person.FullName.AsFirstNameLastName@string.Join(", ", roles.Select(x => x.Name))
-

Trades

+

@localizer["TradesSectionHeader"]

- + @@ -209,27 +178,21 @@ if (!String.IsNullOrWhiteSpace(signup.Trade.UserId)) { person2 = Model.UserProfiles[signup.Trade.UserId]; - - message = String.Format("{0} tradded with {1}", person.FullName.AsFirstNameLastName, person2.FullName.AsFirstNameLastName); + message = String.Format(localizer["TradedWithFormat"].Value, person.FullName.AsFirstNameLastName, person2.FullName.AsFirstNameLastName); } else if (signup.GetTradeType() == ShiftTradeTypes.Source) { person2 = Model.UserProfiles[signup.Trade.TargetShiftSignup.UserId]; - - message = String.Format("{0} tradded with {1}", person.FullName.AsFirstNameLastName, person2.FullName.AsFirstNameLastName); + message = String.Format(localizer["TradedWithFormat"].Value, person.FullName.AsFirstNameLastName, person2.FullName.AsFirstNameLastName); } else if (signup.GetTradeType() == ShiftTradeTypes.Target) { person2 = Model.UserProfiles[signup.Trade.SourceShiftSignup.UserId]; - - message = String.Format("{0} tradded with {1}", person2.FullName.AsFirstNameLastName, person.FullName.AsFirstNameLastName); + message = String.Format(localizer["TradedWithFormat"].Value, person2.FullName.AsFirstNameLastName, person.FullName.AsFirstNameLastName); } - - + } @@ -237,9 +200,7 @@ } - - diff --git a/Web/Resgrid.Web/Areas/User/Views/Shifts/YourShifts.cshtml b/Web/Resgrid.Web/Areas/User/Views/Shifts/YourShifts.cshtml index 1bf248f1..39e858b5 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Shifts/YourShifts.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Shifts/YourShifts.cshtml @@ -2,24 +2,24 @@ @using Resgrid.Model.Helpers @using Resgrid.Web.Helpers @model Resgrid.Web.Areas.User.Models.Shifts.YourShiftsView +@inject IStringLocalizer localizer @{ - ViewBag.Title = "Resgrid | Your Shifts"; + ViewBag.Title = "Resgrid | " + localizer["YourShiftsHeader"]; Layout = "~/Areas/User/Views/Shared/_UserLayout.cshtml"; } -
-

Your Shifts

+

@localizer["YourShiftsHeader"]

@@ -30,31 +30,19 @@
-
Your Shifts
+
@localizer["YourShiftsHeader"]
- Trade - @localizer["TradeColumn"]
- @message - @message
- - - - - - + + + + + + @@ -62,54 +50,46 @@ @foreach (var s in Model.Signups) { - - - + + + - + @@ -128,25 +108,17 @@
-
Your Pending Trades
+
@localizer["YourPendingTrades"]
- Shift - - Group - - Day - - Approved - - Status - - Timestamp - @localizer["ShiftColumn"]@localizer["GroupColumn"]@localizer["DayColumn"]@localizer["ApprovedColumn"]@localizer["StatusColumn"]@localizer["TimestampColumn"]
- @s.Shift.Name - - @s.Group.Name - - @s.ShiftDay.ToShortDateString() - @s.Shift.Name@s.Group.Name@s.ShiftDay.ToShortDateString() @if (s.Denied) { - No + @localizer["ApprovedNo"] } else { - Yes + @localizer["ApprovedYes"] } @if (s.Trade != null && s.Trade.IsTradeComplete()) { - Trade Complete + @localizer["TradeComplete"] } else if (s.Trade != null && !s.Trade.IsTradeComplete()) { - Trade In Progress + @localizer["TradeInProgress"] } else { - Normal + @localizer["Normal"] } - @s.SignupTimestamp.TimeConverterToString(Model.Department) - @s.SignupTimestamp.TimeConverterToString(Model.Department) @if (s.ShiftDay > DateTime.UtcNow.TimeConverter(Model.Department) && s.Trade == null) { - Decline Shift Day + @localizer["DeclineShiftDay"] } @if (s.ShiftDay > DateTime.UtcNow.TimeConverter(Model.Department) && s.Trade == null) { - Request Trade + @localizer["RequestTrade"] } @if (s.Trade != null && !s.Trade.IsTradeComplete()) { - Finish Trade + @localizer["FinishTrade"] }
- - - - + + + + @@ -154,38 +126,30 @@ @foreach (var t in Model.Trades) { - - - - + + + + @@ -202,4 +166,4 @@ @section Scripts { -} \ No newline at end of file +} diff --git a/Web/Resgrid.Web/Areas/User/Views/Units/ViewEvents.cshtml b/Web/Resgrid.Web/Areas/User/Views/Units/ViewEvents.cshtml index f8d9497d..8ed5873a 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Units/ViewEvents.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Units/ViewEvents.cshtml @@ -41,7 +41,7 @@
-
+
- Shift - - Group - - Day - - Time - @localizer["ShiftColumn"]@localizer["GroupColumn"]@localizer["DayColumn"]@localizer["TimeColumn"]
- @t.SourceShiftSignup.Shift.Name - - @t.SourceShiftSignup.Group.Name - - @t.SourceShiftSignup.ShiftDay.ToShortDateString() - - @t.SourceShiftSignup.Shift.StartTime - @t.SourceShiftSignup.Shift.Name@t.SourceShiftSignup.Group.Name@t.SourceShiftSignup.ShiftDay.ToShortDateString()@t.SourceShiftSignup.Shift.StartTime @if (t.GetState(ClaimsAuthorizationHelper.GetUserId()) == ShiftSignupTradeStates.Open) { - Process Trade Request + @localizer["ProcessTradeRequest"] } else if (t.GetState(ClaimsAuthorizationHelper.GetUserId()) == ShiftSignupTradeStates.Declined) { - Declined + @localizer["Declined"] } else if (t.GetState(ClaimsAuthorizationHelper.GetUserId()) == ShiftSignupTradeStates.Accepted) { - Accepted + @localizer["Accepted"] } else if (t.GetState(ClaimsAuthorizationHelper.GetUserId()) == ShiftSignupTradeStates.Filled) { - Filled + @localizer["Filled"] } else if (t.GetState(ClaimsAuthorizationHelper.GetUserId()) == ShiftSignupTradeStates.Proposed) { - Trade Offered + @localizer["TradeOffered"] }
diff --git a/Web/Resgrid.Web/Areas/User/Views/Units/_SmallUnitsGridPartial.cshtml b/Web/Resgrid.Web/Areas/User/Views/Units/_SmallUnitsGridPartial.cshtml index c5f923f5..00648064 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Units/_SmallUnitsGridPartial.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Units/_SmallUnitsGridPartial.cshtml @@ -1,6 +1,6 @@ @inject IStringLocalizer localizer -
+
diff --git a/Web/Resgrid.Web/Areas/User/Views/Workshifts/New.cshtml b/Web/Resgrid.Web/Areas/User/Views/Workshifts/New.cshtml index 06ee41e8..88fe52e9 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Workshifts/New.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Workshifts/New.cshtml @@ -102,7 +102,7 @@
- +
diff --git a/Web/Resgrid.Web/Helpers/ClaimsAuthorizationHelper.cs b/Web/Resgrid.Web/Helpers/ClaimsAuthorizationHelper.cs index 86095eb6..4bcd76b9 100644 --- a/Web/Resgrid.Web/Helpers/ClaimsAuthorizationHelper.cs +++ b/Web/Resgrid.Web/Helpers/ClaimsAuthorizationHelper.cs @@ -159,6 +159,11 @@ public static bool CanCreateLog() return GetClaimsPrincipal().HasClaim(ResgridClaimTypes.Resources.Log, ResgridClaimTypes.Actions.Create); } + public static bool CanDeleteLog() + { + return GetClaimsPrincipal().HasClaim(ResgridClaimTypes.Resources.Log, ResgridClaimTypes.Actions.Delete); + } + public static bool CanCreateShift() { return GetClaimsPrincipal().HasClaim(ResgridClaimTypes.Resources.Shift, ResgridClaimTypes.Actions.Create); diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/department/resgrid.department.callsettings.js b/Web/Resgrid.Web/wwwroot/js/app/internal/department/resgrid.department.callsettings.js index 02fbd83a..c4bc19ad 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/department/resgrid.department.callsettings.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/department/resgrid.department.callsettings.js @@ -5,14 +5,20 @@ var resgrid; var callsettings; (function (callsettings) { $(document).ready(function () { - // Load call email types and render as a selectable list + // Load call email types and render as a selectable list with preview images $.getJSON(resgrid.absoluteBaseUrl + '/User/Department/GetCallEmailTypes', function (data) { - var $list = $("#listView").empty(); + var $list = $("#listView").empty().addClass('call-email-type-list'); $.each(data, function (i, item) { var checked = item.Id == $("#CallType").val() ? 'checked' : ''; + var imgSrc = resgrid.absoluteBaseUrl + '/images/CallEmails/' + item.Code + '.png'; $list.append( - '
' + - '' + + '' ); }); diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/department/resgrid.department.textsettings.js b/Web/Resgrid.Web/wwwroot/js/app/internal/department/resgrid.department.textsettings.js index 1854a567..15542aef 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/department/resgrid.department.textsettings.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/department/resgrid.department.textsettings.js @@ -6,14 +6,20 @@ var resgrid; var textsettings; (function (textsettings) { $(document).ready(function () { - // Load call text types and render as a selectable list + // Load call text types and render as a selectable list with preview images $.getJSON(resgrid.absoluteBaseUrl + '/User/Department/GetCallTextTypes', function (data) { - var $list = $("#textTypesListView").empty(); + var $list = $("#textTypesListView").empty().addClass('call-text-type-list'); $.each(data, function (i, item) { var checked = item.Id == $("#TextCallType").val() ? 'checked' : ''; + var imgSrc = resgrid.absoluteBaseUrl + '/images/CallTexts/' + item.Code + '.png'; $list.append( - '
' + - '' + + '
' + + '' + '
' ); }); diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.addArchivedCall.js b/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.addArchivedCall.js index 4f9039c2..b6995bca 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.addArchivedCall.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.addArchivedCall.js @@ -1,4 +1,3 @@ - var resgrid; (function (resgrid) { var dispatch; @@ -6,29 +5,46 @@ var resgrid; var addArchivedCall; (function (addArchivedCall) { var personnelTable, unitsTable; + addArchivedCall.protocolCount = 0; + addArchivedCall.protocolData = {}; $(document).ready(function () { callMarker = null; map = null; - let quill = new Quill('#editor-container', { + let quillNature = new Quill('#nature-container', { placeholder: '', theme: 'snow' }); - let quill2 = new Quill('#editor-container2', { + let quillNotes = new Quill('#note-container', { placeholder: '', theme: 'snow' }); $(document).on('submit', '#addArchivedCallForm', function () { - $('#Call_NatureOfCall').val(quill.root.innerHTML); - $('#Call_Notes').val(quill2.root.innerHTML); + $('#Call_NatureOfCall').val(quillNature.root.innerHTML); + $('#Call_Notes').val(quillNotes.root.innerHTML); return true; }); + if (newCallFormData) { + let newCallForm = $('#fb-template').formRender({ + dataType: 'json', + formData: newCallFormData + }); + + $("#saveNewCallFrom").click(function (evt) { + var data = JSON.stringify(newCallForm.userData); + $("#Call_CallFormData").val(data); + }); + } $('#Call_LoggedOn').datetimepicker({ step: 5 }); + + $('#PrimaryContact').select2(); + $('#AdditionalContacts').select2(); + $("#Call_Address").bind("keypress", function (event) { if (event.keyCode == 13) { $("#searchButton").click(); @@ -42,6 +58,14 @@ var resgrid; } }); + $("#CallPriority").change(function () { + checkForProtocols(); + }); + + $("#Call_Type").change(function () { + checkForProtocols(); + }); + const tiles1 = L.tileLayer( osmTileUrl, { @@ -59,7 +83,6 @@ var resgrid; $("#Latitude").val(e.latlng.lat.toString()); $("#Longitude").val(e.latlng.lng.toString()); - //$("#What3Word").val(''); map.panTo(e.latlng); @@ -134,6 +157,75 @@ var resgrid; }); evt.preventDefault(); }); + + $('#protocolQuestionWindow').on('show.bs.modal', function (event) { + var protocolId = $(event.relatedTarget).data('protocolid'); + + var protocol = null; + for (var i = 0; i < resgrid.dispatch.addArchivedCall.protocolData.length; i++) { + if (resgrid.dispatch.addArchivedCall.protocolData[i].Id === protocolId) { + protocol = resgrid.dispatch.addArchivedCall.protocolData[i]; + break; + } + } + + var modal = $(this); + modal.find('.modal-title').text(`Questions for ${protocol.Name}`); + + var questionHtml = ""; + for (var t = 0; t < protocol.Questions.length; t++) { + var question = protocol.Questions[t]; + questionHtml = questionHtml + `
'; + } + modal.find('.modal-body').empty(); + modal.find('.modal-body').append(questionHtml); + + $('#processQuestionAnswers').removeAttr("data-protocolid"); + $('#processQuestionAnswers').attr('data-protocolid', protocol.Id); + }); + + $('#processQuestionAnswers').click(function () { + var buttonProtocolId = $('#processQuestionAnswers').attr('data-protocolid'); + $('#protocolQuestionWindow').modal('hide'); + + var protocol = null; + for (var i = 0; i < resgrid.dispatch.addArchivedCall.protocolData.length; i++) { + if (resgrid.dispatch.addArchivedCall.protocolData[i].Id === Number(buttonProtocolId)) { + protocol = resgrid.dispatch.addArchivedCall.protocolData[i]; + break; + } + } + + var totalAnswerWeight = 0; + for (var t = 0; t < protocol.Questions.length; t++) { + var question = protocol.Questions[t]; + var answerWeight = $(`#questionAnswer_${question.Id}`).val(); + if (answerWeight) { + totalAnswerWeight = totalAnswerWeight + Number(answerWeight); + } + } + + $(`#answerProcotolQuestions_${protocol.Id}`).removeClass("btn-warning btn-success btn-inverse"); + + if (totalAnswerWeight >= protocol.MinimumWeight) { + $(`#pendingProtocol_${protocol.Id}`).val('1'); + $(`#answerProcotolQuestions_${protocol.Id}`).addClass("btn-success"); + } else { + $(`#answerProcotolQuestions_${protocol.Id}`).addClass("btn-inverse"); + } + }); + $('#addNewLinkedCall').click(function () { var data = $('#selectLinkedCall').select2('data'); @@ -141,6 +233,7 @@ var resgrid; $('#selectCallNote').val(''); $('#selectLinkedCall').empty(); }); + personnelTable = $("#personnelGrid").DataTable({ ajax: { url: resgrid.absoluteBaseUrl + '/User/Personnel/GetPersonnelForCallGrid?callLat=' + $("#Latitude").val() + '&callLong=' + $("#Longitude").val(), dataSrc: '' }, paging: false, @@ -206,25 +299,30 @@ var resgrid; $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { if (e.target && e.target.textContent === "Personnel") { personnelTable.columns.adjust(); } else if (e.target && e.target.textContent === "Groups") { groupsTable.columns.adjust(); } - else if (e.target && e.target.textContent === "Units") { unitsTable.columns.adjust(); } else if (e.target && e.target.textContent === "Roles") { rolesTable.columns.adjust(); } }); + + checkForProtocols(); centerMap(); }); + function centerMap() { if (centerLat && centerLng) { map.panTo(new L.LatLng(centerLat, centerLng)); } } addArchivedCall.centerMap = centerMap; + function foundLocation(position) { map.panTo(new L.LatLng(position.coords.latitude, position.coords.longitude)); } addArchivedCall.foundLocation = foundLocation; + function noLocation() { map.panTo(new L.LatLng(-34.397, 150.644)); } addArchivedCall.noLocation = noLocation; + function setMarkerLocation(lat, lng) { if (callMarker) { callMarker.setLatLng(new L.LatLng(lat, lng)); @@ -238,13 +336,13 @@ var resgrid; $("#Latitude").val(position.lat); $("#Longitude").val(position.lng); - //$("#What3Word").val(''); resgrid.dispatch.addArchivedCall.geocodeCoordinates(position.lat, position.lng); }); } } addArchivedCall.setMarkerLocation = setMarkerLocation; + function geocodeCoordinates(lat, lng) { if (google && google.maps) { let geocoder = new google.maps.Geocoder(); @@ -264,6 +362,7 @@ var resgrid; } } addArchivedCall.geocodeCoordinates = geocodeCoordinates; + function findLocation(pos) { var geocoder = new google.maps.Geocoder(); geocoder.geocode({ @@ -280,11 +379,94 @@ var resgrid; $("#Longitude").val(pos.lng().toString()); } addArchivedCall.findLocation = findLocation; + function refreshPersonnelGrid() { personnelTable.ajax.url(resgrid.absoluteBaseUrl + '/User/Personnel/GetPersonnelForCallGrid?callLat=' + $("#Latitude").val() + '&callLong=' + $("#Longitude").val()).load(); unitsTable.ajax.url(resgrid.absoluteBaseUrl + '/User/Units/GetUnitsForCallGrid?callLat=' + $("#Latitude").val() + '&callLong=' + $("#Longitude").val()).load(); } addArchivedCall.refreshPersonnelGrid = refreshPersonnelGrid; + + function fillCallTemplate() { + var templateId = $('#CallTemplateId').val(); + + if (templateId && templateId > 0) { + $.ajax({ + url: resgrid.absoluteBaseUrl + '/User/Templates/GetTemplate?id=' + templateId, + contentType: 'application/json', + type: 'GET' + }).done(function (data) { + if (data) { + if (data.CallName && data.CallName.length > 0) { + $('#Call_Name').val(data.CallName); + } + + if (data.CallNature && data.CallNature.length > 0) { + $('#Call_NatureOfCall').val(data.CallNature); + } + + if (data.CallType && data.CallType.length > 0) { + $('#Call_Type').val(data.CallType); + } + + if (data.CallPriority && data.CallPriority >= 0) { + $('#CallPriority').val(data.CallPriority); + } + } + }); + } + } + addArchivedCall.fillCallTemplate = fillCallTemplate; + + function checkForProtocols() { + var callPriorityVal = $('#CallPriority').val(); + var callTypeVal = $('#Call_Type').val(); + + $("#protocols tr").remove(); + + $.ajax({ + url: resgrid.absoluteBaseUrl + `/User/Protocols/GetProtocolsForPrioType?priority=${callPriorityVal}&type=${callTypeVal}`, + contentType: 'application/json', + type: 'GET' + }).done(function (data) { + if (data) { + resgrid.dispatch.addArchivedCall.protocolCount = 0; + + resgrid.dispatch.addArchivedCall.protocolData = data; + for (var i = 0; i < data.length; i++) { + var pendingProtocol = data[i]; + + if (pendingProtocol.State === 1 || pendingProtocol.State === 2) { + resgrid.dispatch.addArchivedCall.addProtocol(pendingProtocol.Id, pendingProtocol.Name, pendingProtocol.Code, pendingProtocol.State); + } + } + } + }); + } + addArchivedCall.checkForProtocols = checkForProtocols; + + function addProtocol(id, name, code, state) { + resgrid.dispatch.addArchivedCall.protocolCount++; + $('#protocols tbody').first().append(` + ${code} + ${name} + ${resgrid.dispatch.addArchivedCall.getStatusField(id, state, code)} + `); + } + addArchivedCall.addProtocol = addProtocol; + + function getStatusField(id, state, code) { + if (state === 0) { + return "Inactive"; + } else if (state === 1) { + return `Active `; + } else if (state === 2) { + return `Answer Questions `; + } else { + return "Unknown"; + } + } + addArchivedCall.getStatusField = getStatusField; + })(addArchivedCall = dispatch.addArchivedCall || (dispatch.addArchivedCall = {})); })(dispatch = resgrid.dispatch || (resgrid.dispatch = {})); })(resgrid || (resgrid = {})); diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.dashboard.js b/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.dashboard.js index 41a9212a..d3c2f994 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.dashboard.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.dashboard.js @@ -12,20 +12,33 @@ var resgrid; activeCallsTable = $("#activeCallsList").DataTable({ ajax: { url: resgrid.absoluteBaseUrl + '/User/Dispatch/GetActiveCallsList', dataSrc: '' }, pageLength: 50, + order: [[2, 'desc']], columns: [ { data: 'Number', title: 'Number' }, { data: 'Name', title: 'Name' }, - { data: 'Timestamp', title: 'Timestamp' }, { - data: null, title: 'Priority', orderable: false, + data: 'Priority', title: 'Priority', render: function (data, type, row) { return '' + row.Priority + ''; } }, + { + data: 'Timestamp', title: 'Timestamp', defaultContent: '', + render: function (data, type, row) { + if (type === 'sort' || type === 'type') { return row.LoggedOn || 0; } + return data || ''; + } + }, { data: 'CallId', title: 'Actions', orderable: false, render: function (data, type, row) { - var html = 'View '; + var html = 'View '; + if (row.CanUpdateCall) { + html += 'Update '; + } + if (row.CanCloseCall) { + html += 'Close '; + } if (row.CanDeleteCall) { html += 'Delete'; } diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.editcall.js b/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.editcall.js index 3a9f8a21..c8a21668 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.editcall.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/dispatch/resgrid.dispatch.editcall.js @@ -1,4 +1,3 @@ - var resgrid; (function (resgrid) { var dispatch; @@ -6,15 +5,46 @@ var resgrid; var editcall; (function (editcall) { var personnelTable, groupsTable, unitsTable, rolesTable; + var initialDrawCount = 0; + var totalTables = 4; + editcall.protocolCount = 0; + editcall.protocolData = {}; $(document).ready(function () { callMarker = null; map = null; - let quillNote2 = new Quill('#nature-container', { + let quillNature = new Quill('#nature-container', { placeholder: '', theme: 'snow' }); + let quillNotes = new Quill('#note-container', { + placeholder: '', + theme: 'snow' + }); + + $(document).on('submit', '#updateCallForm', function () { + $('#Call_Notes').val(quillNotes.root.innerHTML); + $('#Call_NatureOfCall').val(quillNature.root.innerHTML); + + return true; + }); + + if (newCallFormData) { + let newCallForm = $('#fb-template').formRender({ + dataType: 'json', + formData: newCallFormData + }); + + $("#saveNewCallFrom").click(function (evt) { + var data = JSON.stringify(newCallForm.userData); + $("#Call_CallFormData").val(data); + }); + } + + $('#PrimaryContact').select2(); + $('#AdditionalContacts').select2(); + $("#Call_Address").bind("keypress", function (event) { if (event.keyCode == 13) { $("#searchButton").click(); @@ -28,19 +58,12 @@ var resgrid; } }); - $('#PrimaryContact').select2(); - $('#AdditionalContacts').select2(); - - let quillNote = new Quill('#note-container', { - placeholder: '', - theme: 'snow' + $("#CallPriority").change(function () { + checkForProtocols(); }); - $(document).on('submit', '#updateCallForm', function () { - $('#Call_Notes').val(quillNote.root.innerHTML); - $('#Call_NatureOfCall').val(quillNote2.root.innerHTML); - - return true; + $("#Call_Type").change(function () { + checkForProtocols(); }); $("#selectLinkedCall").select2({ @@ -56,6 +79,7 @@ var resgrid; }, } }); + $.ajax({ url: resgrid.absoluteBaseUrl + '/User/Dispatch/GetMapDataForCall?callId=' + callId, contentType: 'application/json; charset=utf-8', @@ -80,7 +104,6 @@ var resgrid; $("#Latitude").val(e.latlng.lat.toString()); $("#Longitude").val(e.latlng.lng.toString()); - //$("#What3Word").val(''); map.panTo(e.latlng); resgrid.dispatch.editcall.geocodeCoordinates(e.latlng.lat, e.latlng.lng); @@ -89,6 +112,7 @@ var resgrid; resgrid.dispatch.editcall.setMarkerLocation(data.centerLat, data.centerLon); } }); + $("#searchButton").click(function (evt) { var where = jQuery.trim($("#Call_Address").val()); if (where.length < 1) @@ -116,6 +140,7 @@ var resgrid; } evt.preventDefault(); }); + $("#findw3wButton").click(function (evt) { var word = jQuery.trim($("#What3Word").val()); if (word.length < 1) @@ -130,18 +155,86 @@ var resgrid; $("#Latitude").val(data.Latitude); $("#Longitude").val(data.Longitude); - //$("#What3Word").val(''); resgrid.dispatch.editcall.geocodeCoordinates(data.Latitude, data.Longitude); resgrid.dispatch.editcall.setMarkerLocation(data.Latitude, data.Longitude); } else { - alert("What3Words was unable to find a location for those workds. Ensure its 3 words seperated by periods."); + alert("What3Words was unable to find a location for those words. Ensure its 3 words separated by periods."); } }); evt.preventDefault(); }); + + $('#protocolQuestionWindow').on('show.bs.modal', function (event) { + var protocolId = $(event.relatedTarget).data('protocolid'); + + var protocol = null; + for (var i = 0; i < resgrid.dispatch.editcall.protocolData.length; i++) { + if (resgrid.dispatch.editcall.protocolData[i].Id === protocolId) { + protocol = resgrid.dispatch.editcall.protocolData[i]; + break; + } + } + + var modal = $(this); + modal.find('.modal-title').text(`Questions for ${protocol.Name}`); + + var questionHtml = ""; + for (var t = 0; t < protocol.Questions.length; t++) { + var question = protocol.Questions[t]; + questionHtml = questionHtml + `
'; + } + modal.find('.modal-body').empty(); + modal.find('.modal-body').append(questionHtml); + + $('#processQuestionAnswers').removeAttr("data-protocolid"); + $('#processQuestionAnswers').attr('data-protocolid', protocol.Id); + }); + + $('#processQuestionAnswers').click(function () { + var buttonProtocolId = $('#processQuestionAnswers').attr('data-protocolid'); + $('#protocolQuestionWindow').modal('hide'); + + var protocol = null; + for (var i = 0; i < resgrid.dispatch.editcall.protocolData.length; i++) { + if (resgrid.dispatch.editcall.protocolData[i].Id === Number(buttonProtocolId)) { + protocol = resgrid.dispatch.editcall.protocolData[i]; + break; + } + } + + var totalAnswerWeight = 0; + for (var t = 0; t < protocol.Questions.length; t++) { + var question = protocol.Questions[t]; + var answerWeight = $(`#questionAnswer_${question.Id}`).val(); + if (answerWeight) { + totalAnswerWeight = totalAnswerWeight + Number(answerWeight); + } + } + + $(`#answerProcotolQuestions_${protocol.Id}`).removeClass("btn-warning btn-success btn-inverse"); + + if (totalAnswerWeight >= protocol.MinimumWeight) { + $(`#pendingProtocol_${protocol.Id}`).val('1'); + $(`#answerProcotolQuestions_${protocol.Id}`).addClass("btn-success"); + } else { + $(`#answerProcotolQuestions_${protocol.Id}`).addClass("btn-inverse"); + } + }); + $('#addNewLinkedCall').click(function () { var data = $('#selectLinkedCall').select2('data'); @@ -149,6 +242,7 @@ var resgrid; $('#selectCallNote').val(''); $('#selectLinkedCall').empty(); }); + personnelTable = $("#personnelGrid").DataTable({ ajax: { url: resgrid.absoluteBaseUrl + '/User/Personnel/GetPersonnelForCallGrid?callLat=' + encodeURI($("#Latitude").val()) + '&callLong=' + encodeURI($("#Longitude").val()), dataSrc: '' }, paging: false, @@ -164,7 +258,8 @@ var resgrid; }); personnelTable.on('draw', function() { $('#personnelGrid thead th:first').html(''); - resgrid.dispatch.editcall.updateDispatchedEntities(); + initialDrawCount++; + if (initialDrawCount >= totalTables) { resgrid.dispatch.editcall.updateDispatchedEntities(); } }); groupsTable = $("#groupsGrid").DataTable({ @@ -178,7 +273,8 @@ var resgrid; }); groupsTable.on('draw', function() { $('#groupsGrid thead th:first').html(''); - resgrid.dispatch.editcall.updateDispatchedEntities(); + initialDrawCount++; + if (initialDrawCount >= totalTables) { resgrid.dispatch.editcall.updateDispatchedEntities(); } }); unitsTable = $("#unitsGrid").DataTable({ @@ -194,7 +290,8 @@ var resgrid; }); unitsTable.on('draw', function() { $('#unitsGrid thead th:first').html(''); - resgrid.dispatch.editcall.updateDispatchedEntities(); + initialDrawCount++; + if (initialDrawCount >= totalTables) { resgrid.dispatch.editcall.updateDispatchedEntities(); } }); rolesTable = $("#rolesGrid").DataTable({ @@ -208,7 +305,8 @@ var resgrid; }); rolesTable.on('draw', function() { $('#rolesGrid thead th:first').html(''); - resgrid.dispatch.editcall.updateDispatchedEntities(); + initialDrawCount++; + if (initialDrawCount >= totalTables) { resgrid.dispatch.editcall.updateDispatchedEntities(); } }); $('#checkAllPersonnel').on('click', function () { $('#personnelGrid').find(':checkbox').prop('checked', this.checked); }); @@ -218,10 +316,12 @@ var resgrid; $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { if (e.target && e.target.textContent === "Personnel") { personnelTable.columns.adjust(); } else if (e.target && e.target.textContent === "Groups") { groupsTable.columns.adjust(); } - else if (e.target && e.target.textContent === "Units") { unitsTable.columns.adjust(); } else if (e.target && e.target.textContent === "Roles") { rolesTable.columns.adjust(); } }); + + checkForProtocols(); }); + function findLocation(pos) { if (google && google.maps) { var geocoder = new google.maps.Geocoder(); @@ -243,6 +343,7 @@ var resgrid; } } editcall.findLocation = findLocation; + function setMarkerLocation(lat, lng) { if (callMarker) { callMarker.setLatLng(new L.LatLng(lat, lng)); @@ -262,6 +363,7 @@ var resgrid; } } editcall.setMarkerLocation = setMarkerLocation; + function geocodeCoordinates(lat, lng) { if (google && google.maps) { let geocoder = new google.maps.Geocoder(); @@ -281,11 +383,13 @@ var resgrid; } } editcall.geocodeCoordinates = geocodeCoordinates; + function refreshPersonnelGrid() { personnelTable.ajax.url(resgrid.absoluteBaseUrl + '/User/Personnel/GetPersonnelForCallGrid?callLat=' + encodeURI($("#Latitude").val()) + '&callLong=' + encodeURI($("#Longitude").val())).load(); unitsTable.ajax.url(resgrid.absoluteBaseUrl + '/User/Units/GetUnitsForCallGrid?callLat=' + encodeURI($("#Latitude").val()) + '&callLong=' + encodeURI($("#Longitude").val())).load(); } editcall.refreshPersonnelGrid = refreshPersonnelGrid; + function updateDispatchedEntities() { $.ajax({ url: resgrid.absoluteBaseUrl + '/User/Dispatch/GetAllDispatchesForCall?callId=' + callId, @@ -298,6 +402,88 @@ var resgrid; }); } editcall.updateDispatchedEntities = updateDispatchedEntities; + + function fillCallTemplate() { + var templateId = $('#CallTemplateId').val(); + + if (templateId && templateId > 0) { + $.ajax({ + url: resgrid.absoluteBaseUrl + '/User/Templates/GetTemplate?id=' + templateId, + contentType: 'application/json', + type: 'GET' + }).done(function (data) { + if (data) { + if (data.CallName && data.CallName.length > 0) { + $('#Call_Name').val(data.CallName); + } + + if (data.CallNature && data.CallNature.length > 0) { + $('#Call_NatureOfCall').val(data.CallNature); + } + + if (data.CallType && data.CallType.length > 0) { + $('#Call_Type').val(data.CallType); + } + + if (data.CallPriority && data.CallPriority >= 0) { + $('#CallPriority').val(data.CallPriority); + } + } + }); + } + } + editcall.fillCallTemplate = fillCallTemplate; + + function checkForProtocols() { + var callPriorityVal = $('#CallPriority').val(); + var callTypeVal = $('#Call_Type').val(); + + $("#protocols tr").remove(); + + $.ajax({ + url: resgrid.absoluteBaseUrl + `/User/Protocols/GetProtocolsForPrioType?priority=${callPriorityVal}&type=${callTypeVal}`, + contentType: 'application/json', + type: 'GET' + }).done(function (data) { + if (data) { + resgrid.dispatch.editcall.protocolCount = 0; + + resgrid.dispatch.editcall.protocolData = data; + for (var i = 0; i < data.length; i++) { + var pendingProtocol = data[i]; + + if (pendingProtocol.State === 1 || pendingProtocol.State === 2) { + resgrid.dispatch.editcall.addProtocol(pendingProtocol.Id, pendingProtocol.Name, pendingProtocol.Code, pendingProtocol.State); + } + } + } + }); + } + editcall.checkForProtocols = checkForProtocols; + + function addProtocol(id, name, code, state) { + resgrid.dispatch.editcall.protocolCount++; + $('#protocols tbody').first().append(` + ${code} + ${name} + ${resgrid.dispatch.editcall.getStatusField(id, state, code)} + `); + } + editcall.addProtocol = addProtocol; + + function getStatusField(id, state, code) { + if (state === 0) { + return "Inactive"; + } else if (state === 1) { + return `Active `; + } else if (state === 2) { + return `Answer Questions `; + } else { + return "Unknown"; + } + } + editcall.getStatusField = getStatusField; + })(editcall = dispatch.editcall || (dispatch.editcall = {})); })(dispatch = resgrid.dispatch || (resgrid.dispatch = {})); })(resgrid || (resgrid = {})); diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/groups/resgrid.groups.editgroup.js b/Web/Resgrid.Web/wwwroot/js/app/internal/groups/resgrid.groups.editgroup.js index fb4d212d..4a3632d7 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/groups/resgrid.groups.editgroup.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/groups/resgrid.groups.editgroup.js @@ -7,7 +7,23 @@ var resgrid; (function (editgroup) { $(document).ready(function () { var groupUrl = resgrid.absoluteBaseUrl + '/User/Department/GetRecipientsForGrid?filter=3&filterNotInGroup=true&ignoreGroupId=' + $('#EditGroup_DepartmentGroupId').val(); - function initGroupSelect2(selector) { + + function showDuplicateError(userName) { + var alertId = 'groupDuplicateAlert'; + $('#' + alertId).remove(); + var alertHtml = ''; + $('.ibox-content form').prepend(alertHtml); + $('html, body').animate({ scrollTop: 0 }, 'fast'); + } + + function getSelectedIds(selector) { + return $(selector).val() || []; + } + + function initGroupSelect2(selector, otherSelector) { $(selector).select2({ placeholder: "Select users...", allowClear: true, @@ -19,10 +35,20 @@ var resgrid; return { results: $.map(data, function (u) { return { id: u.Id, text: u.Name }; }) }; } } + }).on('select2:select', function (e) { + var selectedId = e.params.data.id; + var selectedName = e.params.data.text; + var otherIds = getSelectedIds(otherSelector); + if (otherIds.indexOf(selectedId) !== -1) { + var currentVals = getSelectedIds(selector).filter(function (v) { return v !== selectedId; }); + $(selector).val(currentVals).trigger('change'); + showDuplicateError(selectedName); + } }); } - initGroupSelect2("#groupAdmins"); - initGroupSelect2("#groupUsers"); + + initGroupSelect2("#groupAdmins", "#groupUsers"); + initGroupSelect2("#groupUsers", "#groupAdmins"); $.ajax({ url: resgrid.absoluteBaseUrl + '/User/Groups/GetMembersForGroup?groupId=' + $('#EditGroup_DepartmentGroupId').val() + '&includeAdmins=true&includeNormal=false', contentType: 'application/json', type: 'GET' diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/groups/resgrid.groups.newgroup.js b/Web/Resgrid.Web/wwwroot/js/app/internal/groups/resgrid.groups.newgroup.js index 30b5da1e..793a0b9c 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/groups/resgrid.groups.newgroup.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/groups/resgrid.groups.newgroup.js @@ -19,7 +19,23 @@ var resgrid; $("#StationAddress").hide(); } var groupUrl = resgrid.absoluteBaseUrl + '/User/Department/GetRecipientsForGrid?filter=3&filterNotInGroup=true'; - function initGroupSelect2(selector) { + + function showDuplicateError(userName) { + var alertId = 'groupDuplicateAlert'; + $('#' + alertId).remove(); + var alertHtml = ''; + $('.ibox-content form').prepend(alertHtml); + $('html, body').animate({ scrollTop: 0 }, 'fast'); + } + + function getSelectedIds(selector) { + return $(selector).val() || []; + } + + function initGroupSelect2(selector, otherSelector) { $(selector).select2({ placeholder: "Select users...", allowClear: true, @@ -31,10 +47,21 @@ var resgrid; return { results: $.map(data, function (u) { return { id: u.Id, text: u.Name }; }) }; } } + }).on('select2:select', function (e) { + var selectedId = e.params.data.id; + var selectedName = e.params.data.text; + var otherIds = getSelectedIds(otherSelector); + if (otherIds.indexOf(selectedId) !== -1) { + // Remove from this list + var currentVals = getSelectedIds(selector).filter(function (v) { return v !== selectedId; }); + $(selector).val(currentVals).trigger('change'); + showDuplicateError(selectedName); + } }); } - initGroupSelect2("#groupAdmins"); - initGroupSelect2("#groupUsers"); + + initGroupSelect2("#groupAdmins", "#groupUsers"); + initGroupSelect2("#groupUsers", "#groupAdmins"); $("#getPrintersButton").click(function () { if ($('#apiKey').val()) { $.ajax({ diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.adjust.js b/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.adjust.js index 8c111e8c..58863bcf 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.adjust.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.adjust.js @@ -13,6 +13,7 @@ var resgrid; $("#Inventory_Amount").attr({ type: 'number', min: -999999999, max: 999999999, step: 1 }); }); function getUnits(stationId) { + var noUnitLabel = (typeof inventoryAdjustStrings !== 'undefined' && inventoryAdjustStrings.noUnit) ? inventoryAdjustStrings.noUnit : 'No Unit'; $.ajax({ url: resgrid.absoluteBaseUrl + '/User/Units/GetUnitsForGroup?groupId=' + stationId, contentType: 'application/json; charset=utf-8', @@ -20,7 +21,7 @@ var resgrid; }).done(function (data) { if (data) { $('#UnitId').empty(); - $('#UnitId').append(''); + $('#UnitId').append(''); $.each(data, function (index, value) { $('#UnitId').append(''); }); diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.history.js b/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.history.js index 9c10f391..5a65a29e 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.history.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.history.js @@ -6,20 +6,24 @@ var resgrid; (function (history) { $(document).ready(function () { resgrid.common.analytics.track('Inventory - History'); + var strings = typeof inventoryHistoryStrings !== 'undefined' ? inventoryHistoryStrings : { + type: 'Type', amount: 'Amount', group: 'Group', batch: 'Batch', + timestamp: 'Timestamp', addedBy: 'Added By', actions: 'Actions', view: 'View' + }; $("#inventoryList").DataTable({ ajax: { url: resgrid.absoluteBaseUrl + '/User/Inventory/GetInventoryList', dataSrc: '' }, pageLength: 50, columns: [ - { data: 'Type', title: 'Type' }, - { data: 'Amount', title: 'Amount' }, - { data: 'Group', title: 'Group' }, - { data: 'Batch', title: 'Batch' }, - { data: 'Timestamp', title: 'Timestamp' }, - { data: 'UserName', title: 'Added By' }, + { data: 'Type', title: strings.type }, + { data: 'Amount', title: strings.amount }, + { data: 'Group', title: strings.group }, + { data: 'Batch', title: strings.batch }, + { data: 'Timestamp', title: strings.timestamp }, + { data: 'UserName', title: strings.addedBy }, { - data: 'InventoryId', title: 'Actions', orderable: false, + data: 'InventoryId', title: strings.actions, orderable: false, render: function (data) { - return 'View'; + return '' + strings.view + ''; } } ] diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.index.js b/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.index.js index 99e6ad96..55d96770 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.index.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.index.js @@ -6,14 +6,17 @@ var resgrid; (function (index) { $(document).ready(function () { resgrid.common.analytics.track('Inventory List'); + var strings = typeof inventoryIndexStrings !== 'undefined' ? inventoryIndexStrings : { + name: 'Name', group: 'Group', unit: 'Unit', count: 'Count' + }; $("#inventoryIndexList").DataTable({ ajax: { url: resgrid.absoluteBaseUrl + '/User/Inventory/GetCombinedInventoryList', dataSrc: '' }, pageLength: 50, columns: [ - { data: 'Name', title: 'Name' }, - { data: 'Group', title: 'Group' }, - { data: 'Unit', title: 'Unit' }, - { data: 'Count', title: 'Count' } + { data: 'Name', title: strings.name }, + { data: 'Group', title: strings.group }, + { data: 'Unit', title: strings.unit }, + { data: 'Count', title: strings.count } ] }); }); diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.manageTypes.js b/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.manageTypes.js index 1854673e..1f65f11b 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.manageTypes.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/inventory/resgrid.inventory.manageTypes.js @@ -6,17 +6,20 @@ var resgrid; (function (manageTypes) { $(document).ready(function () { resgrid.common.analytics.track('Inventory - Manage Types'); + var strings = typeof inventoryTypesStrings !== 'undefined' ? inventoryTypesStrings : { + name: 'Name', expiresDays: 'Expires Days', actions: 'Actions', edit: 'Edit', delete: 'Delete' + }; $("#typesIndexList").DataTable({ ajax: { url: resgrid.absoluteBaseUrl + '/User/Inventory/GetTypesList', dataSrc: '' }, pageLength: 50, columns: [ - { data: 'Name', title: 'Name' }, - { data: 'ExpiresDays', title: 'Expires Days' }, + { data: 'Name', title: strings.name }, + { data: 'ExpiresDays', title: strings.expiresDays }, { - data: 'TypeId', title: 'Actions', orderable: false, + data: 'TypeId', title: strings.actions, orderable: false, render: function (data) { - return 'Edit ' + - 'Delete'; + return '' + strings.edit + ' ' + + '' + strings.delete + ''; } } ] diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/messages/resgrid.messages.compose.js b/Web/Resgrid.Web/wwwroot/js/app/internal/messages/resgrid.messages.compose.js index 9a4abe96..c89ec627 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/messages/resgrid.messages.compose.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/messages/resgrid.messages.compose.js @@ -38,6 +38,7 @@ var resgrid; $(selector).select2({ placeholder: placeholder, allowClear: true, + multiple: true, ajax: { url: url, dataType: 'json', diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/personnel/resgrid.personnel.viewevents.js b/Web/Resgrid.Web/wwwroot/js/app/internal/personnel/resgrid.personnel.viewevents.js new file mode 100644 index 00000000..66d45126 --- /dev/null +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/personnel/resgrid.personnel.viewevents.js @@ -0,0 +1,88 @@ +var resgrid; +(function (resgrid) { + var personnel; + (function (personnel) { + var viewevents; + (function (viewevents) { + $(document).ready(function () { + viewevents.markers = []; + viewevents.map = L.map('eventsMap').setView([centerLat, centerLon], 13); + + L.tileLayer(osmTileUrl, { + attribution: '' + }).addTo(viewevents.map); + + viewevents.markers = []; + + var eventsTable = $("#eventsGrid").DataTable({ + ajax: { + url: resgrid.absoluteBaseUrl + '/User/Personnel/GetPersonnelEvents?userId=' + personnelUserId, + dataSrc: '' + }, + pageLength: 50, + columns: [ + { + data: 'EventId', + title: '', + orderable: false, + searchable: false, + render: function (data) { + return ''; + } + }, + { data: 'State', title: 'State' }, + { data: 'DestinationName', title: 'Destination' }, + { data: 'Timestamp', title: 'Timestamp' }, + { data: 'Note', title: 'Note' } + ] + }); + + // Update map markers and inject select-all checkbox after each draw + eventsTable.on('draw', function () { + updateMapMarkers(eventsTable); + }); + + $(document).on('click', '#checkAllEvents', function () { + $('#eventsGrid tbody :checkbox').prop('checked', this.checked); + }); + + // Add the select-all checkbox to the first column header + $('#eventsGrid thead th:first').html(''); + + function updateMapMarkers(table) { + $.each(viewevents.markers, function (index, item) { + item.remove && item.remove(); + }); + viewevents.markers = []; + + var data = table.rows().data(); + $.each(data, function (index, item) { + if (item.Latitude && item.Latitude.length > 0 && item.Longitude && item.Longitude.length > 0) { + var marker = L.marker([item.Latitude, item.Longitude], { + icon: new L.icon({ + iconUrl: "/images/Mapping/Event.png", + iconSize: [32, 37], + iconAnchor: [16, 37] + }), + draggable: false, + title: item.State + ' ' + item.Timestamp, + tooltip: item.State + ' ' + item.Timestamp + }).bindTooltip(item.State + ' ' + item.Timestamp, + { + permanent: true, + direction: 'bottom' + }).addTo(viewevents.map); + + viewevents.markers.push(marker); + } + }); + + if (viewevents.markers && viewevents.markers.length > 0) { + var group = new L.featureGroup(viewevents.markers); + viewevents.map.fitBounds(group.getBounds()); + } + } + }); + })(viewevents = personnel.viewevents || (personnel.viewevents = {})); + })(personnel = resgrid.personnel || (resgrid.personnel = {})); +})(resgrid || (resgrid = {})); diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/security/resgrid.security.audits.js b/Web/Resgrid.Web/wwwroot/js/app/internal/security/resgrid.security.audits.js index 32fd4c31..492f6faf 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/security/resgrid.security.audits.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/security/resgrid.security.audits.js @@ -32,7 +32,7 @@ var resgrid; orderable: false, searchable: false, render: function (data) { - return 'View'; + return 'View'; } } ] diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.editshiftgroups.js b/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.editshiftgroups.js index d2dd3e30..09d58c4a 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.editshiftgroups.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.editshiftgroups.js @@ -43,7 +43,9 @@ var resgrid; editshiftgroups.processShiftGroups = processShiftGroups; function addExistingGroup(group) { resgrid.shifts.editshiftgroups.groupsCount++; - $('#groups tbody').first().append("" + resgrid.shifts.editshiftgroups.generateExistingGroupDropdown(group.DepartmentGroupId, editshiftgroups.groupsCount) + "" + resgrid.shifts.editshiftgroups.generateRolesTables(editshiftgroups.groupsCount) + "Remove Group"); + var i18n = (typeof resgridShiftsI18n !== 'undefined') ? resgridShiftsI18n : {}; + var removeGroupLabel = i18n.removeGroup || 'Remove Group'; + $('#groups tbody').first().append("" + resgrid.shifts.editshiftgroups.generateExistingGroupDropdown(group.DepartmentGroupId, editshiftgroups.groupsCount) + "" + resgrid.shifts.editshiftgroups.generateRolesTables(editshiftgroups.groupsCount) + "" + removeGroupLabel + ""); for (var i = 0; i < group.Roles.length; i++) { addExistingGroupRole(group.Roles[i], resgrid.shifts.editshiftgroups.groupsCount); } @@ -51,18 +53,28 @@ var resgrid; editshiftgroups.addExistingGroup = addExistingGroup; function addGroup() { resgrid.shifts.editshiftgroups.groupsCount++; - $('#groups tbody').first().append("" + resgrid.shifts.editshiftgroups.generateGroupDropdown(editshiftgroups.groupsCount) + "" + resgrid.shifts.editshiftgroups.generateRolesTables(editshiftgroups.groupsCount) + "Remove Group"); + var i18n = (typeof resgridShiftsI18n !== 'undefined') ? resgridShiftsI18n : {}; + var removeGroupLabel = i18n.removeGroup || 'Remove Group'; + $('#groups tbody').first().append("" + resgrid.shifts.editshiftgroups.generateGroupDropdown(editshiftgroups.groupsCount) + "" + resgrid.shifts.editshiftgroups.generateRolesTables(editshiftgroups.groupsCount) + "" + removeGroupLabel + ""); } editshiftgroups.addGroup = addGroup; function addGroupRole(count) { var timestamp = new Date(); - $('#groupRolesTable_' + count + ' tbody').append("" + resgrid.shifts.editshiftgroups.generateRoleDropdown(editshiftgroups.groupsCount) + "Remove Role"); + var i18n = (typeof resgridShiftsI18n !== 'undefined') ? resgridShiftsI18n : {}; + var removeRoleLabel = i18n.removeRole || 'Remove Role'; + var removeRoleTitle = i18n.removeRoleFromGroup || 'Remove this role from the group'; + var roleCountMsg = i18n.roleCountRequired || 'Role count is required'; + $('#groupRolesTable_' + count + ' tbody').append("" + resgrid.shifts.editshiftgroups.generateRoleDropdown(editshiftgroups.groupsCount) + "" + removeRoleLabel + ""); addGroupRoleField('groupRole_' + count + '_' + timestamp.getUTCMilliseconds()); } editshiftgroups.addGroupRole = addGroupRole; function addExistingGroupRole(role, count) { var id = generate(4); - $('#groupRolesTable_' + count + ' tbody').append("" + resgrid.shifts.editshiftgroups.generateExistingRoleDropdown(role, editshiftgroups.groupsCount, id) + "Remove Role"); + var i18n = (typeof resgridShiftsI18n !== 'undefined') ? resgridShiftsI18n : {}; + var removeRoleLabel = i18n.removeRole || 'Remove Role'; + var removeRoleTitle = i18n.removeRoleFromGroup || 'Remove this role from the group'; + var roleCountMsg = i18n.roleCountRequired || 'Role count is required'; + $('#groupRolesTable_' + count + ' tbody').append("" + resgrid.shifts.editshiftgroups.generateExistingRoleDropdown(role, editshiftgroups.groupsCount, id) + "" + removeRoleLabel + ""); addGroupRoleField('groupRole_' + count + '_' + id); } editshiftgroups.addExistingGroupRole = addExistingGroupRole; @@ -115,7 +127,12 @@ var resgrid; } editshiftgroups.generateExistingRoleDropdown = generateExistingRoleDropdown; function generateRolesTables(count) { - var rolesTable = '
Shift Role Roles Count Add Role to Group
'; + var i18n = (typeof resgridShiftsI18n !== 'undefined') ? resgridShiftsI18n : {}; + var shiftRole = i18n.shiftRoleColumn || 'Shift Role'; + var rolesCount = i18n.rolesCountColumn || 'Roles Count'; + var addRoleLabel = i18n.addRoleToGroup || 'Add Role to Group'; + var addShiftRolesToGroupTitle = i18n.addShiftRolesToGroup || 'Add Shift Roles to Group'; + var rolesTable = '
' + shiftRole + '' + rolesCount + ' ' + addRoleLabel + '
'; return rolesTable; } editshiftgroups.generateRolesTables = generateRolesTables; diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.newshift.js b/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.newshift.js index b501f045..e04ea7be 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.newshift.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.newshift.js @@ -21,8 +21,9 @@ var resgrid; }).done(function (data) { resgrid.shifts.newshift.roleData = data; }); + var i18n = (typeof resgridShiftsI18n !== 'undefined') ? resgridShiftsI18n : {}; $("#shiftPersonnel").select2({ - placeholder: "Select Non-Group Personnel...", + placeholder: i18n.selectNonGroupPersonnel || "Select Non-Group Personnel...", allowClear: true, multiple: true, ajax: { @@ -35,7 +36,7 @@ var resgrid; }); $('.groupPersonnelSelect').each(function () { $(this).select2({ - placeholder: "Select Personnel for Group...", + placeholder: i18n.selectPersonnelForGroup || "Select Personnel for Group...", allowClear: true, multiple: true, ajax: { @@ -53,12 +54,18 @@ var resgrid; }); function addGroup() { resgrid.shifts.newshift.groupsCount++; - $('#groups tbody').first().append("" + resgrid.shifts.newshift.generateGroupDropdown(newshift.groupsCount) + "" + resgrid.shifts.newshift.generateRolesTables(newshift.groupsCount) + "Remove Group"); + var i18n = (typeof resgridShiftsI18n !== 'undefined') ? resgridShiftsI18n : {}; + var removeGroupLabel = i18n.removeGroup || 'Remove Group'; + $('#groups tbody').first().append("" + resgrid.shifts.newshift.generateGroupDropdown(newshift.groupsCount) + "" + resgrid.shifts.newshift.generateRolesTables(newshift.groupsCount) + "" + removeGroupLabel + ""); } newshift.addGroup = addGroup; function addGroupRole(count) { var timestamp = new Date(); - $('#groupRolesTable_' + count + ' tbody').append("" + resgrid.shifts.newshift.generateRoleDropdown(newshift.groupsCount) + "Remove Role Slot"); + var i18n = (typeof resgridShiftsI18n !== 'undefined') ? resgridShiftsI18n : {}; + var removeRoleLabel = i18n.removeRole || 'Remove Role'; + var removeRoleTitle = i18n.removeRoleFromGroup || 'Remove this role from the group'; + var roleCountMsg = i18n.roleCountRequired || 'Role count is required'; + $('#groupRolesTable_' + count + ' tbody').append("" + resgrid.shifts.newshift.generateRoleDropdown(newshift.groupsCount) + "" + removeRoleLabel + ""); addGroupRoleField('groupRole_' + count + '_' + timestamp.getUTCMilliseconds()); } newshift.addGroupRole = addGroupRole; @@ -108,7 +115,12 @@ var resgrid; } newshift.generateRoleDropdown = generateRoleDropdown; function generateRolesTables(count) { - var rolesTable = '
Shift Role Roles Count Add Role to Group
'; + var i18n = (typeof resgridShiftsI18n !== 'undefined') ? resgridShiftsI18n : {}; + var shiftRole = i18n.shiftRoleColumn || 'Shift Role'; + var rolesCount = i18n.rolesCountColumn || 'Roles Count'; + var addRoleLabel = i18n.addRoleToGroup || 'Add Role to Group'; + var addShiftRolesToGroupTitle = i18n.addShiftRolesToGroup || 'Add Shift Roles to Group'; + var rolesTable = '
' + shiftRole + '' + rolesCount + ' ' + addRoleLabel + '
'; return rolesTable; } newshift.generateRolesTables = generateRolesTables; diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.shiftStaffing.js b/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.shiftStaffing.js index 4797446b..e82270a1 100644 --- a/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.shiftStaffing.js +++ b/Web/Resgrid.Web/wwwroot/js/app/internal/shifts/resgrid.shifts.shiftStaffing.js @@ -80,13 +80,14 @@ var resgrid; var ids = new Array(); if (isAdmin) { - html = '
'; + var nonGroupLabel = (typeof resgridShiftsI18n !== 'undefined' && resgridShiftsI18n.nonGroupPersonnel) ? resgridShiftsI18n.nonGroupPersonnel : 'Non - Group Personnel'; + html = '
'; } for (var i = 0; i < data.length; i++) { if (isAdmin || data[i].Id == groupId) { var itemHtml = '
'; - itemHtml = itemHtml + '
'; + itemHtml = itemHtml + '
'; itemHtml = itemHtml + `
`; ids.push(data[i].Id); @@ -100,8 +101,9 @@ var resgrid; //} if (isAdmin) { + var nonGroupPlaceholder = (typeof resgridShiftsI18n !== 'undefined' && resgridShiftsI18n.selectNonGroupPersonnel) ? resgridShiftsI18n.selectNonGroupPersonnel : 'Select Non-Group Personnel...'; $("#shiftPersonnel").select2({ - placeholder: "Select Non-Group Personnel...", + placeholder: nonGroupPlaceholder, allowClear: true, multiple: true, ajax: { @@ -123,8 +125,9 @@ var resgrid; } $('.groupPersonnelSelect').each(function (i, obj) { var that = this; + var groupPlaceholder = (typeof resgridShiftsI18n !== 'undefined' && resgridShiftsI18n.selectPersonnelForGroup) ? resgridShiftsI18n.selectPersonnelForGroup : 'Select Personnel for Group...'; $(that).select2({ - placeholder: "Select Personnel for Group...", + placeholder: groupPlaceholder, allowClear: true, multiple: true, ajax: { @@ -180,7 +183,7 @@ var resgrid; $(`#unitRole_${data2[j].UnitId}_${roleIds[l]}`).each(function (i, obj) { var that = this; $(that).select2({ - placeholder: "Select Person...", + placeholder: (typeof resgridShiftsI18n !== 'undefined' && resgridShiftsI18n.selectPerson) ? resgridShiftsI18n.selectPerson : 'Select Person...', allowClear: true, ajax: { url: resgrid.absoluteBaseUrl + '/User/Personnel/GetPersonnelForGridWithFilter', From 5dfee2ba76c2543667aebac5d2906fc2a8e6a455 Mon Sep 17 00:00:00 2001 From: Shawn Jackson Date: Sat, 7 Mar 2026 21:39:11 -0800 Subject: [PATCH 4/5] RE1-T104 Adding coderabbit config to exclude resx files --- .coderabbit.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .coderabbit.yaml diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 00000000..1ea2f814 --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,6 @@ +reviews: + path_filters: + - "!**/*.resx" + - "!**/*.Designer.cs" + - "!**/bin/**" + - "!**/obj/**" \ No newline at end of file From e96eb34f5dd1584e1aa4d8d81c6c79e9b92b1f94 Mon Sep 17 00:00:00 2001 From: Shawn Jackson Date: Sat, 7 Mar 2026 21:46:39 -0800 Subject: [PATCH 5/5] RE1-T104 Updating coderabbit config --- .coderabbit.yaml | 229 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 228 insertions(+), 1 deletion(-) diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 1ea2f814..b4f7cf26 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -1,6 +1,233 @@ +# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json +language: en-US +tone_instructions: '' +early_access: false +enable_free_tier: true +inheritance: false reviews: + profile: chill + request_changes_workflow: false + high_level_summary: true + high_level_summary_instructions: '' + high_level_summary_placeholder: '@coderabbitai summary' + high_level_summary_in_walkthrough: false + auto_title_placeholder: '@coderabbitai' + auto_title_instructions: '' + review_status: true + review_details: false + commit_status: true + fail_commit_status: false + collapse_walkthrough: true + changed_files_summary: true + sequence_diagrams: true + estimate_code_review_effort: true + assess_linked_issues: true + related_issues: true + related_prs: true + suggested_labels: true + labeling_instructions: [] + auto_apply_labels: false + suggested_reviewers: true + auto_assign_reviewers: false + in_progress_fortune: true + poem: false + enable_prompt_for_ai_agents: true path_filters: - "!**/*.resx" - "!**/*.Designer.cs" - "!**/bin/**" - - "!**/obj/**" \ No newline at end of file + - "!**/obj/**" + path_instructions: [] + abort_on_close: true + disable_cache: false + auto_review: + enabled: true + description_keyword: '' + auto_incremental_review: true + auto_pause_after_reviewed_commits: 5 + ignore_title_keywords: [] + labels: [] + drafts: false + base_branches: [] + ignore_usernames: [] + finishing_touches: + docstrings: + enabled: true + unit_tests: + enabled: true + simplify: + enabled: false + custom: [] + pre_merge_checks: + override_requested_reviewers_only: false + docstrings: + mode: warning + threshold: 80 + title: + mode: warning + requirements: '' + description: + mode: warning + issue_assessment: + mode: warning + custom_checks: [] + tools: + ast-grep: + rule_dirs: [] + util_dirs: [] + essential_rules: true + packages: [] + shellcheck: + enabled: true + ruff: + enabled: true + markdownlint: + enabled: true + github-checks: + enabled: true + timeout_ms: 90000 + languagetool: + enabled: true + enabled_rules: [] + disabled_rules: [] + enabled_categories: [] + disabled_categories: [] + enabled_only: false + level: default + biome: + enabled: true + hadolint: + enabled: true + swiftlint: + enabled: true + phpstan: + enabled: true + level: default + phpmd: + enabled: true + phpcs: + enabled: true + golangci-lint: + enabled: true + yamllint: + enabled: true + gitleaks: + enabled: true + trufflehog: + enabled: true + checkov: + enabled: true + tflint: + enabled: true + detekt: + enabled: true + eslint: + enabled: true + flake8: + enabled: true + fortitudeLint: + enabled: true + rubocop: + enabled: true + buf: + enabled: true + regal: + enabled: true + actionlint: + enabled: true + pmd: + enabled: true + clang: + enabled: true + cppcheck: + enabled: true + opengrep: + enabled: true + semgrep: + enabled: true + circleci: + enabled: true + clippy: + enabled: true + sqlfluff: + enabled: true + trivy: + enabled: true + prismaLint: + enabled: true + pylint: + enabled: true + oxc: + enabled: true + shopifyThemeCheck: + enabled: true + luacheck: + enabled: true + brakeman: + enabled: true + dotenvLint: + enabled: true + htmlhint: + enabled: true + stylelint: + enabled: true + checkmake: + enabled: true + osvScanner: + enabled: true + blinter: + enabled: true + smartyLint: + enabled: true + emberTemplateLint: + enabled: true + psscriptanalyzer: + enabled: true +chat: + art: true + auto_reply: true + integrations: + jira: + usage: auto + linear: + usage: auto +knowledge_base: + opt_out: false + web_search: + enabled: true + code_guidelines: + enabled: true + filePatterns: [] + learnings: + scope: auto + issues: + scope: auto + jira: + usage: auto + project_keys: [] + linear: + usage: auto + team_keys: [] + pull_requests: + scope: auto + mcp: + usage: auto + disabled_servers: [] + linked_repositories: [] +code_generation: + docstrings: + language: en-US + path_instructions: [] + unit_tests: + path_instructions: [] +issue_enrichment: + auto_enrich: + enabled: false + planning: + enabled: true + auto_planning: + enabled: true + labels: [] + labeling: + labeling_instructions: [] + auto_apply_labels: false \ No newline at end of file