From 065b14b1588570cd369f7bac9eab15ce8fdda3b7 Mon Sep 17 00:00:00 2001 From: Gary Sharp Date: Wed, 9 Nov 2016 20:06:24 +1100 Subject: [PATCH] User Flag Expressions Adds the ability to have expressions evaluated when flags are added and removed. --- Disco.Data/Disco.Data.csproj | 7 + .../201611090729100_DBv18.Designer.cs | 27 + .../Migrations/201611090729100_DBv18.cs | 24 + .../Migrations/201611090729100_DBv18.resx | 123 ++++ Disco.Models/Repository/User/Flag/UserFlag.cs | 5 + .../User/Flag/UserFlagAssignment.cs | 3 + Disco.Services/Disco.Services.csproj | 1 + .../Users/UserFlags/UserFlagExtensions.cs | 129 +++- .../Users/UserFlags/UserFlagService.cs | 27 +- .../UserFlags/UserFlagsBulkAssignTask.cs | 2 +- .../UserFlagAssignmentController.cs | 15 +- .../API/Controllers/UserFlagController.cs | 51 ++ .../Areas/Config/Views/UserFlag/Show.cshtml | 145 +++- .../Config/Views/UserFlag/Show.generated.cs | 620 ++++++++++++++---- Disco.Web/ClientSource/Style/Config.css | 7 + Disco.Web/ClientSource/Style/Config.less | 49 +- Disco.Web/ClientSource/Style/Config.min.css | 2 +- Disco.Web/ClientSource/Style/User.css | 5 + Disco.Web/ClientSource/Style/User.less | 5 + Disco.Web/ClientSource/Style/User.min.css | 2 +- .../T4MVC/API.UserFlagController.generated.cs | 64 ++ Disco.Web/Views/User/Show.generated.cs | 3 +- Disco.Web/Views/User/UserParts/_Flags.cshtml | 8 + .../Views/User/UserParts/_Flags.generated.cs | 127 +++- 24 files changed, 1241 insertions(+), 210 deletions(-) create mode 100644 Disco.Data/Migrations/201611090729100_DBv18.Designer.cs create mode 100644 Disco.Data/Migrations/201611090729100_DBv18.cs create mode 100644 Disco.Data/Migrations/201611090729100_DBv18.resx diff --git a/Disco.Data/Disco.Data.csproj b/Disco.Data/Disco.Data.csproj index 22391aab..3418a446 100644 --- a/Disco.Data/Disco.Data.csproj +++ b/Disco.Data/Disco.Data.csproj @@ -154,6 +154,10 @@ 201609260741183_DBv17.cs + + + 201611090729100_DBv18.cs + @@ -220,6 +224,9 @@ 201609260741183_DBv17.cs + + 201611090729100_DBv18.cs + ResXFileCodeGenerator Resources.Designer.cs diff --git a/Disco.Data/Migrations/201611090729100_DBv18.Designer.cs b/Disco.Data/Migrations/201611090729100_DBv18.Designer.cs new file mode 100644 index 00000000..39b12b71 --- /dev/null +++ b/Disco.Data/Migrations/201611090729100_DBv18.Designer.cs @@ -0,0 +1,27 @@ +// +namespace Disco.Data.Migrations +{ + using System.Data.Entity.Migrations; + using System.Data.Entity.Migrations.Infrastructure; + using System.Resources; + + public sealed partial class DBv18 : IMigrationMetadata + { + private readonly ResourceManager Resources = new ResourceManager(typeof(DBv18)); + + string IMigrationMetadata.Id + { + get { return "201611090729100_DBv18"; } + } + + string IMigrationMetadata.Source + { + get { return null; } + } + + string IMigrationMetadata.Target + { + get { return Resources.GetString("Target"); } + } + } +} diff --git a/Disco.Data/Migrations/201611090729100_DBv18.cs b/Disco.Data/Migrations/201611090729100_DBv18.cs new file mode 100644 index 00000000..4e568567 --- /dev/null +++ b/Disco.Data/Migrations/201611090729100_DBv18.cs @@ -0,0 +1,24 @@ +namespace Disco.Data.Migrations +{ + using System; + using System.Data.Entity.Migrations; + + public partial class DBv18 : DbMigration + { + public override void Up() + { + AddColumn("dbo.UserFlagAssignments", "OnAssignmentExpressionResult", c => c.String()); + AddColumn("dbo.UserFlagAssignments", "OnUnassignmentExpressionResult", c => c.String()); + AddColumn("dbo.UserFlags", "OnAssignmentExpression", c => c.String()); + AddColumn("dbo.UserFlags", "OnUnassignmentExpression", c => c.String()); + } + + public override void Down() + { + DropColumn("dbo.UserFlags", "OnUnassignmentExpression"); + DropColumn("dbo.UserFlags", "OnAssignmentExpression"); + DropColumn("dbo.UserFlagAssignments", "OnUnassignmentExpressionResult"); + DropColumn("dbo.UserFlagAssignments", "OnAssignmentExpressionResult"); + } + } +} diff --git a/Disco.Data/Migrations/201611090729100_DBv18.resx b/Disco.Data/Migrations/201611090729100_DBv18.resx new file mode 100644 index 00000000..cfbb086b --- /dev/null +++ b/Disco.Data/Migrations/201611090729100_DBv18.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 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 + + \ No newline at end of file diff --git a/Disco.Models/Repository/User/Flag/UserFlag.cs b/Disco.Models/Repository/User/Flag/UserFlag.cs index 83758359..6ab37235 100644 --- a/Disco.Models/Repository/User/Flag/UserFlag.cs +++ b/Disco.Models/Repository/User/Flag/UserFlag.cs @@ -22,6 +22,11 @@ namespace Disco.Models.Repository public string UsersLinkedGroup { get; set; } public string UserDevicesLinkedGroup { get; set; } + [DataType(DataType.MultilineText)] + public string OnAssignmentExpression { get; set; } + [DataType(DataType.MultilineText)] + public string OnUnassignmentExpression { get; set; } + public virtual IList UserFlagAssignments { get; set; } public override string ToString() diff --git a/Disco.Models/Repository/User/Flag/UserFlagAssignment.cs b/Disco.Models/Repository/User/Flag/UserFlagAssignment.cs index af195fb8..a0710bc2 100644 --- a/Disco.Models/Repository/User/Flag/UserFlagAssignment.cs +++ b/Disco.Models/Repository/User/Flag/UserFlagAssignment.cs @@ -22,6 +22,9 @@ namespace Disco.Models.Repository public string Comments { get; set; } + public string OnAssignmentExpressionResult { get; set; } + public string OnUnassignmentExpressionResult { get; set; } + [ForeignKey("UserFlagId"), InverseProperty("UserFlagAssignments")] public virtual UserFlag UserFlag { get; set; } diff --git a/Disco.Services/Disco.Services.csproj b/Disco.Services/Disco.Services.csproj index 25600414..6764e439 100644 --- a/Disco.Services/Disco.Services.csproj +++ b/Disco.Services/Disco.Services.csproj @@ -333,6 +333,7 @@ + diff --git a/Disco.Services/Users/UserFlags/UserFlagExtensions.cs b/Disco.Services/Users/UserFlags/UserFlagExtensions.cs index 76b71dfa..84b85f06 100644 --- a/Disco.Services/Users/UserFlags/UserFlagExtensions.cs +++ b/Disco.Services/Users/UserFlags/UserFlagExtensions.cs @@ -1,6 +1,8 @@ using Disco.Data.Repository; using Disco.Models.Repository; using Disco.Services.Authorization; +using Disco.Services.Expressions; +using Disco.Services.Logging; using Disco.Services.Users; using System; using System.Linq; @@ -32,13 +34,36 @@ namespace Disco.Services return UserService.CurrentAuthorization.Has(Claims.User.Actions.RemoveFlags); } - public static void OnRemove(this UserFlagAssignment fa, User Technician) + public static void OnRemove(this UserFlagAssignment fa, DiscoDataContext Database, User RemovingUser) { if (!fa.CanRemove()) throw new InvalidOperationException("Removing user flags is denied"); + fa.OnRemoveUnsafe(Database, RemovingUser); + } + + public static void OnRemoveUnsafe(this UserFlagAssignment fa, DiscoDataContext Database, User RemovingUser) + { fa.RemovedDate = DateTime.Now; - fa.RemovedUserId = Technician.UserId; + fa.RemovedUserId = RemovingUser.UserId; + + if (!string.IsNullOrWhiteSpace(fa.UserFlag.OnUnassignmentExpression)) + { + try + { + Database.SaveChanges(); + var expressionResult = fa.EvaluateOnUnassignmentExpression(Database, RemovingUser, fa.AddedDate); + if (!string.IsNullOrWhiteSpace(expressionResult)) + { + fa.OnUnassignmentExpressionResult = expressionResult; + Database.SaveChanges(); + } + } + catch (Exception ex) + { + SystemLog.LogException("User Flag Expression - OnUnassignmentExpression", ex); + } + } } #endregion @@ -59,24 +84,116 @@ namespace Disco.Services return true; } - public static UserFlagAssignment OnAddUserFlag(this User u, DiscoDataContext Database, UserFlag flag, User Technician, string Comments) + public static UserFlagAssignment OnAddUserFlag(this User u, DiscoDataContext Database, UserFlag flag, User AddingUser, string Comments) { if (!u.CanAddUserFlag(flag)) throw new InvalidOperationException("Adding user flag is denied"); + return u.OnAddUserFlagUnsafe(Database, flag, AddingUser, Comments); + } + + public static UserFlagAssignment OnAddUserFlagUnsafe(this User u, DiscoDataContext Database, UserFlag flag, User AddingUser, string Comments) + { var fa = new UserFlagAssignment() { - UserFlagId = flag.Id, - UserId = u.UserId, + UserFlag = flag, + User = u, AddedDate = DateTime.Now, - AddedUserId = Technician.UserId, + AddedUser = AddingUser, Comments = string.IsNullOrWhiteSpace(Comments) ? null : Comments.Trim() }; Database.UserFlagAssignments.Add(fa); + + if (!string.IsNullOrWhiteSpace(flag.OnAssignmentExpression)) + { + try + { + Database.SaveChanges(); + fa = Database.UserFlagAssignments.Where(ufa => ufa.Id == fa.Id).First(); + var expressionResult = fa.EvaluateOnAssignmentExpression(Database, AddingUser, fa.AddedDate); + if (!string.IsNullOrWhiteSpace(expressionResult)) + { + fa.OnAssignmentExpressionResult = expressionResult; + Database.SaveChanges(); + } + } + catch (Exception ex) + { + SystemLog.LogException("User Flag Expression - OnAssignmentExpression", ex); + } + } + return fa; } #endregion + #region Expressions + + public static Expression OnAssignmentExpressionFromCache(this UserFlag uf) + { + return ExpressionCache.GetValue("UserFlag_OnAssignmentExpression", uf.Id.ToString(), () => { return Expression.TokenizeSingleDynamic(null, uf.OnAssignmentExpression, 0); }); + } + + public static void OnAssignmentExpressionInvalidateCache(this UserFlag uf) + { + ExpressionCache.InvalidateKey("UserFlag_OnAssignmentExpression", uf.Id.ToString()); + } + + public static string EvaluateOnAssignmentExpression(this UserFlagAssignment ufa, DiscoDataContext Database, User AddingUser, DateTime TimeStamp) + { + if (!string.IsNullOrEmpty(ufa.UserFlag.OnAssignmentExpression)) + { + Expression compiledExpression = ufa.UserFlag.OnAssignmentExpressionFromCache(); + System.Collections.IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, AddingUser, TimeStamp, null); + try + { + object result = compiledExpression.EvaluateFirst(ufa, evaluatorVariables); + if (result == null) + return null; + else + return result.ToString(); + } + catch + { + throw; + } + } + return null; + } + + public static Expression OnUnassignmentExpressionFromCache(this UserFlag uf) + { + return ExpressionCache.GetValue("UserFlag_OnUnassignmentExpression", uf.Id.ToString(), () => { return Expression.TokenizeSingleDynamic(null, uf.OnUnassignmentExpression, 0); }); + } + + public static void OnUnassignmentExpressionInvalidateCache(this UserFlag uf) + { + ExpressionCache.InvalidateKey("UserFlag_OnUnassignmentExpression", uf.Id.ToString()); + } + + public static string EvaluateOnUnassignmentExpression(this UserFlagAssignment ufa, DiscoDataContext Database, User RemovingUser, DateTime TimeStamp) + { + if (!string.IsNullOrEmpty(ufa.UserFlag.OnUnassignmentExpression)) + { + Expression compiledExpression = ufa.UserFlag.OnUnassignmentExpressionFromCache(); + System.Collections.IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, RemovingUser, TimeStamp, null); + try + { + object result = compiledExpression.EvaluateFirst(ufa, evaluatorVariables); + if (result == null) + return null; + else + return result.ToString(); + } + catch + { + throw; + } + } + return null; + } + + #endregion } } diff --git a/Disco.Services/Users/UserFlags/UserFlagService.cs b/Disco.Services/Users/UserFlags/UserFlagService.cs index a1e96931..432321d7 100644 --- a/Disco.Services/Users/UserFlags/UserFlagService.cs +++ b/Disco.Services/Users/UserFlags/UserFlagService.cs @@ -146,17 +146,7 @@ namespace Disco.Services.Users.UserFlags { Status.UpdateStatus((chunkIndexOffset + index) * progressInterval, string.Format("Assigning Flag: {0}", user.ToString())); - var fa = new UserFlagAssignment() - { - UserFlagId = UserFlag.Id, - UserId = user.UserId, - AddedDate = DateTime.Now, - AddedUserId = Technician.UserId, - Comments = comments - }; - - Database.UserFlagAssignments.Add(fa); - return fa; + return user.OnAddUserFlag(Database, UserFlag, Technician, comments); }).ToList(); // Save Chunk Items to Database @@ -202,8 +192,7 @@ namespace Disco.Services.Users.UserFlags { Status.UpdateStatus((chunkIndexOffset + index) * progressInterval, string.Format("Removing Flag: {0}", flagAssignment.User.ToString())); - flagAssignment.RemovedDate = removedDateTime; - flagAssignment.RemovedUserId = Technician.UserId; + flagAssignment.OnRemoveUnsafe(Database, Technician); return flagAssignment; }).ToList(); @@ -223,17 +212,7 @@ namespace Disco.Services.Users.UserFlags { Status.UpdateStatus((chunkIndexOffset + index) * progressInterval, string.Format("Assigning Flag: {0}", user.ToString())); - var fa = new UserFlagAssignment() - { - UserFlagId = UserFlag.Id, - UserId = user.UserId, - AddedDate = DateTime.Now, - AddedUserId = Technician.UserId, - Comments = comments - }; - - Database.UserFlagAssignments.Add(fa); - return fa; + return user.OnAddUserFlag(Database, UserFlag, Technician, comments); }).ToList(); // Save Chunk Items to Database diff --git a/Disco.Services/Users/UserFlags/UserFlagsBulkAssignTask.cs b/Disco.Services/Users/UserFlags/UserFlagsBulkAssignTask.cs index 1fda9fbd..f0bfd3b4 100644 --- a/Disco.Services/Users/UserFlags/UserFlagsBulkAssignTask.cs +++ b/Disco.Services/Users/UserFlags/UserFlagsBulkAssignTask.cs @@ -29,9 +29,9 @@ namespace Disco.Services.Users.UserFlags { // Load Flag var userFlag = Database.UserFlags.FirstOrDefault(uf => uf.Id == UserFlagId); - if (userFlag == null) throw new Exception("Invalid User Flag Id"); + Status.UpdateStatus(0, string.Format("Bulk Assigning Users to User Flag: {0}", userFlag.Name), "Preparing to start"); // Load Technician diff --git a/Disco.Web/Areas/API/Controllers/UserFlagAssignmentController.cs b/Disco.Web/Areas/API/Controllers/UserFlagAssignmentController.cs index f90f4eec..5dc3e760 100644 --- a/Disco.Web/Areas/API/Controllers/UserFlagAssignmentController.cs +++ b/Disco.Web/Areas/API/Controllers/UserFlagAssignmentController.cs @@ -75,7 +75,9 @@ namespace Disco.Web.Areas.API.Controllers [DiscoAuthorizeAny(Claims.User.Actions.AddFlags)] public virtual ActionResult AddUser(int id, string UserId, string Comments) { - var userFlag = UserFlagService.GetUserFlag(id); + Database.Configuration.LazyLoadingEnabled = true; + + var userFlag = Database.UserFlags.Find(id); if (userFlag == null) throw new ArgumentException("Invalid User Flag Id", "id"); @@ -86,8 +88,9 @@ namespace Disco.Web.Areas.API.Controllers if (!user.CanAddUserFlag(userFlag)) throw new InvalidOperationException("Adding user flag is denied"); - var userFlagAssignment = user.OnAddUserFlag(Database, userFlag, CurrentUser, Comments); - Database.SaveChanges(); + var addingUser = Database.Users.Find(CurrentUser.UserId); + + var userFlagAssignment = user.OnAddUserFlag(Database, userFlag, addingUser, Comments); return Redirect(string.Format("{0}#UserDetailTab-Flags", Url.Action(MVC.User.Show(user.UserId)))); } @@ -95,6 +98,8 @@ namespace Disco.Web.Areas.API.Controllers [DiscoAuthorizeAny(Claims.User.Actions.RemoveFlags)] public virtual ActionResult RemoveUser(int id) { + Database.Configuration.LazyLoadingEnabled = true; + var userFlagAssignment = Database.UserFlagAssignments.FirstOrDefault(a => a.Id == id); if (userFlagAssignment == null) throw new ArgumentException("Invalid User Flag Assignment Id", "id"); @@ -102,7 +107,9 @@ namespace Disco.Web.Areas.API.Controllers if (!userFlagAssignment.CanRemove()) throw new InvalidOperationException("Removing user flag assignment is denied"); - userFlagAssignment.OnRemove(CurrentUser); + var removingUser = Database.Users.Find(CurrentUser.UserId); + + userFlagAssignment.OnRemove(Database, removingUser); Database.SaveChanges(); return Redirect(string.Format("{0}#UserDetailTab-Flags", Url.Action(MVC.User.Show(userFlagAssignment.UserId)))); diff --git a/Disco.Web/Areas/API/Controllers/UserFlagController.cs b/Disco.Web/Areas/API/Controllers/UserFlagController.cs index b3b1ceb7..a07e6208 100644 --- a/Disco.Web/Areas/API/Controllers/UserFlagController.cs +++ b/Disco.Web/Areas/API/Controllers/UserFlagController.cs @@ -1,4 +1,5 @@ using Disco.Models.Repository; +using Disco.Services; using Disco.Services.Authorization; using Disco.Services.Interop.ActiveDirectory; using Disco.Services.Tasks; @@ -16,6 +17,8 @@ namespace Disco.Web.Areas.API.Controllers const string pDescription = "description"; const string pIcon = "icon"; const string pIconColour = "iconcolour"; + const string pOnAssignmentExpression = "onassignmentexpression"; + const string pOnUnassignmentExpression = "onunassignmentexpression"; [DiscoAuthorize(Claims.Config.UserFlag.Configure)] public virtual ActionResult Update(int id, string key, string value = null, Nullable redirect = null) @@ -45,6 +48,12 @@ namespace Disco.Web.Areas.API.Controllers case pIconColour: UpdateIconColour(flag, value); break; + case pOnAssignmentExpression: + UpdateOnAssignmentExpression(flag, value); + break; + case pOnUnassignmentExpression: + UpdateOnUnassignmentExpression(flag, value); + break; default: throw new Exception("Invalid Update Key"); } @@ -123,6 +132,16 @@ namespace Disco.Web.Areas.API.Controllers } } [DiscoAuthorize(Claims.Config.UserFlag.Configure)] + public virtual ActionResult UpdateOnAssignmentExpression(int id, string OnAssignmentExpression = null, bool redirect = false) + { + return Update(id, pOnAssignmentExpression, OnAssignmentExpression, redirect); + } + [DiscoAuthorize(Claims.Config.UserFlag.Configure)] + public virtual ActionResult UpdateOnUnassignmentExpression(int id, string OnUnassignmentExpression = null, bool redirect = false) + { + return Update(id, pOnUnassignmentExpression, OnUnassignmentExpression, redirect); + } + [DiscoAuthorize(Claims.Config.UserFlag.Configure)] public virtual ActionResult UpdateAssignedUsersLinkedGroup(int id, string GroupId = null, DateTime? FilterBeginDate = null, bool redirect = false) { try @@ -247,6 +266,38 @@ namespace Disco.Web.Areas.API.Controllers } } + private void UpdateOnAssignmentExpression(UserFlag UserFlag, string OnAssignmentExpression) + { + if (string.IsNullOrWhiteSpace(OnAssignmentExpression)) + { + UserFlag.OnAssignmentExpression = null; + } + else + { + UserFlag.OnAssignmentExpression = OnAssignmentExpression.Trim(); + } + // Invalidate Cache + UserFlag.OnAssignmentExpressionInvalidateCache(); + + UserFlagService.Update(Database, UserFlag); + } + + private void UpdateOnUnassignmentExpression(UserFlag UserFlag, string OnUnassignmentExpression) + { + if (string.IsNullOrWhiteSpace(OnUnassignmentExpression)) + { + UserFlag.OnUnassignmentExpression = null; + } + else + { + UserFlag.OnUnassignmentExpression = OnUnassignmentExpression.Trim(); + } + // Invalidate Cache + UserFlag.OnUnassignmentExpressionInvalidateCache(); + + UserFlagService.Update(Database, UserFlag); + } + private ScheduledTaskStatus UpdateAssignedUsersLinkedGroup(UserFlag UserFlag, string AssignedUsersLinkedGroup, DateTime? FilterBeginDate) { var configJson = ADManagedGroup.ValidConfigurationToJson(UserFlagUsersManagedGroup.GetKey(UserFlag), AssignedUsersLinkedGroup, FilterBeginDate); diff --git a/Disco.Web/Areas/Config/Views/UserFlag/Show.cshtml b/Disco.Web/Areas/Config/Views/UserFlag/Show.cshtml index ae7893dc..cb5124bd 100644 --- a/Disco.Web/Areas/Config/Views/UserFlag/Show.cshtml +++ b/Disco.Web/Areas/Config/Views/UserFlag/Show.cshtml @@ -14,7 +14,9 @@ var hideAdvanced = Model.UserFlag.UserDevicesLinkedGroup == null && - Model.UserFlag.UsersLinkedGroup == null; + Model.UserFlag.UsersLinkedGroup == null && + Model.UserFlag.OnAssignmentExpression == null && + Model.UserFlag.OnUnassignmentExpression == null; Html.BundleDeferred("~/ClientScripts/Modules/Disco-PropertyChangeHelpers"); } @@ -222,6 +224,147 @@ } + + + On Assignment
Expression: + + + @if (canConfig) + { + @Html.EditorFor(model => model.UserFlag.OnAssignmentExpression) + @AjaxHelpers.AjaxRemove() + @AjaxHelpers.AjaxSave() + @AjaxHelpers.AjaxLoader() + + } + else + { + if (string.IsNullOrWhiteSpace(Model.UserFlag.OnAssignmentExpression)) + { + <None Specified> + } + else + { +
+ @Model.UserFlag.OnAssignmentExpression +
+ } + } +
+

