Merge pull request #325 from hargata/Hargata/bulk.selection

Hargata/bulk.selection
This commit is contained in:
Hargata Softworks
2024-02-21 22:33:19 -07:00
committed by GitHub
15 changed files with 266 additions and 3 deletions

View File

@@ -2250,6 +2250,119 @@ namespace CarCareTracker.Controllers
}
return Json(result);
}
[HttpPost]
public IActionResult GetGenericRecordModal(List<int> recordIds, ImportMode dataType)
{
return PartialView("_GenericRecordModal", new GenericRecordEditModel() { DataType = dataType, RecordIds = recordIds });
}
[HttpPost]
public IActionResult EditMultipleRecords(GenericRecordEditModel genericRecordEditModel)
{
var dateIsEdited = genericRecordEditModel.EditRecord.Date != default;
var descriptionIsEdited = !string.IsNullOrWhiteSpace(genericRecordEditModel.EditRecord.Description);
var mileageIsEdited = genericRecordEditModel.EditRecord.Mileage != default;
var costIsEdited = genericRecordEditModel.EditRecord.Cost != default;
var noteIsEdited = !string.IsNullOrWhiteSpace(genericRecordEditModel.EditRecord.Notes);
var tagsIsEdited = genericRecordEditModel.EditRecord.Tags.Any();
bool result = false;
foreach (int recordId in genericRecordEditModel.RecordIds)
{
switch (genericRecordEditModel.DataType)
{
case ImportMode.ServiceRecord:
{
var existingRecord = _serviceRecordDataAccess.GetServiceRecordById(recordId);
if (dateIsEdited)
{
existingRecord.Date = genericRecordEditModel.EditRecord.Date;
}
if (descriptionIsEdited)
{
existingRecord.Description = genericRecordEditModel.EditRecord.Description;
}
if (mileageIsEdited)
{
existingRecord.Mileage = genericRecordEditModel.EditRecord.Mileage;
}
if (costIsEdited)
{
existingRecord.Cost = genericRecordEditModel.EditRecord.Cost;
}
if (noteIsEdited)
{
existingRecord.Notes = genericRecordEditModel.EditRecord.Notes;
}
if (tagsIsEdited)
{
existingRecord.Tags = genericRecordEditModel.EditRecord.Tags;
}
result = _serviceRecordDataAccess.SaveServiceRecordToVehicle(existingRecord);
}
break;
case ImportMode.RepairRecord:
{
var existingRecord = _collisionRecordDataAccess.GetCollisionRecordById(recordId);
if (dateIsEdited)
{
existingRecord.Date = genericRecordEditModel.EditRecord.Date;
}
if (descriptionIsEdited)
{
existingRecord.Description = genericRecordEditModel.EditRecord.Description;
}
if (mileageIsEdited)
{
existingRecord.Mileage = genericRecordEditModel.EditRecord.Mileage;
}
if (costIsEdited)
{
existingRecord.Cost = genericRecordEditModel.EditRecord.Cost;
}
if (noteIsEdited)
{
existingRecord.Notes = genericRecordEditModel.EditRecord.Notes;
}
if (tagsIsEdited)
{
existingRecord.Tags = genericRecordEditModel.EditRecord.Tags;
}
result = _collisionRecordDataAccess.SaveCollisionRecordToVehicle(existingRecord);
}
break;
case ImportMode.UpgradeRecord:
{
var existingRecord = _upgradeRecordDataAccess.GetUpgradeRecordById(recordId);
if (dateIsEdited)
{
existingRecord.Date = genericRecordEditModel.EditRecord.Date;
}
if (descriptionIsEdited)
{
existingRecord.Description = genericRecordEditModel.EditRecord.Description;
}
if (mileageIsEdited)
{
existingRecord.Mileage = genericRecordEditModel.EditRecord.Mileage;
}
if (costIsEdited)
{
existingRecord.Cost = genericRecordEditModel.EditRecord.Cost;
}
if (noteIsEdited)
{
existingRecord.Notes = genericRecordEditModel.EditRecord.Notes;
}
if (tagsIsEdited)
{
existingRecord.Tags = genericRecordEditModel.EditRecord.Tags;
}
result = _upgradeRecordDataAccess.SaveUpgradeRecordToVehicle(existingRecord);
}
break;
}
}
return Json(result);
}
#endregion
}

View File

@@ -0,0 +1,9 @@
namespace CarCareTracker.Models
{
public class GenericRecordEditModel
{
public ImportMode DataType { get; set; }
public List<int> RecordIds { get; set; } = new List<int>();
public GenericRecord EditRecord { get; set; } = new GenericRecord();
}
}

View File

