Compare commits

...

6 Commits

Author SHA1 Message Date
Hargata Softworks
2f95e0445c
Merge pull request #1152 from hargata/Hargata/565
fix API endpoints
2025-11-13 16:53:49 -07:00
DESKTOP-T0O5CDB\DESK-555BD
c3110176f2 fix API endpoints 2025-11-13 16:50:59 -07:00
Hargata Softworks
e81c0616f7
Merge pull request #1151 from hargata/Hargata/565
fixed order.
2025-11-13 14:39:29 -07:00
DESKTOP-T0O5CDB\DESK-555BD
0aae215f08 fixed order. 2025-11-13 14:33:10 -07:00
Hargata Softworks
0f2a7c372b
Merge pull request #1150 from hargata/Hargata/565
rbac lol
2025-11-13 14:26:26 -07:00
DESKTOP-T0O5CDB\DESK-555BD
1032112885 rbac lol 2025-11-13 14:24:50 -07:00
8 changed files with 68 additions and 35 deletions

View File

@ -263,12 +263,12 @@ namespace CarCareTracker.Controllers
return Json(result);
}
}
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/planrecords/add")]
[Consumes("application/json")]
public IActionResult AddPlanRecordJson(int vehicleId, [FromBody] PlanRecordExportModel input) => AddPlanRecord(vehicleId, input);
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/planrecords/add")]
public IActionResult AddPlanRecord(int vehicleId, PlanRecordExportModel input)
@ -489,12 +489,12 @@ namespace CarCareTracker.Controllers
return Json(result);
}
}
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/servicerecords/add")]
[Consumes("application/json")]
public IActionResult AddServiceRecordJson(int vehicleId, [FromBody] GenericRecordExportModel input) => AddServiceRecord(vehicleId, input);
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/servicerecords/add")]
public IActionResult AddServiceRecord(int vehicleId, GenericRecordExportModel input)
@ -685,12 +685,12 @@ namespace CarCareTracker.Controllers
return Json(result);
}
}
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/repairrecords/add")]
[Consumes("application/json")]
public IActionResult AddRepairRecordJson(int vehicleId, [FromBody] GenericRecordExportModel input) => AddRepairRecord(vehicleId, input);
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/repairrecords/add")]
public IActionResult AddRepairRecord(int vehicleId, GenericRecordExportModel input)
@ -883,12 +883,12 @@ namespace CarCareTracker.Controllers
return Json(result);
}
}
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/upgraderecords/add")]
[Consumes("application/json")]
public IActionResult AddUpgradeRecordJson(int vehicleId, [FromBody] GenericRecordExportModel input) => AddUpgradeRecord(vehicleId, input);
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/upgraderecords/add")]
public IActionResult AddUpgradeRecord(int vehicleId, GenericRecordExportModel input)
@ -1115,12 +1115,12 @@ namespace CarCareTracker.Controllers
return Json(OperationResponse.Failed($"No Recurring Taxes Updated Due To Error: {ex.Message}"));
}
}
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/taxrecords/add")]
[Consumes("application/json")]
public IActionResult AddTaxRecordJson(int vehicleId, [FromBody] TaxRecordExportModel input) => AddTaxRecord(vehicleId, input);
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/taxrecords/add")]
public IActionResult AddTaxRecord(int vehicleId, TaxRecordExportModel input)
@ -1311,12 +1311,12 @@ namespace CarCareTracker.Controllers
return Json(result);
}
}
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/odometerrecords/add")]
[Consumes("application/json")]
public IActionResult AddOdometerRecordJson(int vehicleId, [FromBody] OdometerRecordExportModel input) => AddOdometerRecord(vehicleId, input);
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/odometerrecords/add")]
public IActionResult AddOdometerRecord(int vehicleId, OdometerRecordExportModel input)
@ -1500,12 +1500,12 @@ namespace CarCareTracker.Controllers
return Json(result);
}
}
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/gasrecords/add")]
[Consumes("application/json")]
public IActionResult AddGasRecordJson(int vehicleId, [FromBody] GasRecordExportModel input) => AddGasRecord(vehicleId, input);
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/gasrecords/add")]
public IActionResult AddGasRecord(int vehicleId, GasRecordExportModel input)
@ -1696,12 +1696,12 @@ namespace CarCareTracker.Controllers
return Json(results);
}
}
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/reminders/add")]
[Consumes("application/json")]
public IActionResult AddReminderRecordJson(int vehicleId, [FromBody] ReminderExportModel input) => AddReminderRecord(vehicleId, input);
[TypeFilter(typeof(CollaboratorFilter))]
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
[HttpPost]
[Route("/api/vehicle/reminders/add")]
public IActionResult AddReminderRecord(int vehicleId, ReminderExportModel input)