+ This expression will be evaluated whenever the user flag is assigned to a user. The output of the expression will be shown with the flag assignment. +

+
+ + + + + On Unassignment
Expression: + + + @if (canConfig) + { + @Html.EditorFor(model => model.UserFlag.OnUnassignmentExpression) + @AjaxHelpers.AjaxRemove() + @AjaxHelpers.AjaxSave() + @AjaxHelpers.AjaxLoader() + + } + else + { + if (string.IsNullOrWhiteSpace(Model.UserFlag.OnUnassignmentExpression)) + { + <None Specified> + } + else + { +
+ @Model.UserFlag.OnUnassignmentExpression +
+ } + } +
+

+ This expression will be evaluated whenever the user flag is removed from a user. The output of the expression will be shown with the flag assignment. +

+
+ + + Linked Groups: diff --git a/Disco.Web/Areas/Config/Views/UserFlag/Show.generated.cs b/Disco.Web/Areas/Config/Views/UserFlag/Show.generated.cs index b5d844cc..6da9824c 100644 --- a/Disco.Web/Areas/Config/Views/UserFlag/Show.generated.cs +++ b/Disco.Web/Areas/Config/Views/UserFlag/Show.generated.cs @@ -75,7 +75,9 @@ namespace Disco.Web.Areas.Config.Views.UserFlag var hideAdvanced = Model.UserFlag.UserDevicesLinkedGroup == null && - Model.UserFlag.UsersLinkedGroup == null; + Model.UserFlag.UsersLinkedGroup == null && + Model.UserFlag.OnAssignmentExpression == null && + Model.UserFlag.OnUnassignmentExpression == null; Html.BundleDeferred("~/ClientScripts/Modules/Disco-PropertyChangeHelpers"); @@ -86,15 +88,15 @@ WriteLiteral("\r\n(hideAdvanced ? " Config_HideAdvanced" : null + #line 23 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" +, Tuple.Create(Tuple.Create("", 1222), Tuple.Create(hideAdvanced ? " Config_HideAdvanced" : null #line default #line hidden -, 1104), false) +, 1222), false) ); WriteLiteral(" style=\"width: 550px\""); @@ -108,7 +110,7 @@ WriteLiteral(">\r\n Id:\r\n \r\n \ WriteLiteral(" "); - #line 28 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 30 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.DisplayFor(model => model.UserFlag.Id)); @@ -118,55 +120,55 @@ WriteLiteral("\r\n \r\n \r\n \r\n " Name:\r\n \r\n \r\n"); - #line 36 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 38 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 36 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 38 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (canConfig) { #line default #line hidden - #line 37 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 39 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.EditorFor(model => model.UserFlag.Name)); #line default #line hidden - #line 37 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 39 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 38 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 40 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxSave()); #line default #line hidden - #line 38 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 40 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 39 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 41 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxLoader()); #line default #line hidden - #line 39 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 41 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" @@ -182,7 +184,7 @@ WriteLiteral(">\r\n $(function () {\r\n " \'"); - #line 45 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 47 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Url.Action(MVC.API.UserFlag.UpdateName(Model.UserFlag.Id))); @@ -192,7 +194,7 @@ WriteLiteral("\',\r\n \'FlagName\'\r\n " });\r\n \r\n"); - #line 50 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 52 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } else { @@ -201,14 +203,14 @@ WriteLiteral("\',\r\n \'FlagName\'\r\n #line default #line hidden - #line 53 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 55 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.UserFlag.Name); #line default #line hidden - #line 53 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 55 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } @@ -219,55 +221,55 @@ WriteLiteral(" \r\n \r\n \r\n " Description:\r\n \r\n \r\n"); - #line 62 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 64 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 62 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 64 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (canConfig) { #line default #line hidden - #line 63 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 65 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.EditorFor(model => model.UserFlag.Description)); #line default #line hidden - #line 63 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 65 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 64 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 66 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxSave()); #line default #line hidden - #line 64 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 66 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 65 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 67 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxLoader()); #line default #line hidden - #line 65 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 67 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" @@ -285,7 +287,7 @@ WriteLiteral(@"> '"); - #line 71 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 73 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Url.Action(MVC.API.UserFlag.UpdateDescription(Model.UserFlag.Id))); @@ -295,7 +297,7 @@ WriteLiteral("\',\r\n \'Description\'\r\n "\r\n });\r\n \r\n"); - #line 76 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 78 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } else { @@ -306,13 +308,13 @@ WriteLiteral("\',\r\n \'Description\'\r\n WriteLiteral("
\r\n");
 
             
-            #line 80 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
+            #line 82 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
                     
             
             #line default
             #line hidden
             
-            #line 80 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
+            #line 82 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
                      if (string.IsNullOrEmpty(Model.UserFlag.Description))
                     {
 
@@ -326,7 +328,7 @@ WriteLiteral("<None>");
 WriteLiteral("\r\n");
 
             
-            #line 83 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
+            #line 85 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
                     }
                     else
                     {
@@ -335,14 +337,14 @@ WriteLiteral("\r\n");
             #line default
             #line hidden
             
-            #line 86 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
+            #line 88 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
                    Write(Model.UserFlag.Description.ToHtmlComment());
 
             
             #line default
             #line hidden
             
-            #line 86 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
+            #line 88 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
                                                                    
                     }
 
@@ -352,7 +354,7 @@ WriteLiteral("\r\n");
 WriteLiteral("                    
\r\n"); - #line 89 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 91 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } @@ -363,7 +365,7 @@ WriteLiteral(" \r\n \r\n \r\n ""); - #line 97 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 99 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.CurrentAssignmentCount); @@ -372,7 +374,7 @@ WriteLiteral(" \r\n \r\n \r\n WriteLiteral(" user"); - #line 97 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 99 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.CurrentAssignmentCount != 1 ? "s" : null); @@ -381,7 +383,7 @@ WriteLiteral(" user"); WriteLiteral(" currently assigned\r\n
"); - #line 98 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 100 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.TotalAssignmentCount); @@ -390,7 +392,7 @@ WriteLiteral(" currently assigned
\r\n
"); WriteLiteral(" total user historical assignment"); - #line 98 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 100 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.TotalAssignmentCount != 1 ? "s" : null); @@ -404,7 +406,7 @@ WriteLiteral(" id=\"Config_UserFlags_Icon\""); WriteLiteral(" data-icon=\""); - #line 106 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 108 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.UserFlag.Icon); @@ -415,7 +417,7 @@ WriteLiteral("\""); WriteLiteral(" data-colour=\""); - #line 106 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 108 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.UserFlag.IconColour); @@ -423,37 +425,37 @@ WriteLiteral(" data-colour=\""); #line hidden WriteLiteral("\""); -WriteAttribute("class", Tuple.Create(" class=\"", 4268), Tuple.Create("\"", 4341) -, Tuple.Create(Tuple.Create("", 4276), Tuple.Create("fa", 4276), true) -, Tuple.Create(Tuple.Create(" ", 4278), Tuple.Create("fa-", 4279), true) +WriteAttribute("class", Tuple.Create(" class=\"", 4386), Tuple.Create("\"", 4459) +, Tuple.Create(Tuple.Create("", 4394), Tuple.Create("fa", 4394), true) +, Tuple.Create(Tuple.Create(" ", 4396), Tuple.Create("fa-", 4397), true) - #line 106 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" - , Tuple.Create(Tuple.Create("", 4282), Tuple.Create(Model.UserFlag.Icon + #line 108 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + , Tuple.Create(Tuple.Create("", 4400), Tuple.Create(Model.UserFlag.Icon #line default #line hidden -, 4282), false) -, Tuple.Create(Tuple.Create(" ", 4304), Tuple.Create("fa-4x", 4305), true) -, Tuple.Create(Tuple.Create(" ", 4310), Tuple.Create("d-", 4311), true) +, 4400), false) +, Tuple.Create(Tuple.Create(" ", 4422), Tuple.Create("fa-4x", 4423), true) +, Tuple.Create(Tuple.Create(" ", 4428), Tuple.Create("d-", 4429), true) - #line 106 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" - , Tuple.Create(Tuple.Create("", 4313), Tuple.Create(Model.UserFlag.IconColour + #line 108 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + , Tuple.Create(Tuple.Create("", 4431), Tuple.Create(Model.UserFlag.IconColour #line default #line hidden -, 4313), false) +, 4431), false) ); WriteLiteral(">\r\n"); - #line 107 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 109 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 107 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 109 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (canConfig) { @@ -483,13 +485,13 @@ WriteLiteral(" class=\"icons\""); WriteLiteral(">\r\n"); - #line 114 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 116 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 114 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 116 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" foreach (var icon in Model.Icons) { @@ -501,7 +503,7 @@ WriteLiteral("
\r\n "save() {\r\n var url = \'"); - #line 183 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 185 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Url.Action(MVC.API.UserFlag.UpdateIconAndColour(id: Model.UserFlag.Id, redirect: true))); @@ -677,7 +679,7 @@ WriteLiteral(@"', "); - #line 205 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 207 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } @@ -686,13 +688,13 @@ WriteLiteral(@"', WriteLiteral(" \r\n \r\n"); - #line 208 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 210 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 208 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 210 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (hideAdvanced) { @@ -726,7 +728,7 @@ WriteLiteral(@">Show Advanced Options "); - #line 224 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 226 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } @@ -736,13 +738,395 @@ WriteLiteral(" \r\n \r\n On Assignment
Expression:\r\n " + +"\r\n \r\n"); + + + #line 232 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + + #line default + #line hidden + + #line 232 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + if (canConfig) + { + + + #line default + #line hidden + + #line 234 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(Html.EditorFor(model => model.UserFlag.OnAssignmentExpression)); + + + #line default + #line hidden + + #line 234 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + + + #line default + #line hidden + + #line 235 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(AjaxHelpers.AjaxRemove()); + + + #line default + #line hidden + + #line 235 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + + + #line default + #line hidden + + #line 236 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(AjaxHelpers.AjaxSave()); + + + #line default + #line hidden + + #line 236 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + + + #line default + #line hidden + + #line 237 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(AjaxHelpers.AjaxLoader()); + + + #line default + #line hidden + + #line 237 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + + + #line default + #line hidden +WriteLiteral(" + $(function () { + var field = $('#UserFlag_OnAssignmentExpression'); + var fieldRemove = field.next('.ajaxRemove'); + var fieldOriginalWidth, fieldOriginalHeight; + + document.DiscoFunctions.PropertyChangeHelper( + field, + 'None', + '"); + + + #line 247 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(Url.Action(MVC.API.UserFlag.UpdateOnAssignmentExpression(Model.UserFlag.Id))); + + + #line default + #line hidden +WriteLiteral("\',\r\n \'OnAssignmentExpression\'\r\n " + +" );\r\n\r\n field.focus(function () {" + +"\r\n fieldOriginalWidth = field.width();\r\n " + +" fieldOriginalHeight = field.height();\r\n " + +" field.css(\'overflow\', \'visible\').animate({ width: fiel" + +"d.parent().width() - 42, height: 75 }, 200);\r\n })" + +".blur(function () {\r\n field.css(\'overflow\', \'" + +"hidden\').animate({ width: fieldOriginalWidth, height: fieldOriginalHeight }, 200" + +");\r\n }).change(function () {\r\n " + +" if (!!field.val()) {\r\n f" + +"ieldRemove.show();\r\n } else {\r\n " + +" fieldRemove.hide();\r\n " + +" }\r\n }).attr(\'placeholder\', \'None\').attr(\'spell" + +"check\', \'false\');\r\n\r\n fieldRemove.click(function " + +"() {\r\n field.val(\'\').change();\r\n " + +" });\r\n\r\n if (!!field.val()) {\r\n" + +" fieldRemove.show();\r\n " + +" } else {\r\n fieldRemove.hide();\r\n " + +" }\r\n });\r\n " + +" \r\n"); + + + #line 276 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + } + else + { + if (string.IsNullOrWhiteSpace(Model.UserFlag.OnAssignmentExpression)) + { + + + #line default + #line hidden +WriteLiteral(" <None Specified>\r\n"); + + + #line 282 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + } + else + { + + + #line default + #line hidden +WriteLiteral(" \r\n"); + +WriteLiteral(" "); + + + #line 286 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(Model.UserFlag.OnAssignmentExpression); + + + #line default + #line hidden +WriteLiteral("\r\n \r\n"); + + + #line 288 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + } + } + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n This expression will be evaluated whenever the user flag is assigned to a us" + +"er. The output of the expression will be shown with the flag assignment.\r\n " + +"

\r\n \r\n \r\n \r\n " + +" \r\n \r\n On Unassignment
Expression:\r\n " + +" \r\n \r\n"); + + + #line 302 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + + #line default + #line hidden + + #line 302 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + if (canConfig) + { + + + #line default + #line hidden + + #line 304 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(Html.EditorFor(model => model.UserFlag.OnUnassignmentExpression)); + + + #line default + #line hidden + + #line 304 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + + + #line default + #line hidden + + #line 305 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(AjaxHelpers.AjaxRemove()); + + + #line default + #line hidden + + #line 305 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + + + #line default + #line hidden + + #line 306 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(AjaxHelpers.AjaxSave()); + + + #line default + #line hidden + + #line 306 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + + + #line default + #line hidden + + #line 307 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(AjaxHelpers.AjaxLoader()); + + + #line default + #line hidden + + #line 307 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + + + #line default + #line hidden +WriteLiteral(" + $(function () { + var field = $('#UserFlag_OnUnassignmentExpression'); + var fieldRemove = field.next('.ajaxRemove'); + var fieldOriginalWidth, fieldOriginalHeight; + + document.DiscoFunctions.PropertyChangeHelper( + field, + 'None', + '"); + + + #line 317 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(Url.Action(MVC.API.UserFlag.UpdateOnUnassignmentExpression(Model.UserFlag.Id))); + + + #line default + #line hidden +WriteLiteral(@"', + 'OnUnassignmentExpression' + ); + + field.focus(function () { + fieldOriginalWidth = field.width(); + fieldOriginalHeight = field.height(); + field.css('overflow', 'visible').animate({ width: field.parent().width() - 42, height: 75 }, 200); + }).blur(function () { + field.css('overflow', 'hidden').animate({ width: fieldOriginalWidth, height: fieldOriginalHeight }, 200); + }).change(function () { + if (!!field.val()) { + fieldRemove.show(); + } else { + fieldRemove.hide(); + } + }).attr('placeholder', 'None').attr('spellcheck', 'false'); + + fieldRemove.click(function () { + field.val('').change(); + }); + + if (!!field.val()) { + fieldRemove.show(); + } else { + fieldRemove.hide(); + } + }); + +"); + + + #line 346 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + } + else + { + if (string.IsNullOrWhiteSpace(Model.UserFlag.OnUnassignmentExpression)) + { + + + #line default + #line hidden +WriteLiteral(" <None Specified>\r\n"); + + + #line 352 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + } + else + { + + + #line default + #line hidden +WriteLiteral(" \r\n"); + +WriteLiteral(" "); + + + #line 356 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(Model.UserFlag.OnUnassignmentExpression); + + + #line default + #line hidden +WriteLiteral("\r\n \r\n"); + + + #line 358 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + } + } + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n This expression will be evaluated whenever the user flag is removed from a u" + +"ser. The output of the expression will be shown with the flag assignment.\r\n " + +"

\r\n \r\n \r\n \r\n\r" + +"\n \r\n \r\n Linked Groups:\r\n \r\n " + " \r\n
\r\n"); WriteLiteral(" "); - #line 231 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 374 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.Partial(MVC.Config.Shared.Views.LinkedGroupInstance, new LinkedGroupModel() { CanConfigure = canConfig, @@ -761,7 +1145,7 @@ WriteLiteral("\r\n"); WriteLiteral(" "); - #line 240 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 383 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.Partial(MVC.Config.Shared.Views.LinkedGroupInstance, new LinkedGroupModel() { CanConfigure = canConfig, @@ -778,13 +1162,13 @@ WriteLiteral(" "); WriteLiteral("\r\n"); - #line 249 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 392 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 249 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 392 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (canConfig) { @@ -792,14 +1176,14 @@ WriteLiteral("\r\n"); #line default #line hidden - #line 251 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 394 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.Partial(MVC.Config.Shared.Views.LinkedGroupShared)); #line default #line hidden - #line 251 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 394 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } @@ -809,7 +1193,7 @@ WriteLiteral("\r\n"); WriteLiteral("
\r\n \r\n \r\n \r\n\r\n"); - #line 258 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 401 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (canBulkAssignment || canDelete || canShowUsers) { @@ -823,13 +1207,13 @@ WriteLiteral(" class=\"actionBar\""); WriteLiteral(">\r\n"); - #line 261 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 404 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 261 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 404 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (canBulkAssignment) { @@ -915,7 +1299,7 @@ WriteLiteral(">\r\n user6
\r\n WriteLiteral(" "); - #line 294 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 437 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(ActiveDirectory.Context.PrimaryDomain.NetBiosName); @@ -928,7 +1312,7 @@ WriteLiteral(" class=\"code\""); WriteLiteral(">user6,smi0099,"); - #line 296 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 439 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(ActiveDirectory.Context.PrimaryDomain.NetBiosName); @@ -941,7 +1325,7 @@ WriteLiteral(" class=\"code\""); WriteLiteral(">user6;smi0099;"); - #line 297 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 440 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(ActiveDirectory.Context.PrimaryDomain.NetBiosName); @@ -1016,7 +1400,7 @@ WriteLiteral(" \r\n"); - #line 166 "..\..\Views\User\UserParts\_Flags.cshtml" + #line 174 "..\..\Views\User\UserParts\_Flags.cshtml" } else { @@ -605,7 +666,7 @@ WriteLiteral(" class=\"none\""); WriteLiteral(">This user has no associated flags\r\n"); - #line 170 "..\..\Views\User\UserParts\_Flags.cshtml" + #line 178 "..\..\Views\User\UserParts\_Flags.cshtml" } @@ -615,7 +676,7 @@ WriteLiteral("