@@ -201,7 +201,7 @@
<img src="/defaults/lubelogger_logo.png" />
</div>
<div class="d-flex justify-content-center">
<small class="text-body-secondary">Version 1.2.1</small>
<small class="text-body-secondary">Version 1.2.2</small>
</div>
<p class="lead">
Proudly developed in the rural town of Price, Utah by Hargata Softworks.

View File

@@ -156,6 +156,12 @@
</div>
</div>
</div>
<div class="modal fade" data-bs-focus="false" id="genericRecordEditModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content" id="genericRecordEditModalContent">
</div>
</div>
</div>
<div class="modal fade" data-bs-focus="false" id="inputSuppliesModal" tabindex="-1" role="dialog" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content" id="inputSuppliesModalContent"></div>

View File

@@ -92,6 +92,7 @@
<ul class="table-context-menu dropdown-menu" style="display:none;">
<li><a class="context-menu-multiple context-menu-select-all dropdown-item" href="#" onclick="selectAllRows()">@translator.Translate(userLanguage, "Select All")</a></li>
<li><a class="context-menu-multiple context-menu-deselect-all dropdown-item" href="#" onclick="clearSelectedRows()">@translator.Translate(userLanguage, "Deselect All")</a></li>
<li><a class="context-menu-active-multiple dropdown-item" href="#" onclick="editMultipleRecords(selectedRow, 'RepairRecord')">@translator.Translate(userLanguage, "Edit Multiple")</a></li>
<li><hr class="context-menu-multiple dropdown-divider"></li>
<li><h6 class="dropdown-header">@translator.Translate(userLanguage, "Move To")</h6></li>
<li><a class="dropdown-item" href="#" onclick="moveRecords(selectedRow, 'RepairRecord', 'ServiceRecord')">@translator.Translate(userLanguage, "Service Records")</a></li>

View File

@@ -0,0 +1,55 @@
@using CarCareTracker.Helper
@inject IConfigHelper config
@inject ITranslationHelper translator
@model GenericRecordEditModel
@{
var userConfig = config.GetUserConfig(User);
var userLanguage = userConfig.UserLanguage;
}
<div class="modal-header">
<h5 class="modal-title">@translator.Translate(userLanguage,"Edit Multiple Records")</h5>
<button type="button" class="btn-close" onclick="hideGenericRecordModal()" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<div class="row">
<div class="col-md-6 col-12">
<label for="genericRecordDate">@translator.Translate(userLanguage,"Date")</label>
<div class="input-group">
<input type="text" id="genericRecordDate" class="form-control" placeholder="@translator.Translate(userLanguage,"(multiple)")">
<span class="input-group-text"><i class="bi bi-calendar-event"></i></span>
</div>
<label for="genericRecordMileage">@translator.Translate(userLanguage,"Odometer")</label>
<input type="number" inputmode="numeric" id="genericRecordMileage" class="form-control" placeholder="@translator.Translate(userLanguage,"(multiple)")">
<label for="genericRecordDescription">@translator.Translate(userLanguage, "Description")</label>
<input type="text" id="genericRecordDescription" class="form-control" placeholder="@translator.Translate(userLanguage,"(multiple)")">
<label for="genericRecordCost">@translator.Translate(userLanguage, "Cost")</label>
<input type="text" inputmode="decimal" id="genericRecordCost" class="form-control" placeholder="@translator.Translate(userLanguage,"(multiple)")">
<label for="genericRecordTag">@translator.Translate(userLanguage, "Tags(optional)")</label>
<select multiple class="form-select" id="genericRecordTag"></select>
</div>
<div class="col-md-6 col-12">
<label for="genericRecordNotes">@translator.Translate(userLanguage, "Notes(optional)")<a class="link-underline link-underline-opacity-0" onclick="showLinks(this)"><i class="bi bi-markdown ms-2"></i></a></label>
<textarea id="genericRecordNotes" class="form-control" rows="5"></textarea>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="hideGenericRecordModal()">@translator.Translate(userLanguage, "Cancel")</button>
<button type="button" class="btn btn-primary" onclick="saveGenericRecord()">@translator.Translate(userLanguage,"Edit")</button>
</div>
<script>
var recordsToEdit = [];
@foreach(int recordId in Model.RecordIds)
{
@:recordsToEdit.push(@recordId);
}
function getGenericRecordEditModelData(){
return {
dataType: decodeHTMLEntities('@Model.DataType.ToString()')
}
}
</script>

View File

