mirror of
https://github.com/hargata/lubelog.git
synced 2025-12-10 00:46:08 -06:00
front end for managing households
This commit is contained in:
parent
b98585006b
commit
a137fbaa52
@ -289,6 +289,24 @@ namespace CarCareTracker.Controllers
|
||||
var userName = User.Identity.Name;
|
||||
return PartialView("_AccountModal", new UserData() { EmailAddress = emailAddress, UserName = userName });
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetHouseholdModal()
|
||||
{
|
||||
var households = _userLogic.GetHouseholdForParentUserId(GetUserID());
|
||||
return PartialView("_UserHouseholdModal", households);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult RemoveUserFromHousehold(int userId)
|
||||
{
|
||||
var result = _userLogic.DeleteUserFromHousehold(GetUserID(), userId);
|
||||
return Json(result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult AddUserToHousehold(string username)
|
||||
{
|
||||
var result = _userLogic.AddUserToHousehold(GetUserID(), username);
|
||||
return Json(result);
|
||||
}
|
||||
[Authorize(Roles = nameof(UserData.IsRootUser))]
|
||||
[HttpGet]
|
||||
public IActionResult GetRootAccountInformationModal()
|
||||
|
||||
@ -118,7 +118,8 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
//get collaborators
|
||||
var collaborators = _userLogic.GetCollaboratorsForVehicle(vehicleId);
|
||||
viewModel.Collaborators = collaborators;
|
||||
var userCanModify = _userLogic.UserCanDirectlyEditVehicle(GetUserID(), vehicleId);
|
||||
viewModel.Collaborators = new VehicleCollaboratorViewModel { CanModifyCollaborators = userCanModify, Collaborators = collaborators};
|
||||
//get MPG per month.
|
||||
var mileageData = _gasHelper.GetGasRecordViewModels(gasRecords, userConfig.UseMPG, !vehicleData.IsElectric && userConfig.UseUKMPG);
|
||||
string preferredFuelMileageUnit = _config.GetUserConfig(User).PreferredGasMileageUnit;
|
||||
@ -176,6 +177,12 @@ namespace CarCareTracker.Controllers
|
||||
public IActionResult GetCollaboratorsForVehicle(int vehicleId)
|
||||
{
|
||||
var result = _userLogic.GetCollaboratorsForVehicle(vehicleId);
|
||||
var userCanModify = _userLogic.UserCanDirectlyEditVehicle(GetUserID(), vehicleId);
|
||||
var viewModel = new VehicleCollaboratorViewModel
|
||||
{
|
||||
Collaborators = result,
|
||||
CanModifyCollaborators = userCanModify
|
||||
};
|
||||
return PartialView("_Collaborators", result);
|
||||
}
|
||||
[TypeFilter(typeof(CollaboratorFilter))]
|
||||
|
||||
@ -217,10 +217,13 @@ namespace CarCareTracker.Controllers
|
||||
if (vehicleIds.Count() == 1)
|
||||
{
|
||||
//only one vehicle to manage
|
||||
if (_userLogic.UserCanEditVehicle(GetUserID(), vehicleIds.First()))
|
||||
if (_userLogic.UserCanDirectlyEditVehicle(GetUserID(), vehicleIds.First()))
|
||||
{
|
||||
viewModel.CommonCollaborators = _userLogic.GetCollaboratorsForVehicle(vehicleIds.First()).Select(x=>x.UserName).ToList();
|
||||
viewModel.VehicleIds.Add(vehicleIds.First());
|
||||
} else
|
||||
{
|
||||
viewModel.CanModifyCollaborators = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -228,11 +231,14 @@ namespace CarCareTracker.Controllers
|
||||
List<UserCollaborator> allCollaborators = new List<UserCollaborator>();
|
||||
foreach (int vehicleId in vehicleIds)
|
||||
{
|
||||
if (_userLogic.UserCanEditVehicle(GetUserID(), vehicleId))
|
||||
if (_userLogic.UserCanDirectlyEditVehicle(GetUserID(), vehicleId))
|
||||
{
|
||||
var vehicleCollaborators = _userLogic.GetCollaboratorsForVehicle(vehicleId);
|
||||
allCollaborators.AddRange(vehicleCollaborators);
|
||||
viewModel.VehicleIds.Add(vehicleId);
|
||||
} else
|
||||
{
|
||||
viewModel.CanModifyCollaborators = false;
|
||||
}
|
||||
}
|
||||
var groupedCollaborations = allCollaborators.GroupBy(x => x.UserName);
|
||||
|
||||
@ -12,8 +12,10 @@ namespace CarCareTracker.Logic
|
||||
OperationResponse AddCollaboratorToVehicle(int vehicleId, string username);
|
||||
List<Vehicle> FilterUserVehicles(List<Vehicle> results, int userId);
|
||||
bool UserCanEditVehicle(int userId, int vehicleId);
|
||||
bool UserCanDirectlyEditVehicle(int userId, int vehicleId);
|
||||
bool DeleteAllAccessToVehicle(int vehicleId);
|
||||
bool DeleteAllAccessToUser(int userId);
|
||||
List<UserHouseholdViewModel> GetHouseholdForParentUserId(int parentUserId);
|
||||
OperationResponse AddUserToHousehold(int parentUserId, string childUsername);
|
||||
bool DeleteUserFromHousehold(int parentUserId, int childUserId);
|
||||
bool DeleteAllHouseholdByParentUserId(int parentUserId);
|
||||
@ -162,6 +164,19 @@ namespace CarCareTracker.Logic
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public bool UserCanDirectlyEditVehicle(int userId, int vehicleId)
|
||||
{
|
||||
if (userId == -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var userAccess = _userAccess.GetUserAccessByVehicleAndUserId(userId, vehicleId);
|
||||
if (userAccess != null && userAccess.Id.UserId == userId && userAccess.Id.VehicleId == vehicleId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public bool DeleteAllAccessToVehicle(int vehicleId)
|
||||
{
|
||||
var result = _userAccess.DeleteAllAccessRecordsByVehicleId(vehicleId);
|
||||
@ -172,6 +187,22 @@ namespace CarCareTracker.Logic
|
||||
var result = _userAccess.DeleteAllAccessRecordsByUserId(userId);
|
||||
return result;
|
||||
}
|
||||
public List<UserHouseholdViewModel> GetHouseholdForParentUserId(int parentUserId)
|
||||
{
|
||||
var result = _userHouseholdData.GetUserHouseholdByParentUserId(parentUserId);
|
||||
var convertedResult = new List<UserHouseholdViewModel>();
|
||||
//convert useraccess to usercollaborator
|
||||
foreach (UserHousehold userHouseholdAccess in result)
|
||||
{
|
||||
var userCollaborator = new UserHouseholdViewModel
|
||||
{
|
||||
UserName = _userData.GetUserRecordById(userHouseholdAccess.Id.ChildUserId).UserName,
|
||||
UserHousehold = userHouseholdAccess.Id
|
||||
};
|
||||
convertedResult.Add(userCollaborator);
|
||||
}
|
||||
return convertedResult;
|
||||
}
|
||||
public OperationResponse AddUserToHousehold(int parentUserId, string childUsername)
|
||||
{
|
||||
//attempting to add to root user
|
||||
@ -184,6 +215,11 @@ namespace CarCareTracker.Logic
|
||||
if (existingUser.Id != default)
|
||||
{
|
||||
//user exists.
|
||||
//check if user is trying to add themselves
|
||||
if (parentUserId == existingUser.Id)
|
||||
{
|
||||
return OperationResponse.Failed("Cannot add yourself to your household");
|
||||
}
|
||||
//check if user already belongs to the household
|
||||
var householdAccess = _userHouseholdData.GetUserHouseholdByParentAndChildUserId(parentUserId, existingUser.Id);
|
||||
if (householdAccess != null && householdAccess.Id.ChildUserId == existingUser.Id && householdAccess.Id.ParentUserId == parentUserId)
|
||||
@ -192,7 +228,7 @@ namespace CarCareTracker.Logic
|
||||
}
|
||||
//check if a circular dependency will exist
|
||||
var circularHouseholdAccess = _userHouseholdData.GetUserHouseholdByParentAndChildUserId(existingUser.Id, parentUserId);
|
||||
if (circularHouseholdAccess != null && circularHouseholdAccess.Id.ChildUserId == existingUser.Id && circularHouseholdAccess.Id.ParentUserId == parentUserId)
|
||||
if (circularHouseholdAccess != null && circularHouseholdAccess.Id.ChildUserId == parentUserId && circularHouseholdAccess.Id.ParentUserId == existingUser.Id)
|
||||
{
|
||||
return OperationResponse.Failed("Circular dependency is not allowed");
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
public CostMakeUpForVehicle CostMakeUpForVehicle { get; set; } = new CostMakeUpForVehicle();
|
||||
public ReminderMakeUpForVehicle ReminderMakeUpForVehicle { get; set; } = new ReminderMakeUpForVehicle();
|
||||
public List<int> Years { get; set; } = new List<int>();
|
||||
public List<UserCollaborator> Collaborators { get; set; } = new List<UserCollaborator>();
|
||||
public VehicleCollaboratorViewModel Collaborators { get; set; } = new VehicleCollaboratorViewModel();
|
||||
public bool CustomWidgetsConfigured { get; set; } = false;
|
||||
public List<ImportMode> AvailableMetrics { get; set; } = new List<ImportMode>();
|
||||
public bool HasVehicleImageMap { get; set; } = false;
|
||||
|
||||
@ -5,5 +5,6 @@
|
||||
public List<int> VehicleIds { get; set; } = new List<int>();
|
||||
public List<string> CommonCollaborators { get; set; } = new List<string>();
|
||||
public List<string> PartialCollaborators { get; set; } = new List<string>();
|
||||
public bool CanModifyCollaborators { get; set; } = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Models/User/UserHouseholdViewModel.cs
Normal file
8
Models/User/UserHouseholdViewModel.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public class UserHouseholdViewModel
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public HouseholdAccess UserHousehold { get; set; }
|
||||
}
|
||||
}
|
||||
8
Models/User/VehicleCollaboratorViewModel.cs
Normal file
8
Models/User/VehicleCollaboratorViewModel.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public class VehicleCollaboratorViewModel
|
||||
{
|
||||
public List<UserCollaborator> Collaborators { get; set; }
|
||||
public bool CanModifyCollaborators { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@ -68,7 +68,11 @@
|
||||
<li>
|
||||
<button class="dropdown-item" onclick="showAccountInformationModal()"><i class="bi bi-person-gear me-2"></i>@translator.Translate(userLanguage, "Profile")</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="dropdown-item" onclick="showHouseholdModal()"><i class="bi bi-house me-2"></i>@translator.Translate(userLanguage, "Household")</button>
|
||||
</li>
|
||||
}
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li>
|
||||
<button class="dropdown-item" onclick="performLogOut()"><i class="bi bi-box-arrow-right me-2"></i>@translator.Translate(userLanguage, "Logout")</button>
|
||||
</li>
|
||||
@ -121,6 +125,9 @@
|
||||
<li>
|
||||
<button class="nav-link" onclick="showAccountInformationModal()"><span class="display-3 ms-2"><i class="bi bi-person-gear me-2"></i>@translator.Translate(userLanguage, "Profile")</span></button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="nav-link" onclick="showHouseholdModal()"><span class="display-3 ms-2"><i class="bi bi-house me-2"></i>@translator.Translate(userLanguage, "Household")</span></button>
|
||||
</li>
|
||||
}
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" onclick="performLogOut()"><span class="display-3 ms-2"><i class="bi bi-box-arrow-right me-2"></i>@translator.Translate(userLanguage,"Logout")</span></button>
|
||||
@ -159,6 +166,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" data-bs-focus="false" id="householdModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content" id="householdModalContent">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" data-bs-focus="false" id="attachmentPreviewModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-fullscreen" role="document">
|
||||
<div class="modal-content frosted" id="attachmentPreviewModalContent">
|
||||
|
||||
40
Views/Home/_UserHouseholdModal.cshtml
Normal file
40
Views/Home/_UserHouseholdModal.cshtml
Normal file
@ -0,0 +1,40 @@
|
||||
@using CarCareTracker.Helper
|
||||
@inject IConfigHelper config
|
||||
@inject ITranslationHelper translator
|
||||
@model List<UserHouseholdViewModel>
|
||||
@{
|
||||
var userConfig = config.GetUserConfig(User);
|
||||
var userLanguage = userConfig.UserLanguage;
|
||||
}
|
||||
<div class="modal-header">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="lead">@translator.Translate(userLanguage, "Manage Household")</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center ms-auto">
|
||||
<button onclick="addUserToHousehold()" class="btn btn-primary">
|
||||
<i class="bi bi-pencil-square me-2"></i>@translator.Translate(userLanguage, "Add User")
|
||||
</button>
|
||||
<button type="button" class="btn-close ms-2" onclick="hideHouseholdModal()" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table table-hover">
|
||||
<thead class="sticky-top">
|
||||
<tr class="d-flex">
|
||||
<th scope="col" class="col-10">@translator.Translate(userLanguage, "Username")</th>
|
||||
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Delete")</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tokenTable">
|
||||
@foreach(UserHouseholdViewModel viewModel in Model)
|
||||
{
|
||||
<tr class="d-flex">
|
||||
<td class="col-10">@viewModel.UserName</td>
|
||||
<td class="col-2">
|
||||
<button type="button" class="btn btn-danger" onclick="removeUserFromHousehold(@viewModel.UserHousehold.ChildUserId, this)"><i class="bi bi-trash"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -5,14 +5,17 @@
|
||||
var userConfig = config.GetUserConfig(User);
|
||||
var userLanguage = userConfig.UserLanguage;
|
||||
}
|
||||
@model List<UserCollaborator>
|
||||
@model VehicleCollaboratorViewModel
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="@(Model.CanModifyCollaborators ? "col-8" : "col-12")">
|
||||
<span class="lead">@translator.Translate(userLanguage, "Collaborators")</span>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<button onclick="addCollaborator()" class="btn btn-link btn-sm"><i class="bi bi-person-add"></i></button>
|
||||
</div>
|
||||
@if (Model.CanModifyCollaborators)
|
||||
{
|
||||
<div class="col-4">
|
||||
<button onclick="addCollaborator()" class="btn btn-link btn-sm"><i class="bi bi-person-add"></i></button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="row">
|
||||
<table class="table table-hover">
|
||||
@ -23,12 +26,12 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (UserCollaborator user in Model)
|
||||
@foreach (UserCollaborator user in Model.Collaborators)
|
||||
{
|
||||
<tr class="d-flex">
|
||||
<td class="col-8">@user.UserName</td>
|
||||
<td class="col-4">
|
||||
@if(User.Identity.Name != user.UserName)
|
||||
@if(User.Identity.Name != user.UserName && Model.CanModifyCollaborators)
|
||||
{
|
||||
<button onclick="deleteCollaborator(@user.UserVehicle.UserId, @user.UserVehicle.VehicleId)" class="btn btn-outline-danger btn-sm"><i class="bi bi-trash"></i></button>
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
<h5 class="modal-title" id="userCollaboratorsModalLabel">@translator.Translate(userLanguage, "Manage Collaborators")</h5>
|
||||
<button type="button" class="btn-close" onclick="hideCollaboratorsModal()" aria-label="Close"></button>
|
||||
</div>
|
||||
@if (Model.CanModifyCollaborators)
|
||||
{
|
||||
<div class="modal-body">
|
||||
@if (showTwoColumns)
|
||||
{
|
||||
@ -105,4 +107,17 @@
|
||||
@:vehiclesToEdit.push(@recordId);
|
||||
}
|
||||
adjustCollaboratorsModalSize(@showTwoColumns.ToString().ToLower());
|
||||
</script>
|
||||
</script>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="d-flex justify-content-center">
|
||||
<span class="lead text-center">@translator.Translate(userLanguage, "You don't have access to manage collaborators for these vehicles")</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -576,6 +576,52 @@ function sortVehicles(desc) {
|
||||
sortedRow.push($('.garage-item-add'))
|
||||
$('.vehiclesContainer').html(sortedRow);
|
||||
}
|
||||
function showHouseholdModal() {
|
||||
$.get('/Home/GetHouseholdModal', function (data) {
|
||||
$("#householdModalContent").html(data);
|
||||
$("#householdModal").modal('show');
|
||||
})
|
||||
}
|
||||
function hideHouseholdModal() {
|
||||
$("#householdModal").modal('hide');
|
||||
}
|
||||
function removeUserFromHousehold(userId) {
|
||||
$.post('/Home/RemoveUserFromHousehold', { userId: userId }, function (data) {
|
||||
if (data) {
|
||||
showHouseholdModal();
|
||||
} else {
|
||||
errorToast(genericErrorMessage())
|
||||
}
|
||||
})
|
||||
}
|
||||
function addUserToHousehold() {
|
||||
Swal.fire({
|
||||
title: 'Add User',
|
||||
html: `
|
||||
<input type="text" id="inputUserName" class="swal2-input" placeholder="Username" onkeydown="handleSwalEnter(event)">
|
||||
`,
|
||||
confirmButtonText: 'Add',
|
||||
focusConfirm: false,
|
||||
preConfirm: () => {
|
||||
const userName = $("#inputUserName").val();
|
||||
if (!userName) {
|
||||
Swal.showValidationMessage(`Please enter a username`);
|
||||
}
|
||||
return { userName }
|
||||
},
|
||||
}).then(function (result) {
|
||||
if (result.isConfirmed) {
|
||||
$.post('/Home/AddUserToHousehold', { username: result.value.userName }, function (data) {
|
||||
if (data.success) {
|
||||
showHouseholdModal();
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showAccountInformationModal() {
|
||||
$.get('/Home/GetUserAccountInformationModal', function (data) {
|
||||
$('#accountInformationModalContent').html(data);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user