View File

@ -89,6 +89,10 @@ namespace CarCareTracker.Controllers
public IActionResult GetUserHouseholdModal(int userId)
{
var households = _userLogic.GetHouseholdForParentUserId(userId);
if (households.Any())
{
households = households.OrderBy(x => x.UserName).ToList();
}
var viewModel = new UserHouseholdAdminViewModel { Households = households, ParentUserId = userId };
return PartialView("_AdminUserHouseholdModal", viewModel);
}

View File

@ -293,6 +293,10 @@ namespace CarCareTracker.Controllers
public IActionResult GetHouseholdModal()
{
var households = _userLogic.GetHouseholdForParentUserId(GetUserID());
if (households.Any())
{
households = households.OrderBy(x => x.UserName).ToList();
}
return PartialView("_UserHouseholdModal", households);
}
[HttpPost]

View File

@ -199,6 +199,9 @@
$('#householdModal').modal('show');
})
}
function hideHouseholdModal(){
$('#householdModal').modal('hide');
}
function adminRemoveUserFromHousehold(parentUserId, childUserId){
$.post('/Admin/RemoveUserFromHousehold', {parentUserId: parentUserId, childUserId: childUserId}, function(data){
if (data) {
@ -210,11 +213,18 @@
});
}
function adminUpdateUserHousehold(parentUserId, childUserId, e){
let selectedChecks = $(e).closest('tr').find(':checked');
let permissions = selectedChecks.map((y, x) => {
return x.value;
});
$.post('/Admin/ModifyUserHouseholdPermissions', {parentUserId: parentUserId, childUserId: childUserId, permissions: permissions.toArray()}, function(data){
let selectedRole = $(e).val();
let permissions = [];
switch (selectedRole){
case 'editor':
permissions.push('Edit');
break;
case 'manager':
permissions.push('Edit');
permissions.push('Delete');
break;
}
$.post('/Admin/ModifyUserHouseholdPermissions', {parentUserId: parentUserId, childUserId: childUserId, permissions: permissions}, function(data){
if (data) {
successToast('Household Updated');
loadUserHousehold(parentUserId);

View File

@ -22,8 +22,7 @@
<thead class="sticky-top">
<tr class="d-flex">
<th scope="col" class="col-6">@translator.Translate(userLanguage, "Username")</th>
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Edit")</th>
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Delete")</th>
<th scope="col" class="col-4">@translator.Translate(userLanguage, "Role")</th>
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Remove")</th>
</tr>
</thead>
@ -32,8 +31,13 @@
{
<tr class="d-flex">
<td class="col-6">@viewModel.UserName</td>
<td class="col-2 d-flex align-items-center"><input class="form-check-input" type="checkbox" value="Edit" onchange="adminUpdateUserHousehold(@viewModel.UserHousehold.Id.ParentUserId, @viewModel.UserHousehold.Id.ChildUserId, this)" @(viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Edit) ? "checked" : "") /></td>
<td class="col-2 d-flex align-items-center"><input class="form-check-input" type="checkbox" value="Delete" onchange="adminUpdateUserHousehold(@viewModel.UserHousehold.Id.ParentUserId, @viewModel.UserHousehold.Id.ChildUserId, this)" @(viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Delete) ? "checked" : "") /></td>
<td class="col-4">
<select class="form-select" onchange="adminUpdateUserHousehold(@viewModel.UserHousehold.Id.ParentUserId, @viewModel.UserHousehold.Id.ChildUserId, this)">
<!option @(!viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Edit) && !viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Delete) ? "selected" : "") value="viewer">@translator.Translate(userLanguage, "Viewer")</!option>
<!option @(viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Edit) && !viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Delete) ? "selected" : "") value="editor">@translator.Translate(userLanguage, "Editor")</!option>
<!option @(viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Edit) && viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Delete) ? "selected" : "") value="manager">@translator.Translate(userLanguage, "Manager")</!option>
</select>
</td>
<td class="col-2">
<button type="button" class="btn btn-danger" onclick="adminRemoveUserFromHousehold(@viewModel.UserHousehold.Id.ParentUserId, @viewModel.UserHousehold.Id.ChildUserId)"><i class="bi bi-trash"></i></button>
</td>