@@ -93,6 +93,7 @@
<ul class="table-context-menu dropdown-menu" style="display:none;">
<li><a class="context-menu-multiple context-menu-select-all dropdown-item" href="#" onclick="selectAllRows()">@translator.Translate(userLanguage, "Select All")</a></li>
<li><a class="context-menu-multiple context-menu-deselect-all dropdown-item" href="#" onclick="clearSelectedRows()">@translator.Translate(userLanguage, "Deselect All")</a></li>
<li><a class="context-menu-active-multiple dropdown-item" href="#" onclick="editMultipleRecords(selectedRow, 'ServiceRecord')">@translator.Translate(userLanguage, "Edit Multiple")</a></li>
<li><hr class="context-menu-multiple dropdown-divider"></li>
<li><h6 class="dropdown-header">@translator.Translate(userLanguage, "Move To")</h6></li>
<li><a class="dropdown-item" href="#" onclick="moveRecords(selectedRow, 'ServiceRecord', 'RepairRecord')">@translator.Translate(userLanguage, "Repairs")</a></li>

View File

@@ -91,6 +91,7 @@
<ul class="table-context-menu dropdown-menu" style="display:none;">
<li><a class="context-menu-multiple context-menu-select-all dropdown-item" href="#" onclick="selectAllRows()">@translator.Translate(userLanguage, "Select All")</a></li>
<li><a class="context-menu-multiple context-menu-deselect-all dropdown-item" href="#" onclick="clearSelectedRows()">@translator.Translate(userLanguage, "Deselect All")</a></li>
<li><a class="context-menu-active-multiple dropdown-item" href="#" onclick="editMultipleRecords(selectedRow, 'UpgradeRecord')">@translator.Translate(userLanguage, "Edit Multiple")</a></li>
<li><hr class="context-menu-multiple dropdown-divider"></li>
<li><h6 class="dropdown-header">@translator.Translate(userLanguage, "Move To")</h6></li>
<li><a class="dropdown-item" href="#" onclick="moveRecords(selectedRow, 'UpgradeRecord', 'ServiceRecord')">@translator.Translate(userLanguage, "Service Records")</a></li>

View File

@@ -811,6 +811,83 @@ function detectRowTouchEndPremature(sender) {
rowTouchTimer = null;
}
}
function editMultipleRecords(ids) {
function editMultipleRecords(ids, dataType) {
$.post('/Vehicle/GetGenericRecordModal', { recordIds: ids, dataType: dataType }, function (data) {
if (data) {
$("#genericRecordEditModalContent").html(data);
initDatePicker($('#genericRecordDate'));
initTagSelector($("#genericRecordTag"));
$("#genericRecordEditModal").modal('show');
}
});
}
function hideGenericRecordModal() {
$("#genericRecordEditModal").modal('hide');
}
function saveGenericRecord() {
//get values
var formValues = getAndValidateGenericRecordValues();
//validate
if (formValues.hasError) {
errorToast("Please check the form data");
return;
}
var refreshDataCallBack;
switch (formValues.dataType) {
case "ServiceRecord":
refreshDataCallBack = getVehicleServiceRecords;
break;
case "RepairRecord":
refreshDataCallBack = getVehicleCollisionRecords;
break;
case "UpgradeRecord":
refreshDataCallBack = getVehicleUpgradeRecords;
break;
}
//save to db.
$.post('/Vehicle/EditMultipleRecords', { genericRecordEditModel: formValues }, function (data) {
if (data) {
successToast(formValues.recordIds.length > 1 ? "Records Updated" : "Record Updated.");
hideGenericRecordModal();
refreshDataCallBack(GetVehicleId().vehicleId);
} else {
errorToast(genericErrorMessage());
}
})
}
function getAndValidateGenericRecordValues() {
var genericDate = $("#genericRecordDate").val();
var genericMileage = $("#genericRecordMileage").val();
var genericMileageToParse = parseInt(globalParseFloat($("#genericRecordMileage").val())).toString();
var genericDescription = $("#genericRecordDescription").val();
var genericCost = $("#genericRecordCost").val();
var genericNotes = $("#genericRecordNotes").val();
var genericTags = $("#genericRecordTag").val();
//validation
var hasError = false;
if (genericMileage.trim() != '' && (isNaN(genericMileageToParse) || parseInt(genericMileageToParse) < 0)) {
hasError = true;
$("#genericRecordMileage").addClass("is-invalid");
} else {
$("#genericRecordMileage").removeClass("is-invalid");
}
if (genericCost.trim() != '' && !isValidMoney(genericCost)) {
hasError = true;
$("#genericRecordCost").addClass("is-invalid");
} else {
$("#genericRecordCost").removeClass("is-invalid");
}
return {
hasError: hasError,
dataType: getGenericRecordEditModelData().dataType,
recordIds: recordsToEdit,
editRecord: {
date: genericDate,
mileage: genericMileageToParse,
description: genericDescription,
cost: genericCost,
notes: genericNotes,
tags: genericTags
}
}
}