bump version and kiosk enhancement.
This commit is contained in:
@@ -55,25 +55,56 @@ namespace CarCareTracker.Controllers
|
||||
{
|
||||
return View(model: tab);
|
||||
}
|
||||
public IActionResult Kiosk(string exceptions)
|
||||
[Route("/kiosk")]
|
||||
public IActionResult Kiosk(string exclusions, KioskMode kioskMode = KioskMode.Vehicle)
|
||||
{
|
||||
try {
|
||||
var exceptionList = string.IsNullOrWhiteSpace(exceptions) ? new List<int>() : exceptions.Split(',').Select(x => int.Parse(x)).ToList();
|
||||
return View(exceptionList);
|
||||
var viewModel = new KioskViewModel
|
||||
{
|
||||
Exclusions = string.IsNullOrWhiteSpace(exclusions) ? new List<int>() : exclusions.Split(',').Select(x => int.Parse(x)).ToList(),
|
||||
KioskMode = kioskMode
|
||||
};
|
||||
return View(viewModel);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return View(new List<int>());
|
||||
_logger.LogError(ex.Message);
|
||||
return View(new KioskViewModel());
|
||||
}
|
||||
}
|
||||
public IActionResult KioskContent(List<int> exceptionList)
|
||||
[HttpPost]
|
||||
public IActionResult KioskContent(KioskViewModel kioskParameters)
|
||||
{
|
||||
var vehiclesStored = _dataAccess.GetVehicles();
|
||||
if (!User.IsInRole(nameof(UserData.IsRootUser)))
|
||||
{
|
||||
vehiclesStored = _userLogic.FilterUserVehicles(vehiclesStored, GetUserID());
|
||||
}
|
||||
vehiclesStored.RemoveAll(x => exceptionList.Contains(x.Id));
|
||||
vehiclesStored.RemoveAll(x => kioskParameters.Exclusions.Contains(x.Id));
|
||||
var userConfig = _config.GetUserConfig(User);
|
||||
if (userConfig.HideSoldVehicles)
|
||||
{
|
||||
vehiclesStored.RemoveAll(x => !string.IsNullOrWhiteSpace(x.SoldDate));
|
||||
}
|
||||
switch (kioskParameters.KioskMode)
|
||||
{
|
||||
case KioskMode.Vehicle:
|
||||
{
|
||||
var kioskResult = _vehicleLogic.GetVehicleInfo(vehiclesStored);
|
||||
return PartialView("_Kiosk", kioskResult);
|
||||
}
|
||||
case KioskMode.Plan:
|
||||
{
|
||||
var kioskResult = _vehicleLogic.GetPlans(vehiclesStored, true);
|
||||
return PartialView("_KioskPlan", kioskResult);
|
||||
}
|
||||
break;
|
||||
case KioskMode.Reminder:
|
||||
{
|
||||
var kioskResult = _vehicleLogic.GetReminders(vehiclesStored, false);
|
||||
return PartialView("_KioskReminder", kioskResult);
|
||||
}
|
||||
}
|
||||
var result = _vehicleLogic.GetVehicleInfo(vehiclesStored);
|
||||
return PartialView("_Kiosk", result);
|
||||
}
|
||||
@@ -140,19 +171,7 @@ namespace CarCareTracker.Controllers
|
||||
{
|
||||
vehiclesStored = _userLogic.FilterUserVehicles(vehiclesStored, GetUserID());
|
||||
}
|
||||
List<ReminderRecordViewModel> reminders = new List<ReminderRecordViewModel>();
|
||||
foreach (Vehicle vehicle in vehiclesStored)
|
||||
{
|
||||
var vehicleReminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicle.Id);
|
||||
vehicleReminders.RemoveAll(x => x.Metric == ReminderMetric.Odometer);
|
||||
//we don't care about mileages so we can basically fake the current vehicle mileage.
|
||||
if (vehicleReminders.Any())
|
||||
{
|
||||
var reminderUrgency = _reminderHelper.GetReminderRecordViewModels(vehicleReminders, 0, DateTime.Now);
|
||||
reminderUrgency = reminderUrgency.Select(x => new ReminderRecordViewModel { Id = x.Id, Date = x.Date, Urgency = x.Urgency, Description = $"{vehicle.Year} {vehicle.Make} {vehicle.Model} #{StaticHelper.GetVehicleIdentifier(vehicle)} - {x.Description}" }).ToList();
|
||||
reminders.AddRange(reminderUrgency);
|
||||
}
|
||||
}
|
||||
var reminders = _vehicleLogic.GetReminders(vehiclesStored, true);
|
||||
return PartialView("_Calendar", reminders);
|
||||
}
|
||||
public IActionResult ViewCalendarReminder(int reminderId)
|
||||
|
||||
10
Enum/KioskMode.cs
Normal file
10
Enum/KioskMode.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public enum KioskMode
|
||||
{
|
||||
Vehicle = 0,
|
||||
Plan = 1,
|
||||
Reminder = 2,
|
||||
Cycle = 3
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,52 @@ namespace CarCareTracker.Helper
|
||||
return input;
|
||||
}
|
||||
}
|
||||
public static string GetReminderUrgencyColor(ReminderUrgency input)
|
||||
{
|
||||
switch (input)
|
||||
{
|
||||
case ReminderUrgency.NotUrgent:
|
||||
return "text-bg-success";
|
||||
case ReminderUrgency.VeryUrgent:
|
||||
return "text-bg-danger";
|
||||
case ReminderUrgency.PastDue:
|
||||
return "text-bg-secondary";
|
||||
default:
|
||||
return "text-bg-warning";
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPlanRecordColor(PlanPriority input)
|
||||
{
|
||||
switch (input)
|
||||
{
|
||||
case PlanPriority.Critical:
|
||||
return "text-bg-danger";
|
||||
case PlanPriority.Normal:
|
||||
return "text-bg-primary";
|
||||
case PlanPriority.Low:
|
||||
return "text-bg-info";
|
||||
default:
|
||||
return "text-bg-primary";
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetPlanRecordProgress(PlanProgress input)
|
||||
{
|
||||
switch (input)
|
||||
{
|
||||
case PlanProgress.Backlog:
|
||||
return "Planned";
|
||||
case PlanProgress.InProgress:
|
||||
return "Doing";
|
||||
case PlanProgress.Testing:
|
||||
return "Testing";
|
||||
case PlanProgress.Done:
|
||||
return "Done";
|
||||
default:
|
||||
return input.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static string TruncateStrings(string input, int maxLength = 25)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace CarCareTracker.Logic
|
||||
int GetOwnershipDays(string purchaseDate, string soldDate, List<ServiceRecord> serviceRecords, List<CollisionRecord> repairRecords, List<GasRecord> gasRecords, List<UpgradeRecord> upgradeRecords, List<OdometerRecord> odometerRecords, List<TaxRecord> taxRecords);
|
||||
bool GetVehicleHasUrgentOrPastDueReminders(int vehicleId, int currentMileage);
|
||||
List<VehicleInfo> GetVehicleInfo(List<Vehicle> vehicles);
|
||||
List<ReminderRecordViewModel> GetReminders(List<Vehicle> vehicles, bool isCalendar);
|
||||
List<PlanRecord> GetPlans(List<Vehicle> vehicles, bool excludeDone);
|
||||
}
|
||||
public class VehicleLogic: IVehicleLogic
|
||||
{
|
||||
@@ -276,5 +278,44 @@ namespace CarCareTracker.Logic
|
||||
}
|
||||
return apiResult;
|
||||
}
|
||||
public List<ReminderRecordViewModel> GetReminders(List<Vehicle> vehicles, bool isCalendar)
|
||||
{
|
||||
List<ReminderRecordViewModel> reminders = new List<ReminderRecordViewModel>();
|
||||
foreach (Vehicle vehicle in vehicles)
|
||||
{
|
||||
var vehicleReminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicle.Id);
|
||||
if (isCalendar)
|
||||
{
|
||||
vehicleReminders.RemoveAll(x => x.Metric == ReminderMetric.Odometer);
|
||||
//we don't care about mileages so we can basically fake the current vehicle mileage.
|
||||
}
|
||||
if (vehicleReminders.Any())
|
||||
{
|
||||
var vehicleMileage = isCalendar ? 0 : GetMaxMileage(vehicle.Id);
|
||||
var reminderUrgency = _reminderHelper.GetReminderRecordViewModels(vehicleReminders, vehicleMileage, DateTime.Now);
|
||||
reminderUrgency = reminderUrgency.Select(x => new ReminderRecordViewModel { Id = x.Id, Metric = x.Metric, Date = x.Date, Notes = x.Notes, Mileage = x.Mileage, Urgency = x.Urgency, Description = $"{vehicle.Year} {vehicle.Make} {vehicle.Model} #{StaticHelper.GetVehicleIdentifier(vehicle)} - {x.Description}" }).ToList();
|
||||
reminders.AddRange(reminderUrgency);
|
||||
}
|
||||
}
|
||||
return reminders.OrderByDescending(x=>x.Urgency).ToList();
|
||||
}
|
||||
public List<PlanRecord> GetPlans(List<Vehicle> vehicles, bool excludeDone)
|
||||
{
|
||||
List<PlanRecord> plans = new List<PlanRecord>();
|
||||
foreach (Vehicle vehicle in vehicles)
|
||||
{
|
||||
var vehiclePlans = _planRecordDataAccess.GetPlanRecordsByVehicleId(vehicle.Id);
|
||||
if (excludeDone)
|
||||
{
|
||||
vehiclePlans.RemoveAll(x => x.Progress == PlanProgress.Done);
|
||||
}
|
||||
if (vehiclePlans.Any())
|
||||
{
|
||||
var convertedPlans = vehiclePlans.Select(x => new PlanRecord { Priority = x.Priority, Progress = x.Progress, Notes = x.Notes, RequisitionHistory = x.RequisitionHistory, Description = $"{vehicle.Year} {vehicle.Make} {vehicle.Model} #{StaticHelper.GetVehicleIdentifier(vehicle)} - {x.Description}" });
|
||||
plans.AddRange(convertedPlans);
|
||||
}
|
||||
}
|
||||
return plans.OrderBy(x => x.Priority).ThenBy(x=>x.Progress).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
Models/Kiosk/KioskViewModel.cs
Normal file
14
Models/Kiosk/KioskViewModel.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public class KioskViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// List of vehicle ids to exclude from Kiosk Dashboard
|
||||
/// </summary>
|
||||
public List<int> Exclusions { get; set; } = new List<int>();
|
||||
/// <summary>
|
||||
/// Whether to retrieve data for vehicle, plans, or reminder view.
|
||||
/// </summary>
|
||||
public KioskMode KioskMode { get; set; } = KioskMode.Vehicle;
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,7 @@ Read this [Getting Started Guide](https://docs.lubelogger.com/Installation/Getti
|
||||
- [Chart.js](https://github.com/chartjs/Chart.js)
|
||||
- [Drawdown](https://github.com/adamvleggett/drawdown)
|
||||
- [MailKit](https://github.com/jstedfast/MailKit)
|
||||
- [Masonry](https://github.com/desandro/masonry)
|
||||
|
||||
## License
|
||||
MIT
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
initialOdometer - Initial Odometer reading(optional)<br />
|
||||
odometer - Odometer reading<br />
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
@@ -153,6 +154,7 @@
|
||||
description - Description<br/>
|
||||
cost - Cost<br />
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
@@ -190,6 +192,7 @@
|
||||
description - Description<br />
|
||||
cost - Cost<br />
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
@@ -227,6 +230,7 @@
|
||||
description - Description<br />
|
||||
cost - Cost<br />
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
@@ -263,6 +267,7 @@
|
||||
description - Description<br />
|
||||
cost - Cost<br />
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
@@ -306,6 +311,7 @@
|
||||
isFillToFull(bool) - Filled To Full<br />
|
||||
missedFuelUp(bool) - Missed Fuel Up<br />
|
||||
notes - notes(optional)<br />
|
||||
tags - tags separated by space(optional)<br />
|
||||
extrafields - <a class="link-body-emphasis link-offset-2 link-underline-opacity-25 link-underline-opacity-100-hover reminder-calendar-item" onclick="showExtraFieldsInfo()">extrafields(optional)</a><br />
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
@{
|
||||
ViewData["Title"] = "Kiosk";
|
||||
}
|
||||
@model List<int>
|
||||
@model KioskViewModel
|
||||
@section Scripts {
|
||||
<script src="~/lib/masonry/masonry.min.js"></script>
|
||||
}
|
||||
<div class="progress" role="progressbar" aria-label="Refresh Progress" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100" style="height: 1px">
|
||||
<div class="progress-bar" style="width: 0%"></div>
|
||||
</div>
|
||||
@@ -11,8 +14,11 @@
|
||||
let refreshTimer;
|
||||
let exceptionList = [];
|
||||
let subtractAmount = 0;
|
||||
let kioskMode = '@Model.KioskMode';
|
||||
let currentKioskMode = 'Plan';
|
||||
let kioskWakeLock;
|
||||
|
||||
@foreach(int exception in Model)
|
||||
@foreach(int exception in Model.Exclusions)
|
||||
{
|
||||
@:exceptionList.push(@exception);
|
||||
}
|
||||
@@ -25,14 +31,56 @@
|
||||
subtractAmount = 2;
|
||||
}
|
||||
retrieveKioskContent();
|
||||
//acquire wakeLock;
|
||||
try {
|
||||
navigator.wakeLock.request('screen').then((wl) => {
|
||||
kioskWakeLock = wl;
|
||||
});
|
||||
} catch (err) {
|
||||
errorToast('Location Services not Enabled');
|
||||
}
|
||||
}
|
||||
function retrieveKioskContent(){
|
||||
clearInterval(refreshTimer);
|
||||
$.post('/Home/KioskContent', {exceptionList: exceptionList}, function (data) {
|
||||
$("#kioskContainer").html(data);
|
||||
$(".progress-bar").width($("#kioskContainer").width());
|
||||
setTimeout(function () { startTimer() }, 500);
|
||||
});
|
||||
if (kioskMode != 'Cycle'){
|
||||
$.post('/Home/KioskContent', { exclusions: exceptionList, kioskMode: kioskMode }, function (data) {
|
||||
$("#kioskContainer").html(data);
|
||||
$(".kiosk-content").masonry();
|
||||
if ($(".no-data-message").length == 0) {
|
||||
$(".progress-bar").width($("#kioskContainer").width());
|
||||
setTimeout(function () { startTimer() }, 500);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//cycle mode
|
||||
switch (currentKioskMode) {
|
||||
case "Vehicle":
|
||||
currentKioskMode = "Reminder";
|
||||
break;
|
||||
case "Reminder":
|
||||
currentKioskMode = "Plan";
|
||||
break;
|
||||
case "Plan":
|
||||
currentKioskMode = "Vehicle";
|
||||
break;
|
||||
}
|
||||
$.post('/Home/KioskContent', { exclusions: exceptionList, kioskMode: currentKioskMode }, function (data) {
|
||||
$("#kioskContainer").html(data);
|
||||
$(".kiosk-content").masonry();
|
||||
if ($(".no-data-message").length > 0) {
|
||||
//if no data on vehicle page
|
||||
if (currentKioskMode == "Vehicle") {
|
||||
return; //exit
|
||||
} else {
|
||||
retrieveKioskContent(); //skip until we hit a page with content.
|
||||
}
|
||||
} else {
|
||||
$(".progress-bar").width($("#kioskContainer").width());
|
||||
setTimeout(function () { startTimer() }, 500);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
function startTimer() {
|
||||
refreshTimer = setInterval(function () {
|
||||
@@ -45,6 +93,9 @@
|
||||
}, 100);
|
||||
}
|
||||
function addVehicleToExceptionList(vehicleId) {
|
||||
if (kioskMode == 'Cycle') {
|
||||
return;
|
||||
}
|
||||
Swal.fire({
|
||||
title: "Remove Vehicle from Dashboard?",
|
||||
text: "Removed vehicles can be restored by refreshing the page",
|
||||
@@ -58,5 +109,28 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
function toggleReminderNote(sender){
|
||||
var reminderNote = $(sender).find('.reminder-note');
|
||||
if (reminderNote.text().trim() != ''){
|
||||
if (reminderNote.hasClass('d-none')) {
|
||||
reminderNote.removeClass('d-none');
|
||||
} else {
|
||||
reminderNote.addClass('d-none');
|
||||
}
|
||||
$(".kiosk-content").masonry();
|
||||
}
|
||||
}
|
||||
function togglePlanDetails(sender) {
|
||||
toggleReminderNote(sender);
|
||||
var planSupplies = $(sender).find('.plan-supplies');
|
||||
if (planSupplies.find('.plan-supply').length > 0) {
|
||||
if (planSupplies.hasClass('d-none')) {
|
||||
planSupplies.removeClass('d-none');
|
||||
} else {
|
||||
planSupplies.addClass('d-none');
|
||||
}
|
||||
$(".kiosk-content").masonry();
|
||||
}
|
||||
}
|
||||
initKiosk();
|
||||
</script>
|
||||
@@ -6,10 +6,10 @@
|
||||
var userConfig = config.GetUserConfig(User);
|
||||
var userLanguage = userConfig.UserLanguage;
|
||||
}
|
||||
<div class="row row-cols-1 row-cols-md-3 g-4 mt-1">
|
||||
@foreach(VehicleInfo vehicle in Model)
|
||||
{
|
||||
@if (!(userConfig.HideSoldVehicles && !string.IsNullOrWhiteSpace(vehicle.VehicleData.SoldDate)))
|
||||
@if (Model.Any())
|
||||
{
|
||||
<div class="row row-cols-1 row-cols-md-3 g-4 mt-1 kiosk-content" data-masonry='{"percentPosition": true }'>
|
||||
@foreach (VehicleInfo vehicle in Model)
|
||||
{
|
||||
<div class="col">
|
||||
<div class="card" onclick="addVehicleToExceptionList(@vehicle.VehicleData.Id)">
|
||||
@@ -65,7 +65,7 @@
|
||||
}
|
||||
@if (vehicle.NextReminder != null)
|
||||
{
|
||||
<hr style="margin:0px;"/>
|
||||
<hr style="margin:0px;" />
|
||||
<div class="card-body" style="padding-top:0.25rem; padding-bottom:0.25rem;">
|
||||
<h5 class="card-title">@translator.Translate(userLanguage, "Upcoming Reminder")</h5>
|
||||
<div class="row">
|
||||
@@ -112,7 +112,15 @@
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row no-data-message">
|
||||
<div class="col">
|
||||
<span class="display-3">@translator.Translate(userLanguage, "No records available to display")</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
86
Views/Home/_KioskPlan.cshtml
Normal file
86
Views/Home/_KioskPlan.cshtml
Normal file
@@ -0,0 +1,86 @@
|
||||
@using CarCareTracker.Helper
|
||||
@model List<PlanRecord>
|
||||
@inject IConfigHelper config
|
||||
@inject ITranslationHelper translator
|
||||
@{
|
||||
var userConfig = config.GetUserConfig(User);
|
||||
var userLanguage = userConfig.UserLanguage;
|
||||
}
|
||||
@if (Model.Any())
|
||||
{
|
||||
<div class="row row-cols-1 row-cols-md-3 g-4 mt-1 kiosk-content" data-masonry='{"percentPosition": true }'>
|
||||
@foreach (PlanRecord plan in Model)
|
||||
{
|
||||
<div class="col" onclick="togglePlanDetails(this)">
|
||||
<div class="card @StaticHelper.GetPlanRecordColor(plan.Priority)">
|
||||
<div class="card-body" style="padding-top:0.25rem; padding-bottom:0.25rem;">
|
||||
<h5 class="card-title">@plan.Description</h5>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<p class="display-7 d-none reminder-note" style="white-space: pre-wrap">@plan.Notes</p>
|
||||
<p class="lead text-wrap">@translator.Translate(userLanguage, StaticHelper.GetPlanRecordProgress(plan.Progress))</p>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
@if (plan.ImportMode == ImportMode.ServiceRecord)
|
||||
{
|
||||
<span class="lead">@translator.Translate(userLanguage, "Service")</span>
|
||||
}
|
||||
else if (plan.ImportMode == ImportMode.UpgradeRecord)
|
||||
{
|
||||
<span class="lead">@translator.Translate(userLanguage, "Repairs")</span>
|
||||
}
|
||||
else if (plan.ImportMode == ImportMode.RepairRecord)
|
||||
{
|
||||
<span class="lead">@translator.Translate(userLanguage, "Upgrades")</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if (plan.RequisitionHistory.Any())
|
||||
{
|
||||
<ul class="list-group list-group-flush plan-supplies d-none">
|
||||
<li class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
@translator.Translate(userLanguage, "Part Number")
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@translator.Translate(userLanguage, "Description")
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@translator.Translate(userLanguage, "Quantity")
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@foreach (SupplyUsageHistory supply in plan.RequisitionHistory)
|
||||
{
|
||||
<li class="list-group-item plan-supply">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
@supply.PartNumber
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@supply.Description
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@supply.Quantity
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
} else
|
||||
{
|
||||
<div class="row no-data-message">
|
||||
<div class="col">
|
||||
<span class="display-3">@translator.Translate(userLanguage, "No records available to display")</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
47
Views/Home/_KioskReminder.cshtml
Normal file
47
Views/Home/_KioskReminder.cshtml
Normal file
@@ -0,0 +1,47 @@
|
||||
@using CarCareTracker.Helper
|
||||
@model List<ReminderRecordViewModel>
|
||||
@inject IConfigHelper config
|
||||
@inject ITranslationHelper translator
|
||||
@{
|
||||
var userConfig = config.GetUserConfig(User);
|
||||
var userLanguage = userConfig.UserLanguage;
|
||||
}
|
||||
@if (Model.Any())
|
||||
{
|
||||
<div class="row row-cols-1 row-cols-md-3 g-4 mt-1 kiosk-content" data-masonry='{"percentPosition": true }'>
|
||||
@foreach (ReminderRecordViewModel reminder in Model)
|
||||
{
|
||||
<div class="col" onclick="toggleReminderNote(this)">
|
||||
<div class="card @StaticHelper.GetReminderUrgencyColor(reminder.Urgency)">
|
||||
<div class="card-body" style="padding-top:0.25rem; padding-bottom:0.25rem;">
|
||||
<h5 class="card-title">@reminder.Description</h5>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<p class="display-7 d-none reminder-note" style="white-space: pre-wrap">@reminder.Notes</p>
|
||||
<p class="lead text-wrap">@translator.Translate(userLanguage, StaticHelper.GetTitleCaseReminderUrgency(reminder.Urgency))</p>
|
||||
<div class="row">
|
||||
@if (reminder.Metric == ReminderMetric.Date || reminder.Metric == ReminderMetric.Both)
|
||||
{
|
||||
<div class="col-6"><i class='bi bi-calendar-event me-2'></i>@reminder.Date.ToShortDateString()</div>
|
||||
}
|
||||
@if (reminder.Metric == ReminderMetric.Odometer || reminder.Metric == ReminderMetric.Both)
|
||||
{
|
||||
<div class="col-6"><i class='bi bi-speedometer me-2'></i>@reminder.Mileage</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="row no-data-message">
|
||||
<div class="col">
|
||||
<span class="display-3">@translator.Translate(userLanguage, "No records available to display")</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -308,6 +308,7 @@
|
||||
<li class="list-group-item">Chart.js</li>
|
||||
<li class="list-group-item">Drawdown</li>
|
||||
<li class="list-group-item">MailKit</li>
|
||||
<li class="list-group-item">Masonry</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
File diff suppressed because one or more lines are too long
9
wwwroot/lib/masonry/masonry.min.js
vendored
Normal file
9
wwwroot/lib/masonry/masonry.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user