mirror of https://github.com/abpframework/abp.git
committed by
GitHub
27 changed files with 497 additions and 55 deletions
Binary file not shown.
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class GetIdentityRolesInput : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class GetIdentityUsersInput : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
} |
|||
} |
|||
@ -1,11 +1,13 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public interface IIdentityRoleAppService : IAsyncCrudAppService<IdentityRoleDto, Guid, PagedAndSortedResultRequestDto, IdentityRoleCreateDto, IdentityRoleUpdateDto> |
|||
public interface IIdentityRoleAppService : IAsyncCrudAppService<IdentityRoleDto, Guid, GetIdentityRolesInput, IdentityRoleCreateDto, IdentityRoleUpdateDto> |
|||
{ |
|||
|
|||
//TODO: remove after a better design
|
|||
Task<List<IdentityRoleDto>> GetAllListAsync(); |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,11 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityUserCreateOrUpdateOutput |
|||
{ |
|||
public IdentityUserDto User { get; set; } |
|||
|
|||
public IdentityUserRoleDto[] Roles { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public class IdentityUserRoleDto |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public bool IsAssigned { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace Volo.Abp.Identity.Web.Areas.Identity.Models |
|||
{ |
|||
public class CreateOrUpdateUserViewModel |
|||
{ |
|||
public IdentityUserDto User { get; set; } |
|||
public IdentityUserRoleDto[] Roles { get; set; } |
|||
} |
|||
} |
|||
@ -1,34 +1,42 @@ |
|||
@model IReadOnlyList<Volo.Abp.Identity.IdentityUserDto> |
|||
|
|||
@section styles { |
|||
@section styles { |
|||
<!-- TODO: Use minified on production, normal in development --> |
|||
<link rel="stylesheet" type="text/css" href="~/modules/identity/libs/datatables/datatables.min.css" /> |
|||
<link rel="stylesheet" type="text/css" href="~/modules/identity/views/users/index.css" /> |
|||
} |
|||
|
|||
@section scripts { |
|||
<script type="text/javascript" src="~/modules/identity/libs/datatables/datatables.min.js"></script> |
|||
<script type="text/javascript" src="~/modules/identity/libs/datatables/datatables.js"></script> |
|||
<script type="text/javascript" src="~/modules/identity/views/users/index.js"></script> |
|||
} |
|||
|
|||
<h2>Users</h2> |
|||
<div class="row"> |
|||
<div class="col-md-6"> |
|||
<h2>Users</h2> |
|||
</div> |
|||
<div class="col-md-6 text-right"> |
|||
<!-- Button trigger modal --> |
|||
<button type="button" class="btn btn-primary create-user" data-toggle="modal"> |
|||
Create User |
|||
</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<table id="IdentityUsersTable"> |
|||
<table id="IdentityUsersTable" class="table table-striped table-bordered table-hover nowrap"> |
|||
<thead> |
|||
<tr> |
|||
<th>Username</th> |
|||
<th>Email Address</th> |
|||
<th>Phone Number</th> |
|||
</tr> |
|||
<tr> |
|||
<th>Actions</th> |
|||
<th>Username</th> |
|||
<th>Email Address</th> |
|||
<th>Phone Number</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
@foreach (var user in Model) |
|||
{ |
|||
<tr> |
|||
<td>@user.UserName</td> |
|||
<td>@user.Email</td> |
|||
<td>@(user.PhoneNumber ?? "-")</td> |
|||
</tr> |
|||
} |
|||
</tbody> |
|||
</table> |
|||
</table> |
|||
|
|||
<!-- Modal --> |
|||
<div class="modal fade" id="createUpdateUserModal" tabindex="-1" role="dialog" aria-labelledby="userModalLabel" aria-hidden="true"> |
|||
<div class="modal-dialog" role="document"> |
|||
<div class="modal-content"> |
|||
|
|||
</div> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,64 @@ |
|||
@model Volo.Abp.Identity.Web.Areas.Identity.Controllers.CreateOrUpdateUserViewModel |
|||
|
|||
<div class="modal-header"> |
|||
<h5 class="modal-title" id="userModalLabel">Create User</h5> |
|||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> |
|||
<span aria-hidden="true">×</span> |
|||
</button> |
|||
</div> |
|||
<div class="modal-body"> |
|||
<form id="createUserForm"> |
|||
<!-- Nav tabs --> |
|||
<ul class="nav nav-tabs" role="tablist"> |
|||
<li class="nav-item"> |
|||
<a class="nav-link active" data-toggle="tab" href="#userInformations" role="tab">User informations</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" data-toggle="tab" href="#roles" role="tab">Roles</a> |
|||
</li> |
|||
</ul> |
|||
|
|||
<!-- Tab panes --> |
|||
<div class="tab-content pt-3"> |
|||
|
|||
<div class="tab-pane active" id="userInformations" role="tabpanel"> |
|||
|
|||
<div class="form-group"> |
|||
<label for="userName">User name</label> |
|||
<input type="text" class="form-control" id="userName" name="UserName" placeholder="User name"> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label for="password">Password</label> |
|||
<input type="password" class="form-control" id="password" name="Password" placeholder="Password"> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label for="email">Email address</label> |
|||
<input type="email" class="form-control" id="email" name="Email" placeholder="Enter email"> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label for="phoneNumber">Phone number</label> |
|||
<input type="tel" class="form-control" id="phoneNumber" name="PhoneNumber" placeholder="Phone number"> |
|||
</div> |
|||
|
|||
</div> |
|||
<div class="tab-pane" id="roles" role="tabpanel"> |
|||
<div class="user-role-checkbox-list"> |
|||
@foreach (var role in Model.Roles) |
|||
{ |
|||
<div class="form-check"> |
|||
<label class="form-check-label"> |
|||
<input id="CreateUser_@(role.Name)" class="form-check-input" type="checkbox" name="@(role.Name)" value="true" @Html.Raw(role.IsAssigned ? "checked=\"checked\"" : "")> |
|||
@role.Name |
|||
</label> |
|||
</div> |
|||
} |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
</form> |
|||
</div> |
|||
<div class="modal-footer"> |
|||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> |
|||
<button type="button" class="btn btn-primary" id="btnCreateUserSave">Save</button> |
|||
</div> |
|||
@ -0,0 +1,62 @@ |
|||
@model Volo.Abp.Identity.Web.Areas.Identity.Controllers.CreateOrUpdateUserViewModel |
|||
|
|||
<div class="modal-header"> |
|||
<h5 class="modal-title" id="userModalLabel">Update User</h5> |
|||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> |
|||
<span aria-hidden="true">×</span> |
|||
</button> |
|||
</div> |
|||
<div class="modal-body"> |
|||
<form id="updateUserForm"> |
|||
<!-- Nav tabs --> |
|||
<ul class="nav nav-tabs" role="tablist"> |
|||
<li class="nav-item"> |
|||
<a class="nav-link active" data-toggle="tab" href="#userInformations" role="tab">User informations</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" data-toggle="tab" href="#roles" role="tab">Roles</a> |
|||
</li> |
|||
</ul> |
|||
|
|||
<!-- Tab panes --> |
|||
<div class="tab-content pt-3"> |
|||
|
|||
<div class="tab-pane active" id="userInformations" role="tabpanel"> |
|||
|
|||
<input type="hidden" name="Id" value="@Model.User.Id" /> |
|||
|
|||
<div class="form-group"> |
|||
<label for="userName">User name</label> |
|||
<input type="text" class="form-control" id="userName" name="UserName" placeholder="User name" value="@Model.User.UserName"> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label for="email">Email address</label> |
|||
<input type="email" class="form-control" id="email" name="Email" placeholder="Enter email" value="@Model.User.Email"> |
|||
</div> |
|||
<div class="form-group"> |
|||
<label for="phoneNumber">Phone number</label> |
|||
<input type="tel" class="form-control" id="phoneNumber" name="PhoneNumber" placeholder="Phone number" value="@Model.User.PhoneNumber"> |
|||
</div> |
|||
|
|||
</div> |
|||
<div class="tab-pane" id="roles" role="tabpanel"> |
|||
<div class="user-role-checkbox-list"> |
|||
@foreach (var role in Model.Roles) |
|||
{ |
|||
<div class="form-check"> |
|||
<label class="form-check-label"> |
|||
<input id="CreateUser_@(role.Name)" class="form-check-input" type="checkbox" name="@(role.Name)" value="true" @Html.Raw(role.IsAssigned ? "checked=\"checked\"" : "")> |
|||
@role.Name |
|||
</label> |
|||
</div> |
|||
} |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
</form> |
|||
</div> |
|||
<div class="modal-footer"> |
|||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> |
|||
<button type="button" class="btn btn-primary" id="btnUpdateUserSave">Save</button> |
|||
</div> |
|||
@ -1,3 +1,8 @@ |
|||
#IdentityUsersTable { |
|||
width: 100%; |
|||
.dataTable { |
|||
width: 100% !important; |
|||
border-spacing: 0 !important; |
|||
} |
|||
.table td, |
|||
.table th { |
|||
padding: 8px 10px; |
|||
} |
|||
@ -1,3 +1,155 @@ |
|||
$(function() { |
|||
$('#IdentityUsersTable').DataTable(); |
|||
}); |
|||
$(function () { |
|||
var _identityUserAppService = volo.abp.identity.identityUser; |
|||
|
|||
var dataTable = $('#IdentityUsersTable').DataTable({ |
|||
paging: true, |
|||
serverSide: true, |
|||
processing: true, |
|||
responsive: true, |
|||
order: [[1, "asc"]], |
|||
ajax: function (requestData, callback, settings) { |
|||
var inputFilter = {}; |
|||
|
|||
//set paging filters
|
|||
if (settings.oInit.paging) { |
|||
inputFilter = $.extend(inputFilter, { |
|||
maxResultCount: requestData.length, |
|||
skipCount: requestData.start |
|||
}); |
|||
} |
|||
|
|||
//set sorting filter
|
|||
if (requestData.order && requestData.order.length > 0) { |
|||
var orderingField = requestData.order[0]; |
|||
if (requestData.columns[orderingField.column].data) { |
|||
inputFilter.sorting = requestData.columns[orderingField.column].data + " " + orderingField.dir; |
|||
} |
|||
} |
|||
|
|||
//set searching filter
|
|||
if (requestData.search && requestData.search.value !== "") { |
|||
inputFilter.filter = requestData.search.value; |
|||
} |
|||
|
|||
if (callback) { |
|||
_identityUserAppService.getList(inputFilter).done(function (result) { |
|||
callback({ |
|||
recordsTotal: result.totalCount, |
|||
recordsFiltered: result.totalCount, |
|||
data: result.items |
|||
}); |
|||
}); |
|||
} |
|||
}, |
|||
columnDefs: [ |
|||
{ |
|||
targets: 0, |
|||
data: null, |
|||
orderable: false, |
|||
autoWidth: false, |
|||
defaultContent: '', |
|||
render: function (list, type, record, meta) { |
|||
return '<div class="dropdown">' + |
|||
'<button class="btn btn-primary btn-sm dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' + |
|||
'Actions' + |
|||
'</button>' + |
|||
'<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">' + |
|||
'<a class="dropdown-item update-user" href="#" data-id="' + record.id + '">Edit</a>' + |
|||
'<a class="dropdown-item delete-user" href="#" data-id="' + record.id + '">Delete</a>' + |
|||
'</div>' + |
|||
'</div>'; |
|||
} |
|||
}, |
|||
{ |
|||
targets: 1, |
|||
data: "userName" |
|||
}, |
|||
{ |
|||
targets: 2, |
|||
data: "email" |
|||
}, |
|||
{ |
|||
targets: 3, |
|||
data: "phoneNumber" |
|||
} |
|||
] |
|||
}); |
|||
|
|||
$('#IdentityUsersTable').on('click', '.update-user', function () { |
|||
var id = $(this).data('id'); |
|||
|
|||
$('#createUpdateUserModal').modal('show') |
|||
.find('.modal-content') |
|||
.load(abp.appPath + 'Identity/Users/Update', { id: id }); |
|||
}); |
|||
|
|||
$('#IdentityUsersTable').on('click', '.delete-user', function () { |
|||
var id = $(this).data('id'); |
|||
|
|||
if (confirm('Are you sure you want to delete?')) { |
|||
_identityUserAppService.delete(id).done(function () { |
|||
dataTable.ajax.reload(); |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
$('.create-user').click(function () { |
|||
$('#createUpdateUserModal').modal('show') |
|||
.find('.modal-content') |
|||
.load(abp.appPath + 'Identity/Users/Create'); |
|||
}); |
|||
|
|||
$('#createUpdateUserModal').on('click', '#btnCreateUserSave', function () { |
|||
var $createUserForm = $('#createUserForm'); |
|||
var user = $createUserForm.serializeFormToObject(); |
|||
user.RoleNames = findAssignedRoleNames(); |
|||
|
|||
_identityUserAppService.create(user).done(function () { |
|||
$('#createUpdateUserModal').modal('hide'); |
|||
dataTable.ajax.reload(); |
|||
}); |
|||
}); |
|||
|
|||
$('#createUpdateUserModal').on('click', '#btnUpdateUserSave', function () { |
|||
var $updateUserForm = $('#updateUserForm'); |
|||
var user = $updateUserForm.serializeFormToObject(); |
|||
user.RoleNames = findAssignedRoleNames(); |
|||
|
|||
_identityUserAppService.update(user.Id, user).done(function () { |
|||
$('#createUpdateUserModal').modal('hide'); |
|||
dataTable.ajax.reload(); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
|
|||
function findAssignedRoleNames() { |
|||
var assignedRoleNames = []; |
|||
|
|||
$(document).find('.user-role-checkbox-list input[type=checkbox]') |
|||
.each(function () { |
|||
if ($(this).is(':checked')) { |
|||
assignedRoleNames.push($(this).attr('name')); |
|||
} |
|||
}); |
|||
|
|||
return assignedRoleNames; |
|||
} |
|||
|
|||
//TODO: move to common script file
|
|||
$.fn.serializeFormToObject = function () { |
|||
//serialize to array
|
|||
var data = $(this).serializeArray(); |
|||
|
|||
//add also disabled items
|
|||
$(':disabled[name]', this) |
|||
.each(function () { |
|||
data.push({ name: this.name, value: $(this).val() }); |
|||
}); |
|||
|
|||
//map to object
|
|||
var obj = {}; |
|||
data.map(function (x) { obj[x.name] = x.value; }); |
|||
|
|||
return obj; |
|||
}; |
|||
|
|||
@ -1,3 +1,8 @@ |
|||
#IdentityUsersTable { |
|||
width: 100%; |
|||
.dataTable { |
|||
width: 100% !important; |
|||
border-spacing: 0 !important; |
|||
} |
|||
|
|||
.table td, .table th { |
|||
padding: 8px 10px; |
|||
} |
|||
|
|||
@ -1 +1 @@ |
|||
#IdentityUsersTable{width:100%;} |
|||
.dataTable{width:100% !important;border-spacing:0 !important;}.table td,.table th{padding:8px 10px;} |
|||
Loading…
Reference in new issue