Bug Fixes: enrolment, assignment and search order

This commit is contained in:
Gary Sharp
2014-04-22 13:55:46 +10:00
parent 74df073b29
commit 3cf6d5475d
22 changed files with 310 additions and 127 deletions
+10 -3
View File
@@ -362,7 +362,11 @@ namespace Disco.BI.DeviceBI
{ {
if (!authenticatedToken.Has(Claims.ComputerAccount)) if (!authenticatedToken.Has(Claims.ComputerAccount))
throw new EnrolSafeException(string.Format("Connection not correctly authenticated (SN: {0}; Auth User: {1})", Request.DeviceSerialNumber, authenticatedToken.User.UserId)); throw new EnrolSafeException(string.Format("Connection not correctly authenticated (SN: {0}; Auth User: {1})", Request.DeviceSerialNumber, authenticatedToken.User.UserId));
if (!authenticatedToken.User.UserId.Equals(string.Format("{0}$", Request.DeviceComputerName), System.StringComparison.OrdinalIgnoreCase))
if (domain == null)
domain = ActiveDirectory.Context.GetDomainByName(Request.DeviceDNSDomainName);
if (!authenticatedToken.User.UserId.Equals(string.Format(@"{0}\{1}$", domain.NetBiosName, Request.DeviceComputerName), System.StringComparison.OrdinalIgnoreCase))
throw new EnrolSafeException(string.Format("Connection not correctly authenticated (SN: {0}; Auth User: {1})", Request.DeviceSerialNumber, authenticatedToken.User.UserId)); throw new EnrolSafeException(string.Format("Connection not correctly authenticated (SN: {0}; Auth User: {1})", Request.DeviceSerialNumber, authenticatedToken.User.UserId));
} }
} }
@@ -418,10 +422,13 @@ namespace Disco.BI.DeviceBI
else else
EnrolmentLog.LogSessionDevice(sessionId, Request.DeviceSerialNumber, deviceModel.Id); EnrolmentLog.LogSessionDevice(sessionId, Request.DeviceSerialNumber, deviceModel.Id);
if (domain == null)
domain = ActiveDirectory.Context.GetDomainByName(Request.DeviceDNSDomainName);
RepoDevice = new Device RepoDevice = new Device
{ {
SerialNumber = Request.DeviceSerialNumber, SerialNumber = Request.DeviceSerialNumber,
DeviceDomainId = Request.DeviceComputerName, DeviceDomainId = string.Format(@"{0}\{1}", domain.NetBiosName, Request.DeviceComputerName),
DeviceProfile = deviceProfile, DeviceProfile = deviceProfile,
DeviceModel = deviceModel, DeviceModel = deviceModel,
AllowUnauthenticatedEnrol = false, AllowUnauthenticatedEnrol = false,
@@ -507,7 +514,7 @@ namespace Disco.BI.DeviceBI
} }
else else
{ {
RepoDevice.DeviceDomainId = adMachineAccount.Name; RepoDevice.DeviceDomainId = adMachineAccount.Id.Trim('$');
response.DeviceComputerName = adMachineAccount.Name; response.DeviceComputerName = adMachineAccount.Name;
response.DeviceDomainName = adMachineAccount.Domain.NetBiosName; response.DeviceDomainName = adMachineAccount.Domain.NetBiosName;
+7 -1
View File
@@ -2,6 +2,7 @@
using Disco.Data.Repository; using Disco.Data.Repository;
using Disco.Models.BI.Device; using Disco.Models.BI.Device;
using Disco.Models.Repository; using Disco.Models.Repository;
using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Users; using Disco.Services.Users;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -207,8 +208,13 @@ namespace Disco.BI.DeviceBI.Importing
csvAssignedUserId = record[4]; csvAssignedUserId = record[4];
if (string.IsNullOrWhiteSpace(csvAssignedUserId)) if (string.IsNullOrWhiteSpace(csvAssignedUserId))
csvAssignedUserId = null; // Not Assigned csvAssignedUserId = null; // Not Assigned
else if (csvAssignedUserId.Length > 50) else
{
if (csvAssignedUserId.Length > 50)
errors.Add("AssignedUserId", "The assigned user must be less than or equal to 50 characters"); errors.Add("AssignedUserId", "The assigned user must be less than or equal to 50 characters");
else if (!csvAssignedUserId.Contains('\\')) // Assume Primary Domain
csvAssignedUserId = string.Format(@"{0}\{1}", ActiveDirectory.Context.PrimaryDomain.NetBiosName, csvAssignedUserId);
}
if (csvFieldCount > 5) if (csvFieldCount > 5)
{ {
@@ -142,6 +142,9 @@ namespace Disco.BI.Extensions
Database.Devices.Add(d2); Database.Devices.Add(d2);
if (!string.IsNullOrEmpty(d.AssignedUserId)) if (!string.IsNullOrEmpty(d.AssignedUserId))
{ {
if (!d.AssignedUserId.Contains('\\'))
d.AssignedUserId = string.Format(@"{0}\{1}", ActiveDirectory.Context.PrimaryDomain.NetBiosName, d.AssignedUserId);
User u = UserService.GetUser(d.AssignedUserId, Database, true); User u = UserService.GetUser(d.AssignedUserId, Database, true);
d2.AssignDevice(Database, u); d2.AssignDevice(Database, u);
} }
@@ -9,11 +9,17 @@ namespace Disco.Models.Services.Searching
public class DeviceSearchResultItem : ISearchResultItem public class DeviceSearchResultItem : ISearchResultItem
{ {
private const string type = "Device"; private const string type = "Device";
private Lazy<string[]> LazyScoreValue;
public DeviceSearchResultItem()
{
this.LazyScoreValue = new Lazy<string[]>(BuildScoreValues, false);
}
public string Id { get; set; } public string Id { get; set; }
public string Type { get { return type; } } public string Type { get { return type; } }
public string Description { get { return string.Format("{0} ({1})", this.Id, this.ComputerName); } } public string Description { get { return string.Format("{0} ({1})", this.Id, this.ComputerName); } }
public string ScoreValue { get { return string.Format("{0} {1} {2} {3} {4}", this.Id, this.AssignedUserId != null ? this.AssignedUserId.Substring(0, this.AssignedUserId.IndexOf('\\')) : null, this.AssignedUserId, this.AssignedUserDisplayName, this.AssetNumber); } } public string[] ScoreValues { get { return LazyScoreValue.Value; } }
public string AssetNumber { get; set; } public string AssetNumber { get; set; }
public string AssignedUserDescription public string AssignedUserDescription
@@ -37,5 +43,28 @@ namespace Disco.Models.Services.Searching
public string DeviceProfileDescription { get; set; } public string DeviceProfileDescription { get; set; }
public int JobCount { get; set; } public int JobCount { get; set; }
public DateTime? DecommissionedDate { get; set; } public DateTime? DecommissionedDate { get; set; }
private string[] BuildScoreValues()
{
if (this.AssignedUserId == null)
{
return new string[] {
this.Id,
this.AssetNumber,
this.ComputerName
};
}
else
{
return new string[] {
this.Id,
this.AssetNumber,
this.ComputerName,
this.AssignedUserId.Substring(this.AssignedUserId.IndexOf('\\') + 1),
this.AssignedUserId,
this.AssignedUserDisplayName
};
}
}
} }
} }
@@ -11,6 +11,6 @@ namespace Disco.Models.Services.Searching
string Id { get; set; } string Id { get; set; }
string Type { get; } string Type { get; }
string Description { get; } string Description { get; }
string ScoreValue { get; } string[] ScoreValues { get; }
} }
} }
@@ -9,16 +9,43 @@ namespace Disco.Models.Services.Searching
public class JobSearchResultItem : ISearchResultItem public class JobSearchResultItem : ISearchResultItem
{ {
private const string type = "Job"; private const string type = "Job";
private Lazy<string[]> LazyScoreValue;
public JobSearchResultItem()
{
this.LazyScoreValue = new Lazy<string[]>(BuildScoreValues, false);
}
public virtual string Id { get; set; } public virtual string Id { get; set; }
public string Type { get { return type; } } public string Type { get { return type; } }
public string Description { get { return string.Format("{0} ({1}; {2})", this.Id, this.UserId, this.DeviceSerialNumber); } } public string Description { get { return string.Format("{0} ({1}; {2})", this.Id, this.UserId, this.DeviceSerialNumber); } }
public string ScoreValue { get { return string.Format("{0} {1} {2} {3} {4}", this.Id, this.UserId.Substring(0, this.UserId.IndexOf('\\')), this.UserId, this.DeviceSerialNumber, this.UserDisplayName); } } public string[] ScoreValues { get { return LazyScoreValue.Value; } }
public string DeviceSerialNumber { get; set; } public string DeviceSerialNumber { get; set; }
public string UserId { get; set; } public string UserId { get; set; }
public string UserFriendlyId { get; set; } public string UserFriendlyId { get; set; }
public string UserDisplayName { get; set; } public string UserDisplayName { get; set; }
private string[] BuildScoreValues()
{
if (this.UserId == null)
{
return new string[] {
this.Id,
this.DeviceSerialNumber
};
}
else
{
return new string[] {
this.Id,
this.UserId.Substring(this.UserId.IndexOf('\\') + 1),
this.UserId,
this.UserDisplayName,
this.DeviceSerialNumber
};
}
}
} }
} }
@@ -9,16 +9,31 @@ namespace Disco.Models.Services.Searching
public class UserSearchResultItem : ISearchResultItem public class UserSearchResultItem : ISearchResultItem
{ {
private const string type = "User"; private const string type = "User";
private Lazy<string[]> LazyScoreValue;
public UserSearchResultItem()
{
this.LazyScoreValue = new Lazy<string[]>(BuildScoreValues, false);
}
public string Id { get; set; } public string Id { get; set; }
public string Type { get { return type; } } public string Type { get { return type; } }
public string Description { get { return string.Format("{0} ({1})", this.DisplayName, this.Id); } } public string Description { get { return string.Format("{0} ({1})", this.DisplayName, this.Id); } }
public string ScoreValue { get { return string.Format("{0} {1} {2}", this.Id.Substring(0, this.Id.IndexOf('\\')), this.Id, this.DisplayName); } } public string[] ScoreValues { get { return LazyScoreValue.Value; } }
public int AssignedDevicesCount { get; set; } public int AssignedDevicesCount { get; set; }
public string DisplayName { get; set; } public string DisplayName { get; set; }
public string GivenName { get; set; } public string GivenName { get; set; }
public int JobCount { get; set; } public int JobCount { get; set; }
public string Surname { get; set; } public string Surname { get; set; }
private string[] BuildScoreValues()
{
return new string[] {
this.Id.Substring(this.Id.IndexOf('\\') + 1),
this.Id,
this.DisplayName
};
}
} }
} }
@@ -103,5 +103,20 @@ namespace Disco
return final_score; return final_score;
} }
/// <summary>
/// A fuzzy string search algorithm.
///
/// Based on: ScoreSharp (https://github.com/bltavares/scoresharp)
/// Based on: string_score from Joshaven Potter (https://github.com/joshaven/string_score)
///
/// MIT License
/// </summary>
public static double Score(this IEnumerable<string> Sources, string Test, double Fuzziness = 0)
{
return Sources
.Where(s => s != null)
.Select(s => s.Score(Test, Fuzziness))
.Average();
}
} }
} }
@@ -65,7 +65,7 @@ namespace Disco.Services.Interop.ActiveDirectory
System.DateTime? lastLogon = null; System.DateTime? lastLogon = null;
if (!string.IsNullOrEmpty(Device.DeviceDomainId)) if (!string.IsNullOrEmpty(Device.DeviceDomainId) && Device.DeviceDomainId.Contains('\\'))
{ {
var context = ActiveDirectory.Context; var context = ActiveDirectory.Context;
var deviceSamAccountName = UserExtensions.SplitUserId(Device.DeviceDomainId).Item2 + "$"; var deviceSamAccountName = UserExtensions.SplitUserId(Device.DeviceDomainId).Item2 + "$";
@@ -243,9 +243,18 @@ namespace Disco.Services
return items; return items;
} }
public static void Fill(this JobTableModel model, DiscoDataContext Database, IQueryable<Job> Jobs, bool FilterAuthorization) public static JobTableModel Fill(this JobTableModel model, DiscoDataContext Database, IQueryable<Job> Jobs, bool FilterAuthorization)
{ {
model.Items = model.DetermineItems(Database, Jobs, FilterAuthorization); model.Items = model.DetermineItems(Database, Jobs, FilterAuthorization);
return model;
}
public static JobTableModel Score(this JobTableModel model, string Test, double Fuzziness = 0)
{
model.Items = model.Items.OrderByDescending(i => i.ScoreValues.Score(Test)).ToList();
return model;
} }
public static double? SlaPrecentageRemaining(this IEnumerable<JobTableStatusQueueItemModel> queueItems) public static double? SlaPrecentageRemaining(this IEnumerable<JobTableStatusQueueItemModel> queueItems)
+67 -26
View File
@@ -16,7 +16,7 @@ namespace Disco.Services.Searching
{ {
#region Jobs #region Jobs
public static List<JobSearchResultItem> SearchJobs(DiscoDataContext Database, string Term, int? LimitCount = null) public static List<JobSearchResultItem> SearchJobs(DiscoDataContext Database, string Term, int? LimitCount = ActiveDirectory.DefaultSearchResultLimit)
{ {
int termInt = default(int); int termInt = default(int);
@@ -56,10 +56,10 @@ namespace Disco.Services.Searching
DeviceSerialNumber = i.DeviceSerialNumber, DeviceSerialNumber = i.DeviceSerialNumber,
UserId = i.UserId, UserId = i.UserId,
UserDisplayName = i.UserDisplayName UserDisplayName = i.UserDisplayName
}).ToList(); }).OrderByDescending(i => i.ScoreValues.Score(Term)).ToList();
} }
public static JobTableModel SearchJobsTable(DiscoDataContext Database, string Term, int? LimitCount = null, bool IncludeJobStatus = true, bool SearchDetails = false) public static JobTableModel SearchJobsTable(DiscoDataContext Database, string Term, int? LimitCount = ActiveDirectory.DefaultSearchResultLimit, bool IncludeJobStatus = true, bool SearchDetails = false)
{ {
int termInt = default(int); int termInt = default(int);
@@ -126,8 +126,9 @@ namespace Disco.Services.Searching
if (LimitCount.HasValue) if (LimitCount.HasValue)
query = query.Take(LimitCount.Value); query = query.Take(LimitCount.Value);
JobTableModel model = new JobTableModel() { ShowStatus = IncludeJobStatus }; JobTableModel model = new JobTableModel() { ShowStatus = IncludeJobStatus }
model.Fill(Database, query, true); .Fill(Database, query, true)
.Score(Term);
return model; return model;
} }
@@ -139,25 +140,34 @@ namespace Disco.Services.Searching
#endregion #endregion
#region Users #region Users
public static List<UserSearchResultItem> SearchUsers(DiscoDataContext Database, string Term, int? LimitCount = null) public static List<UserSearchResultItem> SearchUsersUpstream(DiscoDataContext Database, string Term, bool PersistResults, int? LimitCount = ActiveDirectory.DefaultSearchResultLimit)
{
return UserService.SearchUsers(Database, Term, PersistResults, LimitCount).Select(u => new UserSearchResultItem()
{
Id = u.UserId,
Surname = u.Surname,
GivenName = u.GivenName,
DisplayName = u.DisplayName,
AssignedDevicesCount = 0,
JobCount = 0
}).OrderByDescending(i => i.ScoreValues.Score(Term)).ToList();
}
public static List<UserSearchResultItem> SearchUsers(DiscoDataContext Database, string Term, bool PersistResults, int? LimitCount = ActiveDirectory.DefaultSearchResultLimit)
{ {
if (string.IsNullOrWhiteSpace(Term) || Term.Length < 2) if (string.IsNullOrWhiteSpace(Term) || Term.Length < 2)
throw new ArgumentException("Search Term must contain at least two characters", "Term"); throw new ArgumentException("Search Term must contain at least two characters", "Term");
// Search Active Directory & Import Relevant Users // Search Active Directory
UserService.SearchUsers(Database, Term); var adResults = SearchUsersUpstream(Database, Term, PersistResults, LimitCount);
var matches = Database.Users.Where(u => // Search Database
var dbResults = Database.Users.Where(u =>
u.UserId.Contains(Term) || u.UserId.Contains(Term) ||
u.Surname.Contains(Term) || u.Surname.Contains(Term) ||
u.GivenName.Contains(Term) || u.GivenName.Contains(Term) ||
u.DisplayName.Contains(Term) u.DisplayName.Contains(Term)
); ).Select(u => new UserSearchResultItem()
if (LimitCount.HasValue)
matches = matches.Take(LimitCount.Value);
return matches.Select(u => new UserSearchResultItem()
{ {
Id = u.UserId, Id = u.UserId,
Surname = u.Surname, Surname = u.Surname,
@@ -166,21 +176,49 @@ namespace Disco.Services.Searching
AssignedDevicesCount = u.DeviceUserAssignments.Where(dua => !dua.UnassignedDate.HasValue).Count(), AssignedDevicesCount = u.DeviceUserAssignments.Where(dua => !dua.UnassignedDate.HasValue).Count(),
JobCount = u.Jobs.Count() JobCount = u.Jobs.Count()
}).ToList(); }).ToList();
IEnumerable<UserSearchResultItem> results;
if (PersistResults)
{
// AD Search persisted the results to the database
results = dbResults;
}
else
{
var adResultsIndexed = adResults.ToDictionary(u => u.Id, StringComparer.OrdinalIgnoreCase);
var dbResultsIndexed = dbResults.ToDictionary(u => u.Id, StringComparer.OrdinalIgnoreCase);
// Update DB Results
dbResults.ForEach(u =>
{
UserSearchResultItem adResult;
if (adResultsIndexed.TryGetValue(u.Id, out adResult))
{
u.Surname = adResult.Surname;
u.GivenName = adResult.GivenName;
u.DisplayName = adResult.DisplayName;
}
});
// Add AD Results
var adResultsAdditional = adResults.Where(u => !dbResultsIndexed.ContainsKey(u.Id));
// Join AD & DB Results
results = adResultsAdditional.Concat(dbResults);
} }
public static List<User> SearchUsersUpstream(string Term, int? LimitCount = null) results = results.OrderByDescending(i => i.ScoreValues.Score(Term));
{
IEnumerable<ADUserAccount> matches = ActiveDirectory.SearchADUserAccounts(Term, Quick: true);
if (LimitCount.HasValue) if (LimitCount.HasValue)
matches = matches.Take(LimitCount.Value); results = results.Take(LimitCount.Value);
return matches.Select(m => m.ToRepositoryUser()).ToList(); return results.ToList();
} }
#endregion #endregion
#region Devices #region Devices
public static List<DeviceSearchResultItem> SearchDevices(DiscoDataContext Database, string Term, int? LimitCount = null, bool SearchDetails = false) public static List<DeviceSearchResultItem> SearchDevices(DiscoDataContext Database, string Term, int? LimitCount = ActiveDirectory.DefaultSearchResultLimit, bool SearchDetails = false)
{ {
IQueryable<Device> query; IQueryable<Device> query;
@@ -207,23 +245,26 @@ namespace Disco.Services.Searching
Term.Contains(d.SerialNumber)); Term.Contains(d.SerialNumber));
} }
return query.ToDeviceSearchResultItems(LimitCount); return query
.ToDeviceSearchResultItems(LimitCount)
.OrderByDescending(i => i.ScoreValues.Score(Term))
.ToList();
} }
public static List<DeviceSearchResultItem> SearchDeviceModel(DiscoDataContext Database, int DeviceModelId, int? LimitCount = null) public static List<DeviceSearchResultItem> SearchDeviceModel(DiscoDataContext Database, int DeviceModelId, int? LimitCount = ActiveDirectory.DefaultSearchResultLimit)
{ {
return Database.Devices.Where(d => d.DeviceModelId == DeviceModelId).ToDeviceSearchResultItems(LimitCount); return Database.Devices.Where(d => d.DeviceModelId == DeviceModelId).ToDeviceSearchResultItems(LimitCount);
} }
public static List<DeviceSearchResultItem> SearchDeviceProfile(DiscoDataContext Database, int DeviceProfileId, int? LimitCount = null) public static List<DeviceSearchResultItem> SearchDeviceProfile(DiscoDataContext Database, int DeviceProfileId, int? LimitCount = ActiveDirectory.DefaultSearchResultLimit)
{ {
return Database.Devices.Where(d => d.DeviceProfileId == DeviceProfileId).ToDeviceSearchResultItems(LimitCount); return Database.Devices.Where(d => d.DeviceProfileId == DeviceProfileId).ToDeviceSearchResultItems(LimitCount);
} }
public static List<DeviceSearchResultItem> SearchDeviceBatch(DiscoDataContext Database, int DeviceBatchId, int? LimitCount = null) public static List<DeviceSearchResultItem> SearchDeviceBatch(DiscoDataContext Database, int DeviceBatchId, int? LimitCount = ActiveDirectory.DefaultSearchResultLimit)
{ {
return Database.Devices.Where(d => d.DeviceBatchId == DeviceBatchId).ToDeviceSearchResultItems(LimitCount); return Database.Devices.Where(d => d.DeviceBatchId == DeviceBatchId).ToDeviceSearchResultItems(LimitCount);
} }
private static List<DeviceSearchResultItem> ToDeviceSearchResultItems(this IQueryable<Device> Query, int? LimitCount = null) private static List<DeviceSearchResultItem> ToDeviceSearchResultItems(this IQueryable<Device> Query, int? LimitCount = ActiveDirectory.DefaultSearchResultLimit)
{ {
if (LimitCount.HasValue) if (LimitCount.HasValue)
Query = Query.Take(LimitCount.Value); Query = Query.Take(LimitCount.Value);
+8 -3
View File
@@ -205,10 +205,13 @@ namespace Disco.Services.Users
Cache.FlushCache(); Cache.FlushCache();
} }
internal static IEnumerable<ADUserAccount> SearchUsers(DiscoDataContext Database, string Term) internal static List<User> SearchUsers(DiscoDataContext Database, string Term, bool PersistResults, int? LimitCount = ActiveDirectory.DefaultSearchResultLimit)
{ {
var adImportedUsers = ActiveDirectory.SearchADUserAccounts(Term, Quick: true); var adImportedUsers = ActiveDirectory.SearchADUserAccounts(Term, Quick: true, ResultLimit: LimitCount).Select(adU => adU.ToRepositoryUser()).ToList();
foreach (var adU in adImportedUsers.Select(adU => adU.ToRepositoryUser()))
if (PersistResults)
{
foreach (var adU in adImportedUsers)
{ {
var existingUser = Database.Users.Find(adU.UserId); var existingUser = Database.Users.Find(adU.UserId);
if (existingUser != null) if (existingUser != null)
@@ -218,6 +221,8 @@ namespace Disco.Services.Users
Database.SaveChanges(); Database.SaveChanges();
UserService.InvalidateCachedUser(adU.UserId); UserService.InvalidateCachedUser(adU.UserId);
} }
}
return adImportedUsers; return adImportedUsers;
} }
@@ -114,8 +114,16 @@ namespace Disco.Web.Areas.API.Controllers
} }
[DiscoAuthorize(Claims.Device.Actions.AssignUser)] [DiscoAuthorize(Claims.Device.Actions.AssignUser)]
public virtual ActionResult UpdateAssignedUserId(string id, string AssignedUserId = null, bool redirect = false) public virtual ActionResult UpdateAssignedUserId(string id, string AssignedUserId = null, string AssignedUserDomain = null, bool redirect = false)
{ {
if (AssignedUserId != null && !AssignedUserId.Contains('\\'))
{
if (string.IsNullOrWhiteSpace(AssignedUserDomain))
AssignedUserId = string.Format(@"{0}\{1}", ActiveDirectory.Context.PrimaryDomain.NetBiosName, AssignedUserId);
else
AssignedUserId = string.Format(@"{0}\{1}", AssignedUserDomain, AssignedUserId);
}
return Update(id, pAssignedUserId, AssignedUserId, redirect); return Update(id, pAssignedUserId, AssignedUserId, redirect);
} }
@@ -361,6 +369,9 @@ namespace Disco.Web.Areas.API.Controllers
[DiscoAuthorize(Claims.Device.Show)] [DiscoAuthorize(Claims.Device.Show)]
public virtual ActionResult LastNetworkLogonDate(string id) public virtual ActionResult LastNetworkLogonDate(string id)
{ {
if (string.IsNullOrWhiteSpace(id))
throw new ArgumentNullException("id", "The Device Serial Number is required");
var device = Database.Devices.Find(id); var device = Database.Devices.Find(id);
if (device == null) if (device == null)
{ {
@@ -2,6 +2,7 @@
using Disco.BI.Extensions; using Disco.BI.Extensions;
using Disco.Models.Repository; using Disco.Models.Repository;
using Disco.Services.Authorization; using Disco.Services.Authorization;
using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Users; using Disco.Services.Users;
using Disco.Services.Web; using Disco.Services.Web;
using System; using System;
@@ -287,7 +288,7 @@ namespace Disco.Web.Areas.API.Controllers
} }
[DiscoAuthorize(Claims.Config.DocumentTemplate.UndetectedPages)] [DiscoAuthorize(Claims.Config.DocumentTemplate.UndetectedPages)]
public virtual ActionResult ImporterUndetectedDataIdLookup(string id, string term, int limitCount = 20) public virtual ActionResult ImporterUndetectedDataIdLookup(string id, string term, int limitCount = ActiveDirectory.DefaultSearchResultLimit)
{ {
if (!string.IsNullOrEmpty(id) && !string.IsNullOrWhiteSpace(term)) if (!string.IsNullOrEmpty(id) && !string.IsNullOrWhiteSpace(term))
{ {
@@ -330,7 +331,7 @@ namespace Disco.Web.Areas.API.Controllers
results = Disco.Services.Searching.Search.SearchJobsTable(Database, term, limitCount, false).Items.Select(sr => Models.DocumentTemplate.ImporterUndetectedDataIdLookupModel.FromSearchResultItem(sr)).ToArray(); results = Disco.Services.Searching.Search.SearchJobsTable(Database, term, limitCount, false).Items.Select(sr => Models.DocumentTemplate.ImporterUndetectedDataIdLookupModel.FromSearchResultItem(sr)).ToArray();
break; break;
case DocumentTemplate.DocumentTemplateScopes.User: case DocumentTemplate.DocumentTemplateScopes.User:
results = Disco.Services.Searching.Search.SearchUsers(Database, term, limitCount).Select(sr => Models.DocumentTemplate.ImporterUndetectedDataIdLookupModel.FromSearchResultItem(sr)).ToArray(); results = Disco.Services.Searching.Search.SearchUsers(Database, term, false, limitCount).Select(sr => Models.DocumentTemplate.ImporterUndetectedDataIdLookupModel.FromSearchResultItem(sr)).ToArray();
break; break;
default: default:
results = null; results = null;
@@ -1,5 +1,6 @@
using Disco.Models.Services.Searching; using Disco.Models.Services.Searching;
using Disco.Services.Authorization; using Disco.Services.Authorization;
using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Searching; using Disco.Services.Searching;
using Disco.Services.Web; using Disco.Services.Web;
using System; using System;
@@ -13,7 +14,7 @@ namespace Disco.Web.Areas.API.Controllers
public partial class SearchController : AuthorizedDatabaseController public partial class SearchController : AuthorizedDatabaseController
{ {
[DiscoAuthorizeAny(Claims.Job.Search, Claims.Device.Search, Claims.User.Search)] [DiscoAuthorizeAny(Claims.Job.Search, Claims.Device.Search, Claims.User.Search)]
public virtual ActionResult QuickQuery(string Term, int Limit = 15) public virtual ActionResult QuickQuery(string Term, int Limit = ActiveDirectory.DefaultSearchResultLimit)
{ {
if (string.IsNullOrWhiteSpace(Term)) if (string.IsNullOrWhiteSpace(Term))
throw new ArgumentNullException("Term", "The search query term is required"); throw new ArgumentNullException("Term", "The search query term is required");
@@ -36,20 +37,35 @@ namespace Disco.Web.Areas.API.Controllers
break; break;
case '@': // User Only case '@': // User Only
if (Authorization.Has(Claims.User.Search)) if (Authorization.Has(Claims.User.Search))
results = results.Concat(Search.SearchUsers(Database, Term.Substring(1), Limit)); results = results.Concat(Search.SearchUsers(Database, Term.Substring(1), false, Limit));
break; break;
default: // Search All default: // Search All
if (Authorization.Has(Claims.Job.Search)) if (Authorization.Has(Claims.Job.Search))
results = results.Concat(Search.SearchJobs(Database, Term, Limit)); results = results.Concat(Search.SearchJobs(Database, Term, Limit));
if (Authorization.Has(Claims.User.Search)) if (Authorization.Has(Claims.User.Search))
results = results.Concat(Search.SearchUsers(Database, Term, Limit)); results = results.Concat(Search.SearchUsers(Database, Term, false, Limit));
if (Authorization.Has(Claims.Device.Search)) if (Authorization.Has(Claims.Device.Search))
results = results.Concat(Search.SearchDevices(Database, Term, Limit)); results = results.Concat(Search.SearchDevices(Database, Term, Limit));
break; break;
} }
results = results.OrderByDescending(i => i.ScoreValue.Score(Term)).Take(Limit); results = results.OrderByDescending(i => i.ScoreValues.Score(Term)).Take(Limit);
return Json(results, JsonRequestBehavior.AllowGet);
}
[DiscoAuthorize(Claims.User.Search)]
public virtual ActionResult UsersUpstream(string Term, int Limit = 15)
{
if (string.IsNullOrWhiteSpace(Term))
throw new ArgumentNullException("Term", "The search query term is required");
if (Term.Length < 2)
throw new ArgumentException("The search query term must be at least two characters", "Term");
if (Limit < 1)
throw new ArgumentException("The search query limit cannot be less than 1", "Limit");
var results = Search.SearchUsersUpstream(Database, Term, false, Limit);
return Json(results, JsonRequestBehavior.AllowGet); return Json(results, JsonRequestBehavior.AllowGet);
} }
@@ -12,12 +12,6 @@ namespace Disco.Web.Areas.API.Controllers
{ {
public partial class UserController : AuthorizedDatabaseController public partial class UserController : AuthorizedDatabaseController
{ {
[DiscoAuthorize(Claims.User.Search)]
public virtual ActionResult UpstreamUsers(string term)
{
return Json(Disco.Services.Searching.Search.SearchUsersUpstream(term), JsonRequestBehavior.AllowGet);
}
#region User Attachements #region User Attachements
[DiscoAuthorize(Claims.User.ShowAttachments)] [DiscoAuthorize(Claims.User.ShowAttachments)]
+8 -8
View File
@@ -62,13 +62,13 @@ namespace Disco.Web.Controllers
return View(m); return View(m);
} }
if (Authorization.Has(Claims.Job.Search)) if (Authorization.Has(Claims.Job.Search))
m.Jobs = Services.Searching.Search.SearchJobsTable(Database, term, null, true, searchDetails); m.Jobs = Services.Searching.Search.SearchJobsTable(Database, term, LimitCount: null, IncludeJobStatus: true, SearchDetails: searchDetails);
if (Authorization.Has(Claims.Device.Search)) if (Authorization.Has(Claims.Device.Search))
m.Devices = Services.Searching.Search.SearchDevices(Database, term, null, searchDetails); m.Devices = Services.Searching.Search.SearchDevices(Database, term, LimitCount: null, SearchDetails: searchDetails);
if (Authorization.Has(Claims.User.Search)) if (Authorization.Has(Claims.User.Search))
m.Users = Services.Searching.Search.SearchUsers(Database, term); m.Users = Services.Searching.Search.SearchUsers(Database, term, true, LimitCount: null);
} }
else else
{ {
@@ -83,7 +83,7 @@ namespace Disco.Web.Controllers
if (vm != null) if (vm != null)
{ {
m.FriendlyTerm = string.Format("Device Model: {0}", vm.ToString()); m.FriendlyTerm = string.Format("Device Model: {0}", vm.ToString());
m.Devices = Services.Searching.Search.SearchDeviceModel(Database, vm.Id); m.Devices = Services.Searching.Search.SearchDeviceModel(Database, vm.Id, LimitCount: null);
break; break;
} }
} }
@@ -100,7 +100,7 @@ namespace Disco.Web.Controllers
if (dp != null) if (dp != null)
{ {
m.FriendlyTerm = string.Format("Device Profile: {0}", dp.ToString()); m.FriendlyTerm = string.Format("Device Profile: {0}", dp.ToString());
m.Devices = Services.Searching.Search.SearchDeviceProfile(Database, dp.Id); m.Devices = Services.Searching.Search.SearchDeviceProfile(Database, dp.Id, LimitCount: null);
break; break;
} }
} }
@@ -117,7 +117,7 @@ namespace Disco.Web.Controllers
if (db != null) if (db != null)
{ {
m.FriendlyTerm = string.Format("Device Batch: {0}", db.ToString()); m.FriendlyTerm = string.Format("Device Batch: {0}", db.ToString());
m.Devices = Services.Searching.Search.SearchDeviceBatch(Database, db.Id); m.Devices = Services.Searching.Search.SearchDeviceBatch(Database, db.Id, LimitCount: null);
break; break;
} }
} }
@@ -154,7 +154,7 @@ namespace Disco.Web.Controllers
return RedirectToAction(MVC.Job.Show(termInt)); return RedirectToAction(MVC.Job.Show(termInt));
} }
} }
m.Jobs = Services.Searching.Search.SearchJobsTable(Database, term, null, true, searchDetails); m.Jobs = Services.Searching.Search.SearchJobsTable(Database, term, LimitCount: null, IncludeJobStatus: true, SearchDetails: searchDetails);
break; break;
case "users": case "users":
Authorization.Require(Claims.User.Search); Authorization.Require(Claims.User.Search);
@@ -164,7 +164,7 @@ namespace Disco.Web.Controllers
m.ErrorMessage = "A search term of at least two characters is required"; m.ErrorMessage = "A search term of at least two characters is required";
return View(m); return View(m);
} }
m.Users = Services.Searching.Search.SearchUsers(Database, term); m.Users = Services.Searching.Search.SearchUsers(Database, term, true, LimitCount: null);
if (m.Users.Count == 1) if (m.Users.Count == 1)
{ {
return RedirectToAction(MVC.User.Show(m.Users[0].Id)); return RedirectToAction(MVC.User.Show(m.Users[0].Id));
+33 -29
View File
@@ -3684,6 +3684,7 @@ namespace Disco.Web.Areas.API.Controllers
{ {
public readonly string id = "id"; public readonly string id = "id";
public readonly string AssignedUserId = "AssignedUserId"; public readonly string AssignedUserId = "AssignedUserId";
public readonly string AssignedUserDomain = "AssignedUserDomain";
public readonly string redirect = "redirect"; public readonly string redirect = "redirect";
} }
static readonly ActionParamsClass_UpdateAllowUnauthenticatedEnrol s_params_UpdateAllowUnauthenticatedEnrol = new ActionParamsClass_UpdateAllowUnauthenticatedEnrol(); static readonly ActionParamsClass_UpdateAllowUnauthenticatedEnrol s_params_UpdateAllowUnauthenticatedEnrol = new ActionParamsClass_UpdateAllowUnauthenticatedEnrol();
@@ -3896,15 +3897,16 @@ namespace Disco.Web.Areas.API.Controllers
return callInfo; return callInfo;
} }
partial void UpdateAssignedUserIdOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string id, string AssignedUserId, bool redirect); partial void UpdateAssignedUserIdOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string id, string AssignedUserId, string AssignedUserDomain, bool redirect);
public override System.Web.Mvc.ActionResult UpdateAssignedUserId(string id, string AssignedUserId, bool redirect) public override System.Web.Mvc.ActionResult UpdateAssignedUserId(string id, string AssignedUserId, string AssignedUserDomain, bool redirect)
{ {
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UpdateAssignedUserId); var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UpdateAssignedUserId);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id); ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "AssignedUserId", AssignedUserId); ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "AssignedUserId", AssignedUserId);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "AssignedUserDomain", AssignedUserDomain);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "redirect", redirect); ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "redirect", redirect);
UpdateAssignedUserIdOverride(callInfo, id, AssignedUserId, redirect); UpdateAssignedUserIdOverride(callInfo, id, AssignedUserId, AssignedUserDomain, redirect);
return callInfo; return callInfo;
} }
@@ -9065,6 +9067,12 @@ namespace Disco.Web.Areas.API.Controllers
{ {
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.QuickQuery); return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.QuickQuery);
} }
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult UsersUpstream()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UsersUpstream);
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public SearchController Actions { get { return MVC.API.Search; } } public SearchController Actions { get { return MVC.API.Search; } }
@@ -9082,12 +9090,14 @@ namespace Disco.Web.Areas.API.Controllers
public class ActionNamesClass public class ActionNamesClass
{ {
public readonly string QuickQuery = "QuickQuery"; public readonly string QuickQuery = "QuickQuery";
public readonly string UsersUpstream = "UsersUpstream";
} }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionNameConstants public class ActionNameConstants
{ {
public const string QuickQuery = "QuickQuery"; public const string QuickQuery = "QuickQuery";
public const string UsersUpstream = "UsersUpstream";
} }
@@ -9100,6 +9110,15 @@ namespace Disco.Web.Areas.API.Controllers
public readonly string Term = "Term"; public readonly string Term = "Term";
public readonly string Limit = "Limit"; public readonly string Limit = "Limit";
} }
static readonly ActionParamsClass_UsersUpstream s_params_UsersUpstream = new ActionParamsClass_UsersUpstream();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_UsersUpstream UsersUpstreamParams { get { return s_params_UsersUpstream; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_UsersUpstream
{
public readonly string Term = "Term";
public readonly string Limit = "Limit";
}
static readonly ViewsClass s_views = new ViewsClass(); static readonly ViewsClass s_views = new ViewsClass();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ViewsClass Views { get { return s_views; } } public ViewsClass Views { get { return s_views; } }
@@ -9130,6 +9149,17 @@ namespace Disco.Web.Areas.API.Controllers
return callInfo; return callInfo;
} }
partial void UsersUpstreamOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string Term, int Limit);
public override System.Web.Mvc.ActionResult UsersUpstream(string Term, int Limit)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UsersUpstream);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Term", Term);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Limit", Limit);
UsersUpstreamOverride(callInfo, Term, Limit);
return callInfo;
}
} }
} }
@@ -9564,12 +9594,6 @@ namespace Disco.Web.Areas.API.Controllers
return RedirectToRoutePermanent(callInfo.RouteValueDictionary); return RedirectToRoutePermanent(callInfo.RouteValueDictionary);
} }
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult UpstreamUsers()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UpstreamUsers);
}
[NonAction] [NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult AttachmentDownload() public virtual System.Web.Mvc.ActionResult AttachmentDownload()
@@ -9628,7 +9652,6 @@ namespace Disco.Web.Areas.API.Controllers
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionNamesClass public class ActionNamesClass
{ {
public readonly string UpstreamUsers = "UpstreamUsers";
public readonly string AttachmentDownload = "AttachmentDownload"; public readonly string AttachmentDownload = "AttachmentDownload";
public readonly string AttachmentThumbnail = "AttachmentThumbnail"; public readonly string AttachmentThumbnail = "AttachmentThumbnail";
public readonly string AttachmentUpload = "AttachmentUpload"; public readonly string AttachmentUpload = "AttachmentUpload";
@@ -9641,7 +9664,6 @@ namespace Disco.Web.Areas.API.Controllers
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionNameConstants public class ActionNameConstants
{ {
public const string UpstreamUsers = "UpstreamUsers";
public const string AttachmentDownload = "AttachmentDownload"; public const string AttachmentDownload = "AttachmentDownload";
public const string AttachmentThumbnail = "AttachmentThumbnail"; public const string AttachmentThumbnail = "AttachmentThumbnail";
public const string AttachmentUpload = "AttachmentUpload"; public const string AttachmentUpload = "AttachmentUpload";
@@ -9652,14 +9674,6 @@ namespace Disco.Web.Areas.API.Controllers
} }
static readonly ActionParamsClass_UpstreamUsers s_params_UpstreamUsers = new ActionParamsClass_UpstreamUsers();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_UpstreamUsers UpstreamUsersParams { get { return s_params_UpstreamUsers; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_UpstreamUsers
{
public readonly string term = "term";
}
static readonly ActionParamsClass_AttachmentDownload s_params_AttachmentDownload = new ActionParamsClass_AttachmentDownload(); static readonly ActionParamsClass_AttachmentDownload s_params_AttachmentDownload = new ActionParamsClass_AttachmentDownload();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_AttachmentDownload AttachmentDownloadParams { get { return s_params_AttachmentDownload; } } public ActionParamsClass_AttachmentDownload AttachmentDownloadParams { get { return s_params_AttachmentDownload; } }
@@ -9740,16 +9754,6 @@ namespace Disco.Web.Areas.API.Controllers
{ {
public T4MVC_UserController() : base(Dummy.Instance) { } public T4MVC_UserController() : base(Dummy.Instance) { }
partial void UpstreamUsersOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string term);
public override System.Web.Mvc.ActionResult UpstreamUsers(string term)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UpstreamUsers);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "term", term);
UpstreamUsersOverride(callInfo, term);
return callInfo;
}
partial void AttachmentDownloadOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id); partial void AttachmentDownloadOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, int id);
public override System.Web.Mvc.ActionResult AttachmentDownload(int id) public override System.Web.Mvc.ActionResult AttachmentDownload(int id)
+1 -1
View File
@@ -126,7 +126,7 @@
.watermark('Search Users') .watermark('Search Users')
.focus(function () { $AssignedUserId.select() }) .focus(function () { $AssignedUserId.select() })
.autocomplete({ .autocomplete({
source: '@(Url.Action(MVC.API.User.UpstreamUsers()))', source: '@(Url.Action(MVC.API.Search.UsersUpstream()))',
minLength: 2, minLength: 2,
focus: function (e, ui) { focus: function (e, ui) {
$AssignedUserId.val(ui.item.DisplayName + ' (' + ui.item.Id + ')'); $AssignedUserId.val(ui.item.DisplayName + ' (' + ui.item.Id + ')');
@@ -2,7 +2,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Runtime Version:4.0.30319.34011 // Runtime Version:4.0.30319.34014
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -494,7 +494,7 @@ WriteLiteral(@"
#line 129 "..\..\Views\Device\AddOffline.cshtml" #line 129 "..\..\Views\Device\AddOffline.cshtml"
Write(Url.Action(MVC.API.User.UpstreamUsers())); Write(Url.Action(MVC.API.Search.UsersUpstream()));
#line default #line default
@@ -500,7 +500,7 @@
} }
@if (Model.Device.CanUpdateAssignment()) @if (Model.Device.CanUpdateAssignment())
{ {
@Html.ActionLinkSmallButton("Update Assignment", MVC.API.Device.UpdateAssignedUserId(Model.Device.SerialNumber, null, true), "Device_Show_User_Actions_Assign_Button") @Html.ActionLinkSmallButton("Update Assignment", MVC.API.Device.UpdateAssignedUserId(Model.Device.SerialNumber, null, null, true), "Device_Show_User_Actions_Assign_Button")
<div id="Device_Show_User_Actions_Assign_Dialog" class="dialog" title="Assign this Device?"> <div id="Device_Show_User_Actions_Assign_Dialog" class="dialog" title="Assign this Device?">
<h4><i class="fa fa-info-circle information"></i>&nbsp;Assign to User:</h4> <h4><i class="fa fa-info-circle information"></i>&nbsp;Assign to User:</h4>
<br /> <br />
@@ -555,7 +555,7 @@
inputUserId = $('#Device_Show_User_Actions_Assign_UserId'); inputUserId = $('#Device_Show_User_Actions_Assign_UserId');
inputUserId.focus(function () { inputUserId.select() }) inputUserId.focus(function () { inputUserId.select() })
.autocomplete({ .autocomplete({
source: '@(Url.Action(MVC.API.User.UpstreamUsers()))', source: '@(Url.Action(MVC.API.Search.UsersUpstream()))',
minLength: 2, minLength: 2,
select: function (e, ui) { select: function (e, ui) {
inputUserId.val(ui.item.Id); inputUserId.val(ui.item.Id);
@@ -2,7 +2,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Runtime Version:4.0.30319.34011 // Runtime Version:4.0.30319.34014
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1901,7 +1901,7 @@ WriteLiteral(" ");
#line hidden #line hidden
#line 503 "..\..\Views\Device\DeviceParts\_Subject.cshtml" #line 503 "..\..\Views\Device\DeviceParts\_Subject.cshtml"
Write(Html.ActionLinkSmallButton("Update Assignment", MVC.API.Device.UpdateAssignedUserId(Model.Device.SerialNumber, null, true), "Device_Show_User_Actions_Assign_Button")); Write(Html.ActionLinkSmallButton("Update Assignment", MVC.API.Device.UpdateAssignedUserId(Model.Device.SerialNumber, null, null, true), "Device_Show_User_Actions_Assign_Button"));
#line default #line default
@@ -2008,7 +2008,7 @@ WriteLiteral("\r\n \"Assign\": function () {\r\n
#line 558 "..\..\Views\Device\DeviceParts\_Subject.cshtml" #line 558 "..\..\Views\Device\DeviceParts\_Subject.cshtml"
Write(Url.Action(MVC.API.User.UpstreamUsers())); Write(Url.Action(MVC.API.Search.UsersUpstream()));
#line default #line default
@@ -2314,28 +2314,28 @@ WriteLiteral(" <li>\r\n
WriteLiteral(" type=\"radio\""); WriteLiteral(" type=\"radio\"");
WriteAttribute("id", Tuple.Create(" id=\"", 41935), Tuple.Create("\"", 42013) WriteAttribute("id", Tuple.Create(" id=\"", 41943), Tuple.Create("\"", 42021)
, Tuple.Create(Tuple.Create("", 41940), Tuple.Create("Device_Show_Device_Actions_Decommission_Reason_", 41940), true) , Tuple.Create(Tuple.Create("", 41948), Tuple.Create("Device_Show_Device_Actions_Decommission_Reason_", 41948), true)
#line 679 "..\..\Views\Device\DeviceParts\_Subject.cshtml" #line 679 "..\..\Views\Device\DeviceParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 41987), Tuple.Create<System.Object, System.Int32>((int)decommissionReason , Tuple.Create(Tuple.Create("", 41995), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default #line default
#line hidden #line hidden
, 41987), false) , 41995), false)
); );
WriteLiteral("\r\n name=\"Device_Show_Device_Actions_Decomm" + WriteLiteral("\r\n name=\"Device_Show_Device_Actions_Decomm" +
"ission_Reason\""); "ission_Reason\"");
WriteAttribute("value", Tuple.Create(" value=\"", 42109), Tuple.Create("\"", 42143) WriteAttribute("value", Tuple.Create(" value=\"", 42117), Tuple.Create("\"", 42151)
#line 680 "..\..\Views\Device\DeviceParts\_Subject.cshtml" #line 680 "..\..\Views\Device\DeviceParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 42117), Tuple.Create<System.Object, System.Int32>((int)decommissionReason , Tuple.Create(Tuple.Create("", 42125), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default #line default
#line hidden #line hidden
, 42117), false) , 42125), false)
); );
WriteLiteral(" "); WriteLiteral(" ");
@@ -2349,15 +2349,15 @@ WriteLiteral(" ");
#line hidden #line hidden
WriteLiteral("/>\r\n <label"); WriteLiteral("/>\r\n <label");
WriteAttribute("for", Tuple.Create(" for=\"", 42293), Tuple.Create("\"", 42372) WriteAttribute("for", Tuple.Create(" for=\"", 42301), Tuple.Create("\"", 42380)
, Tuple.Create(Tuple.Create("", 42299), Tuple.Create("Device_Show_Device_Actions_Decommission_Reason_", 42299), true) , Tuple.Create(Tuple.Create("", 42307), Tuple.Create("Device_Show_Device_Actions_Decommission_Reason_", 42307), true)
#line 681 "..\..\Views\Device\DeviceParts\_Subject.cshtml" #line 681 "..\..\Views\Device\DeviceParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 42346), Tuple.Create<System.Object, System.Int32>((int)decommissionReason , Tuple.Create(Tuple.Create("", 42354), Tuple.Create<System.Object, System.Int32>((int)decommissionReason
#line default #line default
#line hidden #line hidden
, 42346), false) , 42354), false)
); );
WriteLiteral(">"); WriteLiteral(">");