View File

@ -22,8 +22,7 @@
<thead class="sticky-top">
<tr class="d-flex">
<th scope="col" class="col-6">@translator.Translate(userLanguage, "Username")</th>
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Edit")</th>
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Delete")</th>
<th scope="col" class="col-4">@translator.Translate(userLanguage, "Role")</th>
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Remove")</th>
</tr>
</thead>
@ -32,8 +31,13 @@
{
<tr class="d-flex">
<td class="col-6">@viewModel.UserName</td>
<td class="col-2 d-flex align-items-center"><input class="form-check-input" type="checkbox" value="Edit" onchange="modifyUserHousehold(@viewModel.UserHousehold.Id.ChildUserId, this)" @(viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Edit) ? "checked" : "") /></td>
<td class="col-2 d-flex align-items-center"><input class="form-check-input" type="checkbox" value="Delete" onchange="modifyUserHousehold(@viewModel.UserHousehold.Id.ChildUserId, this)" @(viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Delete) ? "checked" : "") /></td>
<td class="col-4">
<select class="form-select" onchange="modifyUserHousehold(@viewModel.UserHousehold.Id.ChildUserId, this)">
<!option @(!viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Edit) && !viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Delete) ? "selected" : "") value="viewer">@translator.Translate(userLanguage, "Viewer")</!option>
<!option @(viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Edit) && !viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Delete) ? "selected" : "") value="editor">@translator.Translate(userLanguage, "Editor")</!option>
<!option @(viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Edit) && viewModel.UserHousehold.Permissions.Contains(HouseholdPermission.Delete) ? "selected" : "") value="manager">@translator.Translate(userLanguage, "Manager")</!option>
</select>
</td>
<td class="col-2">
<button type="button" class="btn btn-danger" onclick="removeUserFromHousehold(@viewModel.UserHousehold.Id.ChildUserId, this)"><i class="bi bi-trash"></i></button>
</td>

File diff suppressed because one or more lines are too long

View File

@ -602,11 +602,18 @@ function removeUserFromHousehold(userId) {
})
}
function modifyUserHousehold(userId, e) {
let selectedChecks = $(e).closest('tr').find(':checked');
let permissions = selectedChecks.map((y, x) => {
return x.value;
});
$.post('/Home/ModifyUserHouseholdPermissions', { userId: userId, permissions: permissions.toArray() }, function (data) {
let selectedRole = $(e).val();
let permissions = [];
switch (selectedRole) {
case 'editor':
permissions.push('Edit');
break;
case 'manager':
permissions.push('Edit');
permissions.push('Delete');
break;
}
$.post('/Home/ModifyUserHouseholdPermissions', { userId: userId, permissions: permissions }, function (data) {
if (data) {
successToast('Household Updated');
showHouseholdModal();