added an autocomplete component and implemented in permission grid
This commit is contained in:
		
							
								
								
									
										153
									
								
								Oqtane.Client/Modules/Controls/AutoComplete.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								Oqtane.Client/Modules/Controls/AutoComplete.razor
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,153 @@ | ||||
| @namespace Oqtane.Modules.Controls | ||||
| @inherits LocalizableComponent | ||||
|  | ||||
| <div class="app-autocomplete"> | ||||
| 	<input class="form-control" value="@Value" @oninput="OnInput" @onkeyup="OnKeyUp" placeholder="@Placeholder" autocomplete="off" /> | ||||
| 	@if (_results != null) | ||||
| 	{ | ||||
| 		<select class="form-select" style="position: relative;" value="@Value" size="@Rows" @onkeyup="OnKeyUp" @onchange="(e => OnChange(e))"> | ||||
| 			@if (_results.Any()) | ||||
| 			{ | ||||
| 				@foreach (var result in _results) | ||||
| 				{ | ||||
| 					if (result.Value == Value) | ||||
| 					{ | ||||
| 						<option selected>@result.Value</option> | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						<option>@result.Value</option> | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				<option disabled>No Results</option> | ||||
| 			} | ||||
| 		</select> | ||||
| 	} | ||||
| </div> | ||||
|  | ||||
| @code { | ||||
| 	Dictionary<string, string> _results; | ||||
|  | ||||
| 	[Parameter] | ||||
| 	public Func<string, Task<Dictionary<string, string>>> OnSearch { get; set; } // required - an async delegate method which accepts a filter string parameter and returns a dictionary | ||||
|  | ||||
| 	[Parameter] | ||||
| 	public int Characters { get; set; } = 3; // optional - number of characters before search is initiated | ||||
|  | ||||
| 	[Parameter] | ||||
| 	public int Rows { get; set; } = 3; // optional - number of result rows to display | ||||
|  | ||||
| 	[Parameter] | ||||
| 	public string Placeholder { get; set; } // optional - placeholder input text | ||||
|  | ||||
| 	[Parameter] | ||||
| 	public string Value { get; set; } // value of item selected | ||||
|  | ||||
| 	[Parameter] | ||||
| 	public string Key { get; set; } // key of item selected | ||||
|  | ||||
| 	private async Task OnInput(ChangeEventArgs e) | ||||
| 	{ | ||||
| 		Value = e.Value?.ToString(); | ||||
| 		if (Value?.Length >= Characters) | ||||
| 		{ | ||||
| 			_results = await OnSearch?.Invoke(Value); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			_results = null; | ||||
| 		} | ||||
| 		SetKey(); | ||||
| 	} | ||||
|  | ||||
| 	private async Task OnKeyUp(KeyboardEventArgs e) | ||||
| 	{ | ||||
| 		var index = -1; | ||||
| 		switch (e.Key) | ||||
| 		{ | ||||
| 			case "ArrowDown": | ||||
| 				if (_results == null) | ||||
| 				{ | ||||
| 					if (Value?.Length >= Characters) | ||||
| 					{ | ||||
| 						_results = await OnSearch?.Invoke(Value); | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					index = GetIndex(); | ||||
| 					if (index < _results.Count - 1) | ||||
| 					{ | ||||
| 						Value = _results.ElementAt(index + 1).Value; | ||||
| 						Key = _results.ElementAt(index + 1).Key; | ||||
| 					} | ||||
| 				} | ||||
| 				break; | ||||
| 			case "ArrowUp": | ||||
| 				index = GetIndex(); | ||||
| 				if (index > 0) | ||||
| 				{ | ||||
| 					Value = _results.ElementAt(index - 1).Value; | ||||
| 					Key = _results.ElementAt(index - 1).Key; | ||||
| 				} | ||||
| 				break; | ||||
| 			case "ArrowRight": | ||||
| 			case "Tab": | ||||
| 				_results = null; | ||||
| 				break; | ||||
| 			case "Enter": // note within a form the enter key submits the entire form | ||||
| 			case "NumpadEnter": | ||||
| 				_results = null; | ||||
| 				break; | ||||
| 			case "Escape": | ||||
| 				Value = ""; | ||||
| 				_results = null; | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private void OnChange(ChangeEventArgs e) | ||||
| 	{ | ||||
| 		Value = (string)e.Value; | ||||
| 		SetKey(); | ||||
| 		_results = null; | ||||
| 	} | ||||
|  | ||||
| 	private int GetIndex() | ||||
| 	{ | ||||
| 		if (_results != null) | ||||
| 		{ | ||||
| 			for (int index = 0; index < _results.Count; index++) | ||||
| 			{ | ||||
| 				if (_results.ElementAt(index).Value == Value) | ||||
| 				{ | ||||
| 					return index; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	private void SetKey() | ||||
| 	{ | ||||
| 		var index = GetIndex(); | ||||
| 		if (index != -1) | ||||
| 		{ | ||||
| 			Key = _results.ElementAt(index).Key; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			Key = ""; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public void Clear() | ||||
| 	{ | ||||
| 		Value = ""; | ||||
| 		Key = ""; | ||||
| 		_results = null; | ||||
| 	} | ||||
| } | ||||
| @ -2,6 +2,7 @@ | ||||
| @inherits ModuleControlBase | ||||
| @inject IRoleService RoleService | ||||
| @inject IUserService UserService | ||||
| @inject IUserRoleService UserRoleService | ||||
| @inject IStringLocalizer<PermissionGrid> Localizer | ||||
| @inject IStringLocalizer<SharedResources> SharedLocalizer | ||||
|  | ||||
| @ -77,23 +78,16 @@ | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|         <div class="col"> | ||||
|             <table class="table table-borderless"> | ||||
|                 <tbody> | ||||
|                     <tr> | ||||
|                         <td class="input-group"> | ||||
|                             <input type="text" name="Username" class="form-control" placeholder="@Localizer["Username.Enter"]" @bind="@_username" /> | ||||
|                             <button type="button" class="btn btn-primary" @onclick="AddUser">@SharedLocalizer["Add"]</button> | ||||
|                         </td> | ||||
|                     </tr> | ||||
|                 </tbody> | ||||
|             </table> | ||||
|             <br /> | ||||
|         <div class="col-11"> | ||||
| 			<AutoComplete OnSearch="GetUsers" Placeholder="@Localizer["Username.Enter"]" @ref="_user" /> | ||||
| 		</div> | ||||
| 		<div class="col-1"> | ||||
| 			<button type="button" class="btn btn-primary" @onclick="AddUser">@SharedLocalizer["Add"]</button> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|         <div class="col"> | ||||
|             <ModuleMessage Type="MessageType.Error" Message="@_message" /> | ||||
|             <ModuleMessage Type="MessageType.Warning" Message="@_message" /> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| @ -104,7 +98,7 @@ | ||||
| 	private List<Role> _roles; | ||||
| 	private List<PermissionString> _permissions; | ||||
| 	private List<User> _users = new List<User>(); | ||||
| 	private string _username = string.Empty; | ||||
| 	private AutoComplete _user; | ||||
| 	private string _message = string.Empty; | ||||
|  | ||||
| 	[Parameter] | ||||
| @ -191,25 +185,28 @@ | ||||
| 	private bool GetPermissionDisabled(string roleName) | ||||
| 		=> (roleName == RoleNames.Admin && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) ? true : false; | ||||
|  | ||||
| 	private async Task<Dictionary<string, string>> GetUsers(string filter) | ||||
| 	{ | ||||
| 		var users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered); | ||||
| 		return users.Where(item => item.User.DisplayName.Contains(filter, StringComparison.OrdinalIgnoreCase)) | ||||
| 			.ToDictionary(item => item.UserId.ToString(), item => item.User.DisplayName); | ||||
| 	} | ||||
|  | ||||
| 	private async Task AddUser() | ||||
| 	{ | ||||
| 		if (_users.Where(item => item.Username == _username).FirstOrDefault() == null) | ||||
| 		if (!string.IsNullOrEmpty(_user.Key)) | ||||
| 		{ | ||||
| 			try | ||||
| 			var user = await UserService.GetUserAsync(int.Parse(_user.Key), ModuleState.SiteId); | ||||
| 			if (user != null && !_users.Any(item => item.UserId == user.UserId)) | ||||
| 			{ | ||||
| 				var user = await UserService.GetUserAsync(_username, ModuleState.SiteId); | ||||
| 				if (user != null) | ||||
| 				{ | ||||
| 					_users.Add(user); | ||||
| 				} | ||||
| 			} | ||||
| 			catch | ||||
| 			{ | ||||
| 				_message = Localizer["Message.Username.DontExist"]; | ||||
| 				_users.Add(user); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		_username = string.Empty; | ||||
| 		else | ||||
| 		{ | ||||
| 			_message = Localizer["Message.Username.DontExist"]; | ||||
| 		} | ||||
| 		_user.Clear(); | ||||
| 	} | ||||
|  | ||||
| 	private void PermissionChanged(bool? value, string permissionName, string securityId) | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <root> | ||||
|   <!--  | ||||
|     Microsoft ResX Schema  | ||||
| @ -124,9 +124,9 @@ | ||||
|     <value>User</value> | ||||
|   </data> | ||||
|   <data name="Username.Enter" xml:space="preserve"> | ||||
|     <value>Enter Username</value> | ||||
|     <value>Enter User's Name</value> | ||||
|   </data> | ||||
|   <data name="Message.Username.DontExist" xml:space="preserve"> | ||||
|     <value>Username Does Not Exist</value> | ||||
|     <value>User Does Not Exist With Name Specified</value> | ||||
|   </data> | ||||
| </root> | ||||
		Reference in New Issue
	
	Block a user
	 Shaun Walker
					Shaun Walker