From 53e57d4017064e76ad37bdc6a2bebe49a8b43151 Mon Sep 17 00:00:00 2001 From: Gary Sharp Date: Sat, 11 Nov 2023 20:04:52 +1100 Subject: [PATCH] feature: user flag assignment exporting --- Disco.Models/Disco.Models.csproj | 3 + .../Users/UserFlags/UserFlagExportOptions.cs | 77 ++ .../Users/UserFlags/UserFlagExportRecord.cs | 12 + .../UserFlag/ConfigUserFlagExportModel.cs | 17 + Disco.Services/Authorization/Claims.cs | 8 + .../Configuration/UserFlag/UserFlagClaims.cs | 2 + Disco.Services/Disco.Services.csproj | 2 + .../Users/UserFlags/UserFlagExport.cs | 176 +++++ .../Users/UserFlags/UserFlagExportTask.cs | 46 ++ .../API/Controllers/UserFlagController.cs | 54 ++ .../Areas/Config/ConfigAreaRegistration.cs | 5 + .../Config/Controllers/UserFlagController.cs | 46 +- .../Config/Models/UserFlag/ExportModel.cs | 17 + .../Areas/Config/Views/UserFlag/Export.cshtml | 185 +++++ .../Config/Views/UserFlag/Export.generated.cs | 707 ++++++++++++++++++ .../Areas/Config/Views/UserFlag/Index.cshtml | 12 +- .../Config/Views/UserFlag/Index.generated.cs | 64 +- .../Areas/Config/Views/UserFlag/Show.cshtml | 15 +- .../Config/Views/UserFlag/Show.generated.cs | 354 +++++---- Disco.Web/ClientSource/Style/Config.css | 28 + Disco.Web/ClientSource/Style/Config.less | 40 + Disco.Web/ClientSource/Style/Config.min.css | 2 +- Disco.Web/Disco.Web.csproj | 11 + .../T4MVC/API.UserFlagController.generated.cs | 56 ++ .../Config.UserFlagController.generated.cs | 34 + 25 files changed, 1790 insertions(+), 183 deletions(-) create mode 100644 Disco.Models/Services/Users/UserFlags/UserFlagExportOptions.cs create mode 100644 Disco.Models/Services/Users/UserFlags/UserFlagExportRecord.cs create mode 100644 Disco.Models/UI/Config/UserFlag/ConfigUserFlagExportModel.cs create mode 100644 Disco.Services/Users/UserFlags/UserFlagExport.cs create mode 100644 Disco.Services/Users/UserFlags/UserFlagExportTask.cs create mode 100644 Disco.Web/Areas/Config/Models/UserFlag/ExportModel.cs create mode 100644 Disco.Web/Areas/Config/Views/UserFlag/Export.cshtml create mode 100644 Disco.Web/Areas/Config/Views/UserFlag/Export.generated.cs diff --git a/Disco.Models/Disco.Models.csproj b/Disco.Models/Disco.Models.csproj index 3d8aa26c..1349a79a 100644 --- a/Disco.Models/Disco.Models.csproj +++ b/Disco.Models/Disco.Models.csproj @@ -158,6 +158,8 @@ + + @@ -199,6 +201,7 @@ + diff --git a/Disco.Models/Services/Users/UserFlags/UserFlagExportOptions.cs b/Disco.Models/Services/Users/UserFlags/UserFlagExportOptions.cs new file mode 100644 index 00000000..fa02a554 --- /dev/null +++ b/Disco.Models/Services/Users/UserFlags/UserFlagExportOptions.cs @@ -0,0 +1,77 @@ +using Disco.Models.Exporting; +using Disco.Models.Services.Devices.Exporting; +using Disco.Models.Services.Exporting; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Disco.Models.Services.Users.UserFlags +{ + public class UserFlagExportOptions : IExportOptions + { + public ExportFormat Format { get; set; } + public string FilenamePrefix { get; } = "DiscoUserFlagExport"; + public string ExcelWorksheetName { get; } = "UserFlagExport"; + public string ExcelTableName { get; } = "UserFlags"; + + [Required] + public List UserFlagIds { get; set; } = new List(); + + [DisplayAttribute(Name = "Current Only")] + public bool CurrentOnly { get; set; } + + // User Flag + [Display(ShortName = "User Flag", Name = "Identifier", Description = "The identifier of the user flag")] + public bool Id { get; set; } + [Display(ShortName = "User Flag", Name = "Name", Description = "The name of the user flag")] + public bool Name { get; set; } + [Display(ShortName = "User Flag", Name = "Description", Description = "The description of the user flag")] + public bool Description { get; set; } + [Display(ShortName = "User Flag", Name = "Icon", Description = "The icon assigned to the user flag")] + public bool Icon { get; set; } + [Display(ShortName = "User Flag", Name = "Icon Colour", Description = "The icon colour assigned to the user flag")] + public bool IconColour { get; set; } + [Display(ShortName = "User Flag", Name = "Assignment Identifier", Description = "The identifier of the user flag assignment")] + public bool AssignmentId { get; set; } + [Display(ShortName = "User Flag", Name = "Added Date", Description = "The date the user flag was assigned to the user")] + public bool AddedDate { get; set; } + [Display(ShortName = "User Flag", Name = "Added User Identifier", Description = "The identifier of the user who assigned the user flag")] + public bool AddedUserId { get; set; } + [Display(ShortName = "User Flag", Name = "Removed Date", Description = "The date the user flag was unassigned from the user")] + public bool RemovedDate { get; set; } + [Display(ShortName = "User Flag", Name = "Removed User Identifier", Description = "The identifier of the user who unassigned the user flag")] + public bool RemovedUserId { get; set; } + [Display(ShortName = "User Flag", Name = "Comments", Description = "The comments associated with the user flag assignment")] + public bool Comments { get; set; } + + + // User + [Display(ShortName = "User", Name = "Identifier", Description = "The identifier of the user assigned to the user flag")] + public bool UserId { get; set; } + [Display(ShortName = "User", Name = "Display Name", Description = "The display name of the user assigned to the user flag")] + public bool UserDisplayName { get; set; } + [Display(ShortName = "User", Name = "Surname", Description = "The surname of the user assigned to the user flag")] + public bool UserSurname { get; set; } + [Display(ShortName = "User", Name = "Given Name", Description = "The given name of the user assigned to the user flag")] + public bool UserGivenName { get; set; } + [Display(ShortName = "User", Name = "Phone Number", Description = "The phone number of the user assigned to the user flag")] + public bool UserPhoneNumber { get; set; } + [Display(ShortName = "User", Name = "Email Address", Description = "The email address of the user assigned to the user flag")] + public bool UserEmailAddress { get; set; } + [Display(ShortName = "User", Name = "Custom Details", Description = "The custom details provided by plugins for the user assigned to the user flag")] + public bool UserDetailCustom { get; set; } + + public static UserFlagExportOptions DefaultOptions() + { + return new UserFlagExportOptions() + { + Format = ExportFormat.Xlsx, + CurrentOnly = true, + Name = true, + AddedDate = true, + UserId = true, + UserDisplayName = true, + Comments = true, + }; + } + } +} diff --git a/Disco.Models/Services/Users/UserFlags/UserFlagExportRecord.cs b/Disco.Models/Services/Users/UserFlags/UserFlagExportRecord.cs new file mode 100644 index 00000000..fee6d99c --- /dev/null +++ b/Disco.Models/Services/Users/UserFlags/UserFlagExportRecord.cs @@ -0,0 +1,12 @@ +using Disco.Models.Exporting; +using Disco.Models.Repository; +using System.Collections.Generic; + +namespace Disco.Models.Services.Users.UserFlags +{ + public class UserFlagExportRecord : IExportRecord + { + public UserFlagAssignment Assignment { get; set; } + public Dictionary UserCustomDetails { get; set; } + } +} diff --git a/Disco.Models/UI/Config/UserFlag/ConfigUserFlagExportModel.cs b/Disco.Models/UI/Config/UserFlag/ConfigUserFlagExportModel.cs new file mode 100644 index 00000000..c490760b --- /dev/null +++ b/Disco.Models/UI/Config/UserFlag/ConfigUserFlagExportModel.cs @@ -0,0 +1,17 @@ +using Disco.Models.Services.Exporting; +using Disco.Models.Services.Users.UserFlags; +using Disco.Models.UI; +using System.Collections.Generic; + +namespace Disco.Models.Areas.Config.UI.UserFlag +{ + public interface ConfigUserFlagExportModel : BaseUIModel + { + UserFlagExportOptions Options { get; set; } + + string ExportSessionId { get; set; } + ExportResult ExportSessionResult { get; set; } + + List UserFlags { get; set; } + } +} diff --git a/Disco.Services/Authorization/Claims.cs b/Disco.Services/Authorization/Claims.cs index b0b59012..6452cdf1 100644 --- a/Disco.Services/Authorization/Claims.cs +++ b/Disco.Services/Authorization/Claims.cs @@ -77,6 +77,7 @@ namespace Disco.Services.Authorization { "Config.UserFlag.Configure", new Tuple, Action, string, string, bool>(c => c.Config.UserFlag.Configure, (c, v) => c.Config.UserFlag.Configure = v, "Configure User Flags", "Can configure user flags", false) }, { "Config.UserFlag.Create", new Tuple, Action, string, string, bool>(c => c.Config.UserFlag.Create, (c, v) => c.Config.UserFlag.Create = v, "Create User Flags", "Can create user flags", false) }, { "Config.UserFlag.Delete", new Tuple, Action, string, string, bool>(c => c.Config.UserFlag.Delete, (c, v) => c.Config.UserFlag.Delete = v, "Delete User Flags", "Can delete user flags", false) }, + { "Config.UserFlag.Export", new Tuple, Action, string, string, bool>(c => c.Config.UserFlag.Export, (c, v) => c.Config.UserFlag.Export = v, "Export User Flag Assignments", "Can export user flag assignments", false) }, { "Config.UserFlag.Show", new Tuple, Action, string, string, bool>(c => c.Config.UserFlag.Show, (c, v) => c.Config.UserFlag.Show = v, "Show User Flags", "Can show user flags", false) }, { "Config.Show", new Tuple, Action, string, string, bool>(c => c.Config.Show, (c, v) => c.Config.Show = v, "Show Configuration", "Can show the configuration menu", false) }, { "Job.Lists.AllOpen", new Tuple, Action, string, string, bool>(c => c.Job.Lists.AllOpen, (c, v) => c.Job.Lists.AllOpen = v, "All Open List", "Can show list", false) }, @@ -306,6 +307,7 @@ namespace Disco.Services.Authorization new ClaimNavigatorItem("Config.UserFlag.Configure", false), new ClaimNavigatorItem("Config.UserFlag.Create", false), new ClaimNavigatorItem("Config.UserFlag.Delete", false), + new ClaimNavigatorItem("Config.UserFlag.Export", false), new ClaimNavigatorItem("Config.UserFlag.Show", false) }), new ClaimNavigatorItem("Config.Show", false) @@ -593,6 +595,7 @@ namespace Disco.Services.Authorization c.Config.UserFlag.Configure = true; c.Config.UserFlag.Create = true; c.Config.UserFlag.Delete = true; + c.Config.UserFlag.Export = true; c.Config.UserFlag.Show = true; c.Config.Show = true; c.Job.Lists.AllOpen = true; @@ -1109,6 +1112,11 @@ namespace Disco.Services.Authorization /// public const string Delete = "Config.UserFlag.Delete"; + /// Export User Flag Assignments + /// Can export user flag assignments + /// + public const string Export = "Config.UserFlag.Export"; + /// Show User Flags /// Can show user flags /// diff --git a/Disco.Services/Authorization/Roles/ClaimGroups/Configuration/UserFlag/UserFlagClaims.cs b/Disco.Services/Authorization/Roles/ClaimGroups/Configuration/UserFlag/UserFlagClaims.cs index 3ee39a51..633563fd 100644 --- a/Disco.Services/Authorization/Roles/ClaimGroups/Configuration/UserFlag/UserFlagClaims.cs +++ b/Disco.Services/Authorization/Roles/ClaimGroups/Configuration/UserFlag/UserFlagClaims.cs @@ -11,6 +11,8 @@ [ClaimDetails("Delete User Flags", "Can delete user flags")] public bool Delete { get; set; } + [ClaimDetails("Export User Flag Assignments", "Can export user flag assignments")] + public bool Export { get; set; } [ClaimDetails("Show User Flags", "Can show user flags")] public bool Show { get; set; } diff --git a/Disco.Services/Disco.Services.csproj b/Disco.Services/Disco.Services.csproj index f59daff6..6b73ec03 100644 --- a/Disco.Services/Disco.Services.csproj +++ b/Disco.Services/Disco.Services.csproj @@ -461,6 +461,8 @@ + + diff --git a/Disco.Services/Users/UserFlags/UserFlagExport.cs b/Disco.Services/Users/UserFlags/UserFlagExport.cs new file mode 100644 index 00000000..97c6fcd9 --- /dev/null +++ b/Disco.Services/Users/UserFlags/UserFlagExport.cs @@ -0,0 +1,176 @@ +using Disco.Data.Repository; +using Disco.Models.Exporting; +using Disco.Models.Services.Exporting; +using Disco.Models.Services.Users.UserFlags; +using Disco.Services.Plugins.Features.DetailsProvider; +using Disco.Services.Tasks; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Data.Entity; +using System.Linq; + +namespace Disco.Services.Users.UserFlags +{ + using Metadata = ExportFieldMetadata; + + public class UserFlagExport + { + private readonly DiscoDataContext database; + private readonly UserFlagExportOptions options; + + public UserFlagExport(DiscoDataContext database, UserFlagExportOptions options) + { + this.database = database; + this.options = options; + } + + public ExportResult Generate(IScheduledTaskStatus status) + { + var records = BuildRecords(status); + + var metadata = BuildMetadata(records, status); + + if (metadata.Count == 0) + throw new ArgumentException("At least one export field must be specified", nameof(options)); + + status.UpdateStatus(90, $"Formatting {records.Count} records for export"); + return ExportHelpers.WriteExport(options, status, metadata, records); + } + + private List BuildRecords(IScheduledTaskStatus status) + { + var query = database.UserFlagAssignments + .Include(a => a.User.UserDetails) + .Include(a => a.UserFlag) + .Where(a => options.UserFlagIds.Contains(a.UserFlagId)); + + if (options.CurrentOnly) + { + query = query.Where(a => !a.RemovedDate.HasValue); + } + + // Update Users + if (options.UserDisplayName || + options.UserSurname || + options.UserGivenName || + options.UserPhoneNumber || + options.UserEmailAddress) + { + status.UpdateStatus(5, "Refreshing user details from Active Directory"); + var userIds = query.Select(d => d.UserId).Distinct().ToList(); + foreach (var userId in userIds) + { + try + { + UserService.GetUser(userId, database); + } + catch (Exception) { } // Ignore Errors + } + } + + status.UpdateStatus(15, "Extracting records from the database"); + + var records = query.Select(a => new UserFlagExportRecord() + { + Assignment = a + }).ToList(); + + if (options.UserDetailCustom) + { + status.UpdateStatus(50, "Extracting custom user detail records"); + + var detailsService = new DetailsProviderService(database); + var cache = new Dictionary>(StringComparer.Ordinal); + foreach (var record in records) + { + if (!cache.TryGetValue(record.Assignment.UserId, out var details)) + details = detailsService.GetDetails(record.Assignment.User); + record.UserCustomDetails = details; + } + } + + return records; + } + + private List BuildMetadata(List records, IScheduledTaskStatus status) + { + status.UpdateStatus(80, "Building metadata"); + + IEnumerable userDetailCustomKeys = null; + if (options.UserDetailCustom) + userDetailCustomKeys = records.Where(r => r.UserCustomDetails != null).SelectMany(r => r.UserCustomDetails.Keys).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); + + var accessors = BuildAccessors(userDetailCustomKeys); + + return typeof(UserFlagExportOptions).GetProperties() + .Where(p => p.PropertyType == typeof(bool)) + .Select(p => new + { + property = p, + details = (DisplayAttribute)p.GetCustomAttributes(typeof(DisplayAttribute), false).FirstOrDefault() + }) + .Where(p => p.details != null && p.property.Name != nameof(options.CurrentOnly) && (bool)p.property.GetValue(options)) + .SelectMany(p => + { + var fieldMetadata = accessors[p.property.Name]; + fieldMetadata.ForEach(f => + { + if (f.ColumnName == null) + f.ColumnName = (p.details.ShortName == "User Flag") ? p.details.Name : $"{p.details.ShortName} {p.details.Name}"; + }); + return fieldMetadata; + }).ToList(); + } + + private static Dictionary> BuildAccessors(IEnumerable userDetailsCustomKeys) + { + const string DateFormat = "yyyy-MM-dd"; + const string DateTimeFormat = DateFormat + " HH:mm:ss"; + + Func csvStringEncoded = (o) => o == null ? null : $"\"{((string)o).Replace("\"", "\"\"")}\""; + Func csvToStringEncoded = (o) => o == null ? null : o.ToString(); + Func csvCurrencyEncoded = (o) => ((decimal?)o).HasValue ? ((decimal?)o).Value.ToString("C") : null; + Func csvDateEncoded = (o) => ((DateTime)o).ToString(DateFormat); + Func csvDateTimeEncoded = (o) => ((DateTime)o).ToString(DateTimeFormat); + Func csvNullableDateEncoded = (o) => ((DateTime?)o).HasValue ? csvDateEncoded(o) : null; + Func csvNullableDateTimeEncoded = (o) => ((DateTime?)o).HasValue ? csvDateTimeEncoded(o) : null; + + var metadata = new Dictionary>(); + + // User Flag + metadata.Add(nameof(UserFlagExportOptions.Id), new List() { new Metadata(nameof(UserFlagExportOptions.Id), typeof(string), r => r.Assignment.UserFlagId, csvToStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.Name), new List() { new Metadata(nameof(UserFlagExportOptions.Name), typeof(string), r => r.Assignment.UserFlag.Name, csvStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.Description), new List() { new Metadata(nameof(UserFlagExportOptions.Description), typeof(string), r => r.Assignment.UserFlag.Description, csvStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.Icon), new List() { new Metadata(nameof(UserFlagExportOptions.Icon), typeof(string), r => r.Assignment.UserFlag.Icon, csvStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.IconColour), new List() { new Metadata(nameof(UserFlagExportOptions.IconColour), typeof(string), r => r.Assignment.UserFlag.IconColour, csvStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.AssignmentId), new List() { new Metadata(nameof(UserFlagExportOptions.AssignmentId), typeof(string), r => r.Assignment.Id, csvToStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.AddedDate), new List() { new Metadata(nameof(UserFlagExportOptions.AddedDate), typeof(string), r => r.Assignment.AddedDate, csvDateTimeEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.AddedUserId), new List() { new Metadata(nameof(UserFlagExportOptions.AddedUserId), typeof(string), r => r.Assignment.AddedUserId, csvStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.RemovedUserId), new List() { new Metadata(nameof(UserFlagExportOptions.RemovedUserId), typeof(string), r => r.Assignment.RemovedUserId, csvStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.RemovedDate), new List() { new Metadata(nameof(UserFlagExportOptions.RemovedDate), typeof(string), r => r.Assignment.RemovedDate, csvNullableDateTimeEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.Comments), new List() { new Metadata(nameof(UserFlagExportOptions.Comments), typeof(string), r => r.Assignment.Comments, csvStringEncoded) }); + + // User + metadata.Add(nameof(UserFlagExportOptions.UserId), new List() { new Metadata(nameof(UserFlagExportOptions.UserId), typeof(string), r => r.Assignment.User?.UserId, csvStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.UserDisplayName), new List() { new Metadata(nameof(UserFlagExportOptions.UserDisplayName), typeof(string), r => r.Assignment.User?.DisplayName, csvStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.UserSurname), new List() { new Metadata(nameof(UserFlagExportOptions.UserSurname), typeof(string), r => r.Assignment.User?.Surname, csvStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.UserGivenName), new List() { new Metadata(nameof(UserFlagExportOptions.UserGivenName), typeof(string), r => r.Assignment.User?.GivenName, csvStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.UserPhoneNumber), new List() { new Metadata(nameof(UserFlagExportOptions.UserPhoneNumber), typeof(string), r => r.Assignment.User?.PhoneNumber, csvStringEncoded) }); + metadata.Add(nameof(UserFlagExportOptions.UserEmailAddress), new List() { new Metadata(nameof(UserFlagExportOptions.UserEmailAddress), typeof(string), r => r.Assignment.User?.EmailAddress, csvStringEncoded) }); + if (userDetailsCustomKeys != null) + { + var userDetailCustomFields = new List(); + foreach (var detailKey in userDetailsCustomKeys.OrderBy(k => k, StringComparer.OrdinalIgnoreCase)) + { + var key = detailKey; + userDetailCustomFields.Add(new Metadata(detailKey, detailKey, typeof(string), r => r.UserCustomDetails != null && r.UserCustomDetails.TryGetValue(key, out var value) ? value : null, csvStringEncoded)); + } + metadata.Add(nameof(UserFlagExportOptions.UserDetailCustom), userDetailCustomFields); + } + + return metadata; + } + + } +} diff --git a/Disco.Services/Users/UserFlags/UserFlagExportTask.cs b/Disco.Services/Users/UserFlags/UserFlagExportTask.cs new file mode 100644 index 00000000..9ecc725b --- /dev/null +++ b/Disco.Services/Users/UserFlags/UserFlagExportTask.cs @@ -0,0 +1,46 @@ +using Disco.Data.Repository; +using Disco.Models.Services.Users.UserFlags; +using Disco.Services.Exporting; +using Disco.Services.Tasks; +using Quartz; + +namespace Disco.Services.Users.UserFlags +{ + public class UserFlagExportTask : ScheduledTask + { + private const string JobDataMapContext = "Context"; + + public override string TaskName { get; } = "Export User Flags"; + public override bool SingleInstanceTask { get { return false; } } + public override bool CancelInitiallySupported { get { return false; } } + + public static ExportTaskContext ScheduleNow(UserFlagExportOptions options) + { + // Build Context + var context = new ExportTaskContext(options); + + // Build Data Map + var task = new UserFlagExportTask(); + JobDataMap taskData = new JobDataMap() { { JobDataMapContext, context } }; + + // Schedule Task + context.TaskStatus = task.ScheduleTask(taskData); + + return context; + } + + protected override void ExecuteTask() + { + var context = (ExportTaskContext)ExecutionContext.JobDetail.JobDataMap[JobDataMapContext]; + + Status.UpdateStatus(10, "Exporting User Flag Records", "Starting..."); + + using (DiscoDataContext Database = new DiscoDataContext()) + { + var export = new UserFlagExport(Database, context.Options); + + context.Result = export.Generate(Status); + } + } + } +} diff --git a/Disco.Web/Areas/API/Controllers/UserFlagController.cs b/Disco.Web/Areas/API/Controllers/UserFlagController.cs index a07e6208..8baabf27 100644 --- a/Disco.Web/Areas/API/Controllers/UserFlagController.cs +++ b/Disco.Web/Areas/API/Controllers/UserFlagController.cs @@ -1,12 +1,18 @@ using Disco.Models.Repository; +using Disco.Models.Services.Users.UserFlags; using Disco.Services; using Disco.Services.Authorization; +using Disco.Services.Exporting; using Disco.Services.Interop.ActiveDirectory; using Disco.Services.Tasks; using Disco.Services.Users.UserFlags; using Disco.Services.Web; +using Disco.Web.Areas.Config.Models.UserFlag; +using Disco.Web.Extensions; using System; using System.Linq; +using System.Web; +using System.Web.Caching; using System.Web.Mvc; namespace Disco.Web.Areas.API.Controllers @@ -401,5 +407,53 @@ namespace Disco.Web.Areas.API.Controllers return Json(assignedUsers, JsonRequestBehavior.AllowGet); } #endregion + + #region Exporting + internal const string ExportSessionCacheKey = "UserFlagExportContext_{0}"; + + [DiscoAuthorize(Claims.Config.UserFlag.Export)] + public virtual ActionResult Export(ExportModel Model) + { + if (Model == null || Model.Options == null) + throw new ArgumentNullException(nameof(Model)); + + // Start Export + var exportContext = UserFlagExportTask.ScheduleNow(Model.Options); + + // Store Export Context in Web Cache + string key = string.Format(ExportSessionCacheKey, exportContext.TaskStatus.SessionId); + HttpRuntime.Cache.Insert(key, exportContext, null, DateTime.Now.AddMinutes(60), Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null); + + // Set Task Finished Url + var finishedActionResult = MVC.Config.UserFlag.Export(exportContext.TaskStatus.SessionId, null, null); + exportContext.TaskStatus.SetFinishedUrl(Url.Action(finishedActionResult)); + + // Try waiting for completion + if (exportContext.TaskStatus.WaitUntilFinished(TimeSpan.FromSeconds(2))) + return RedirectToAction(finishedActionResult); + else + return RedirectToAction(MVC.Config.Logging.TaskStatus(exportContext.TaskStatus.SessionId)); + } + [DiscoAuthorize(Claims.Config.UserFlag.Export)] + public virtual ActionResult ExportRetrieve(string Id) + { + if (string.IsNullOrWhiteSpace(Id)) + throw new ArgumentNullException("Id"); + + string key = string.Format(ExportSessionCacheKey, Id); + var context = HttpRuntime.Cache.Get(key) as ExportTaskContext; + + if (context == null) + throw new ArgumentException("The Id specified is invalid, or the export data expired (60 minutes)", nameof(Id)); + + if (context.Result == null || context.Result.Result == null) + throw new ArgumentException("The export session is still running, or failed to complete successfully", nameof(Id)); + + var fileStream = context.Result.Result; + + return this.File(fileStream.GetBuffer(), 0, (int)fileStream.Length, context.Result.MimeType, context.Result.Filename); + } + + #endregion } } \ No newline at end of file diff --git a/Disco.Web/Areas/Config/ConfigAreaRegistration.cs b/Disco.Web/Areas/Config/ConfigAreaRegistration.cs index 783c1534..41660a3c 100644 --- a/Disco.Web/Areas/Config/ConfigAreaRegistration.cs +++ b/Disco.Web/Areas/Config/ConfigAreaRegistration.cs @@ -129,6 +129,11 @@ namespace Disco.Web.Areas.Config "Config/UserFlag/Create", new { controller = "UserFlag", action = "Create", id = UrlParameter.Optional } ); + context.MapRoute( + "Config_UserFlag_Export", + "Config/UserFlag/Export", + new { controller = "UserFlag", action = "Export", id = UrlParameter.Optional } + ); context.MapRoute( "Config_UserFlag", "Config/UserFlag/{id}", diff --git a/Disco.Web/Areas/Config/Controllers/UserFlagController.cs b/Disco.Web/Areas/Config/Controllers/UserFlagController.cs index 944d4d58..eb261bfb 100644 --- a/Disco.Web/Areas/Config/Controllers/UserFlagController.cs +++ b/Disco.Web/Areas/Config/Controllers/UserFlagController.cs @@ -1,12 +1,19 @@ -using Disco.Models.Repository; +using Disco.Models.Areas.Config.UI.UserFlag; +using Disco.Models.Repository; +using Disco.Models.Services.Devices.Exporting; +using Disco.Models.Services.Users.UserFlags; using Disco.Models.UI.Config.UserFlag; using Disco.Services.Authorization; +using Disco.Services.Exporting; using Disco.Services.Extensions; using Disco.Services.Plugins.Features.UIExtension; using Disco.Services.Users.UserFlags; using Disco.Services.Web; +using Disco.Web.Areas.Config.Models.UserFlag; using System; +using System.Collections.Generic; using System.Linq; +using System.Web; using System.Web.Mvc; namespace Disco.Web.Areas.Config.Controllers @@ -114,5 +121,42 @@ namespace Disco.Web.Areas.Config.Controllers return View(model); } + + #region Export + + [DiscoAuthorizeAny(Claims.Config.UserFlag.Export), HttpGet] + public virtual ActionResult Export(string DownloadId, int? UserFlagId, bool? CurrentOnly) + { + var m = new ExportModel() + { + Options = UserFlagExportOptions.DefaultOptions(), + UserFlags = UserFlagService.GetUserFlags(), + }; + + if (!string.IsNullOrWhiteSpace(DownloadId)) + { + string key = string.Format(API.Controllers.UserFlagController.ExportSessionCacheKey, DownloadId); + var context = HttpRuntime.Cache.Get(key) as ExportTaskContext; + + if (context != null) + { + m.ExportSessionResult = context.Result; + m.ExportSessionId = DownloadId; + } + } + + if (UserFlagId.HasValue && CurrentOnly.HasValue) + { + m.Options.UserFlagIds = new List() { UserFlagId.Value }; + m.Options.CurrentOnly = CurrentOnly.Value; + } + + // UI Extensions + UIExtensions.ExecuteExtensions(this.ControllerContext, m); + + return View(m); + } + + #endregion } } \ No newline at end of file diff --git a/Disco.Web/Areas/Config/Models/UserFlag/ExportModel.cs b/Disco.Web/Areas/Config/Models/UserFlag/ExportModel.cs new file mode 100644 index 00000000..0a3b8398 --- /dev/null +++ b/Disco.Web/Areas/Config/Models/UserFlag/ExportModel.cs @@ -0,0 +1,17 @@ +using Disco.Models.Areas.Config.UI.UserFlag; +using Disco.Models.Services.Exporting; +using Disco.Models.Services.Users.UserFlags; +using System.Collections.Generic; + +namespace Disco.Web.Areas.Config.Models.UserFlag +{ + public class ExportModel : ConfigUserFlagExportModel + { + public UserFlagExportOptions Options { get; set; } + + public string ExportSessionId { get; set; } + public ExportResult ExportSessionResult { get; set; } + + public List UserFlags { get; set; } + } +} diff --git a/Disco.Web/Areas/Config/Views/UserFlag/Export.cshtml b/Disco.Web/Areas/Config/Views/UserFlag/Export.cshtml new file mode 100644 index 00000000..e84d2d0f --- /dev/null +++ b/Disco.Web/Areas/Config/Views/UserFlag/Export.cshtml @@ -0,0 +1,185 @@ +@using Disco.Web.Areas.Config.Models.UserFlag; +@model ExportModel +@{ + Authorization.RequireAny(Claims.Config.UserFlag.Export); + + ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "User Flags", MVC.Config.UserFlag.Index(null), "Export"); + + var optionsMetadata = ModelMetadata.FromLambdaExpression(m => m.Options, ViewData); + var optionGroups = optionsMetadata.Properties.Where(p => p.ShortDisplayName != null && p.ModelType == typeof(bool) && p.PropertyName != "CurrentOnly") + .GroupBy(m => m.ShortDisplayName); +} +
+ @using (Html.BeginForm(MVC.API.UserFlag.Export())) + { +
+

Export Scope

+ + + + + + + + + + + + + +
+ User Flags: + + @foreach (var userFlag in Model.UserFlags) + { +
+ +
+ } +
@Html.LabelFor(m => m.Options.CurrentOnly) + @Html.CheckBoxFor(m => m.Options.CurrentOnly) +

Uncheck to include all historical user flag assignments.

+
@Html.LabelFor(m => m.Options.Format) + @Html.DropDownListFor(m => m.Options.Format, Enum.GetNames(typeof(Disco.Models.Exporting.ExportFormat)).Select(v => new SelectListItem() { Value = v, Text = v })) +
+
+
+

Export Fields (Defaults)

+ + @foreach (var optionGroup in optionGroups) + { + var optionFields = optionGroup.ToList(); + var itemsPerColumn = (int)Math.Ceiling((double)optionFields.Count / 2); + + + + + } +
+ @optionGroup.Key + @if (optionFields.Count > 2) + { + ALL | NONE + } + +
+ + + + + +
+
    + @foreach (var optionItem in optionFields.Take(itemsPerColumn)) + { +
  • +
  • + } +
+
+
    + @foreach (var optionItem in optionFields.Skip(itemsPerColumn)) + { +
  • +
  • + } +
+
+
+
+
+ + } +
+@if (Model.ExportSessionId != null) +{ +
+

@Model.ExportSessionResult.RecordCount record@(Model.ExportSessionResult.RecordCount != 1 ? "s" : null) were successfully exported.

+ Download User Flag Export +
+ +} +
+

Exporting user flags...

+
+ diff --git a/Disco.Web/Areas/Config/Views/UserFlag/Export.generated.cs b/Disco.Web/Areas/Config/Views/UserFlag/Export.generated.cs new file mode 100644 index 00000000..0ef76b52 --- /dev/null +++ b/Disco.Web/Areas/Config/Views/UserFlag/Export.generated.cs @@ -0,0 +1,707 @@ +#pragma warning disable 1591 +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Disco.Web.Areas.Config.Views.UserFlag +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Text; + using System.Web; + using System.Web.Helpers; + using System.Web.Mvc; + using System.Web.Mvc.Ajax; + using System.Web.Mvc.Html; + using System.Web.Routing; + using System.Web.Security; + using System.Web.UI; + using System.Web.WebPages; + using Disco; + using Disco.Models.Repository; + using Disco.Services; + using Disco.Services.Authorization; + using Disco.Services.Web; + using Disco.Web; + + #line 1 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + using Disco.Web.Areas.Config.Models.UserFlag; + + #line default + #line hidden + using Disco.Web.Extensions; + + [System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "2.0.0.0")] + [System.Web.WebPages.PageVirtualPathAttribute("~/Areas/Config/Views/UserFlag/Export.cshtml")] + public partial class Export : Disco.Services.Web.WebViewPage + { + public Export() + { + } + public override void Execute() + { + + #line 3 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + + Authorization.RequireAny(Claims.Config.UserFlag.Export); + + ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "User Flags", MVC.Config.UserFlag.Index(null), "Export"); + + var optionsMetadata = ModelMetadata.FromLambdaExpression(m => m.Options, ViewData); + var optionGroups = optionsMetadata.Properties.Where(p => p.ShortDisplayName != null && p.ModelType == typeof(bool) && p.PropertyName != "CurrentOnly") + .GroupBy(m => m.ShortDisplayName); + + + #line default + #line hidden +WriteLiteral("\r\n\r\n"); + + + #line 13 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + + + #line default + #line hidden + + #line 13 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + using (Html.BeginForm(MVC.API.UserFlag.Export())) + { + + + #line default + #line hidden +WriteLiteral(" \r\n

Export Scope

\r\n \r\n \r\n" + +" \r\n User Flags:\r\n \r\n " + +" \r\n \r\n \r\n " + +" \r\n \r\n \r\n " + +"\r\n \r\n \r\n \r\n
\r\n"); + + + #line 23 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + + + #line default + #line hidden + + #line 23 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + foreach (var userFlag in Model.UserFlags) + { + + + #line default + #line hidden +WriteLiteral("
\r\n \r\n \r\n"); + + + #line 32 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + } + + + #line default + #line hidden +WriteLiteral("
"); + + + #line 36 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + Write(Html.LabelFor(m => m.Options.CurrentOnly)); + + + #line default + #line hidden +WriteLiteral("\r\n"); + +WriteLiteral(" "); + + + #line 38 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + Write(Html.CheckBoxFor(m => m.Options.CurrentOnly)); + + + #line default + #line hidden +WriteLiteral("\r\n

Uncheck to include all historical user flag assignme" + +"nts.

\r\n
"); + + + #line 43 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + Write(Html.LabelFor(m => m.Options.Format)); + + + #line default + #line hidden +WriteLiteral("\r\n"); + +WriteLiteral(" "); + + + #line 45 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + Write(Html.DropDownListFor(m => m.Options.Format, Enum.GetNames(typeof(Disco.Models.Exporting.ExportFormat)).Select(v => new SelectListItem() { Value = v, Text = v }))); + + + #line default + #line hidden +WriteLiteral("\r\n
\r\n " + +" \r\n"); + +WriteLiteral(" \r\n

Export Fields (Defaults)

\r\n \r\n"); + + + #line 53 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + + + #line default + #line hidden + + #line 53 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + foreach (var optionGroup in optionGroups) + { + var optionFields = optionGroup.ToList(); + var itemsPerColumn = (int)Math.Ceiling((double)optionFields.Count / 2); + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n"); + +WriteLiteral(" "); + + + #line 59 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + Write(optionGroup.Key); + + + #line default + #line hidden +WriteLiteral("\r\n"); + + + #line 60 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + + + #line default + #line hidden + + #line 60 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + if (optionFields.Count > 2) + { + + + #line default + #line hidden +WriteLiteral(" ALL | NONE\r\n"); + + + #line 63 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n " + +" \r\n \r\n"); + + + #line 71 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + + + #line default + #line hidden + + #line 71 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + foreach (var optionItem in optionFields.Take(itemsPerColumn)) + { + + + #line default + #line hidden +WriteLiteral(" (optionItem.Description + + #line default + #line hidden +, 3832), false) +); + +WriteLiteral(">\r\n (optionItem.PropertyName + + #line default + #line hidden +, 3950), false) +); + +WriteAttribute("name", Tuple.Create(" name=\"", 3975), Tuple.Create("\"", 4014) +, Tuple.Create(Tuple.Create("", 3982), Tuple.Create("Options.", 3982), true) + + #line 74 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + , Tuple.Create(Tuple.Create("", 3990), Tuple.Create(optionItem.PropertyName + + #line default + #line hidden +, 3990), false) +); + +WriteLiteral(" value=\"true\""); + +WriteLiteral(" "); + + + #line 74 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + Write(((bool)optionItem.Model) ? "checked " : null); + + + #line default + #line hidden +WriteLiteral("/>(optionItem.PropertyName + + #line default + #line hidden +, 4098), false) +); + +WriteLiteral(">"); + + + #line 74 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + Write(optionItem.DisplayName); + + + #line default + #line hidden +WriteLiteral("\r\n"); + + + #line 75 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n " + +" \r\n \r\n \r\n"); + + + #line 80 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + + + #line default + #line hidden + + #line 80 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + foreach (var optionItem in optionFields.Skip(itemsPerColumn)) + { + + + #line default + #line hidden +WriteLiteral(" (optionItem.Description + + #line default + #line hidden +, 4665), false) +); + +WriteLiteral(">\r\n (optionItem.PropertyName + + #line default + #line hidden +, 4783), false) +); + +WriteAttribute("name", Tuple.Create(" name=\"", 4808), Tuple.Create("\"", 4847) +, Tuple.Create(Tuple.Create("", 4815), Tuple.Create("Options.", 4815), true) + + #line 83 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + , Tuple.Create(Tuple.Create("", 4823), Tuple.Create(optionItem.PropertyName + + #line default + #line hidden +, 4823), false) +); + +WriteLiteral(" value=\"true\""); + +WriteLiteral(" "); + + + #line 83 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + Write(((bool)optionItem.Model) ? "checked " : null); + + + #line default + #line hidden +WriteLiteral("/>(optionItem.PropertyName + + #line default + #line hidden +, 4931), false) +); + +WriteLiteral(">"); + + + #line 83 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + Write(optionItem.DisplayName); + + + #line default + #line hidden +WriteLiteral("\r\n"); + + + #line 84 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + } + + + #line default + #line hidden +WriteLiteral(@" + + +
\r\n " + +" \r\n \r\n
+ + + +"); + + + #line 92 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n"); + +WriteLiteral(" \r\n"); + + + #line 159 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + } + + + #line default + #line hidden +WriteLiteral("\r\n"); + + + #line 161 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + if (Model.ExportSessionId != null) +{ + + + #line default + #line hidden +WriteLiteral(" \r\n

"); + + + #line 164 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + Write(Model.ExportSessionResult.RecordCount); + + + #line default + #line hidden +WriteLiteral(" record"); + + + #line 164 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" + Write(Model.ExportSessionResult.RecordCount != 1 ? "s" : null); + + + #line default + #line hidden +WriteLiteral(" were successfully exported.

\r\n (Url.Action(MVC.API.UserFlag.ExportRetrieve(Model.ExportSessionId)) + + #line default + #line hidden +, 8233), false) +); + +WriteLiteral(" class=\"button\""); + +WriteLiteral(">Download User Flag Export\r\n \r\n"); + +WriteLiteral(@" +"); + + + #line 179 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" +} + + + #line default + #line hidden +WriteLiteral("\r\n

Exporting user flags...

\r\n\r\n\r\n Export User Flags\r\n\r\n"); + + } + } +} +#pragma warning restore 1591 diff --git a/Disco.Web/Areas/Config/Views/UserFlag/Index.cshtml b/Disco.Web/Areas/Config/Views/UserFlag/Index.cshtml index 759386c9..4649775a 100644 --- a/Disco.Web/Areas/Config/Views/UserFlag/Index.cshtml +++ b/Disco.Web/Areas/Config/Views/UserFlag/Index.cshtml @@ -37,7 +37,7 @@ @if (string.IsNullOrWhiteSpace(item.Description)) - { + { <none> } else @@ -65,10 +65,14 @@ } } +
+ @if (Authorization.Has(Claims.Config.UserFlag.Export) && Model.UserFlags.Count > 0) + { + @Html.ActionLinkButton("Export", MVC.Config.UserFlag.Export()) + } @if (Authorization.Has(Claims.Config.UserFlag.Create)) { -
- @Html.ActionLinkButton("Create User Flag", MVC.Config.UserFlag.Create()) -
+ @Html.ActionLinkButton("Create User Flag", MVC.Config.UserFlag.Create()) } +
\ No newline at end of file diff --git a/Disco.Web/Areas/Config/Views/UserFlag/Index.generated.cs b/Disco.Web/Areas/Config/Views/UserFlag/Index.generated.cs index 0c406bc2..077513ae 100644 --- a/Disco.Web/Areas/Config/Views/UserFlag/Index.generated.cs +++ b/Disco.Web/Areas/Config/Views/UserFlag/Index.generated.cs @@ -197,7 +197,7 @@ WriteLiteral("\r\n \r\n \r\n #line 39 "..\..\Areas\Config\Views\UserFlag\Index.cshtml" if (string.IsNullOrWhiteSpace(item.Description)) - { + { #line default @@ -342,41 +342,67 @@ WriteLiteral(" \r\n"); #line default #line hidden -WriteLiteral(" "); - - - #line 68 "..\..\Areas\Config\Views\UserFlag\Index.cshtml" - if (Authorization.Has(Claims.Config.UserFlag.Create)) - { - - - #line default - #line hidden -WriteLiteral(" \r\n"); -WriteLiteral(" "); - + + #line 69 "..\..\Areas\Config\Views\UserFlag\Index.cshtml" + + + #line default + #line hidden + + #line 69 "..\..\Areas\Config\Views\UserFlag\Index.cshtml" + if (Authorization.Has(Claims.Config.UserFlag.Export) && Model.UserFlags.Count > 0) + { + + + #line default + #line hidden #line 71 "..\..\Areas\Config\Views\UserFlag\Index.cshtml" - Write(Html.ActionLinkButton("Create User Flag", MVC.Config.UserFlag.Create())); + Write(Html.ActionLinkButton("Export", MVC.Config.UserFlag.Export())); #line default #line hidden -WriteLiteral("\r\n \r\n"); - - #line 73 "..\..\Areas\Config\Views\UserFlag\Index.cshtml" + #line 71 "..\..\Areas\Config\Views\UserFlag\Index.cshtml" + } #line default #line hidden -WriteLiteral(""); +WriteLiteral(" "); + + + #line 73 "..\..\Areas\Config\Views\UserFlag\Index.cshtml" + if (Authorization.Has(Claims.Config.UserFlag.Create)) + { + + + #line default + #line hidden + + #line 75 "..\..\Areas\Config\Views\UserFlag\Index.cshtml" + Write(Html.ActionLinkButton("Create User Flag", MVC.Config.UserFlag.Create())); + + + #line default + #line hidden + + #line 75 "..\..\Areas\Config\Views\UserFlag\Index.cshtml" + + } + + + #line default + #line hidden +WriteLiteral("\r\n"); } } diff --git a/Disco.Web/Areas/Config/Views/UserFlag/Show.cshtml b/Disco.Web/Areas/Config/Views/UserFlag/Show.cshtml index cb5124bd..3764d4e2 100644 --- a/Disco.Web/Areas/Config/Views/UserFlag/Show.cshtml +++ b/Disco.Web/Areas/Config/Views/UserFlag/Show.cshtml @@ -11,6 +11,8 @@ var canDelete = Authorization.Has(Claims.Config.UserFlag.Delete); var canBulkAssignment = Authorization.HasAll(Claims.User.Actions.AddFlags, Claims.User.Actions.RemoveFlags, Claims.User.ShowFlagAssignments); var canShowUsers = Model.CurrentAssignmentCount > 0 && Authorization.HasAll(Claims.User.Search, Claims.User.ShowFlagAssignments); + var canExportCurrent = Model.CurrentAssignmentCount > 0 && Authorization.Has(Claims.Config.UserFlag.Export); + var canExportAll = Model.TotalAssignmentCount > 0 && Authorization.Has(Claims.Config.UserFlag.Export); var hideAdvanced = Model.UserFlag.UserDevicesLinkedGroup == null && @@ -398,9 +400,17 @@ -@if (canBulkAssignment || canDelete || canShowUsers) +@if (canBulkAssignment || canDelete || canShowUsers || canExportCurrent || canExportAll) {
+ @if (canExportCurrent) + { + @Html.ActionLinkButton("Export Current Assignments", MVC.Config.UserFlag.Export(null, Model.UserFlag.Id, true), "Config_UserFlags_Actions_ExportCurrent_Button") + } + @if (canExportAll) + { + @Html.ActionLinkButton("Export All Assignments", MVC.Config.UserFlag.Export(null, Model.UserFlag.Id, false), "Config_UserFlags_Actions_ExportAll_Button") + } @if (canBulkAssignment) { Bulk Assign Users @@ -537,9 +547,6 @@ }); } - - - @if (canDelete) { @Html.ActionLinkButton("Delete", MVC.API.UserFlag.Delete(Model.UserFlag.Id, true), "Config_UserFlags_Actions_Delete_Button") diff --git a/Disco.Web/Areas/Config/Views/UserFlag/Show.generated.cs b/Disco.Web/Areas/Config/Views/UserFlag/Show.generated.cs index 6da9824c..98e3f6a3 100644 --- a/Disco.Web/Areas/Config/Views/UserFlag/Show.generated.cs +++ b/Disco.Web/Areas/Config/Views/UserFlag/Show.generated.cs @@ -72,6 +72,8 @@ namespace Disco.Web.Areas.Config.Views.UserFlag var canDelete = Authorization.Has(Claims.Config.UserFlag.Delete); var canBulkAssignment = Authorization.HasAll(Claims.User.Actions.AddFlags, Claims.User.Actions.RemoveFlags, Claims.User.ShowFlagAssignments); var canShowUsers = Model.CurrentAssignmentCount > 0 && Authorization.HasAll(Claims.User.Search, Claims.User.ShowFlagAssignments); + var canExportCurrent = Model.CurrentAssignmentCount > 0 && Authorization.Has(Claims.Config.UserFlag.Export); + var canExportAll = Model.TotalAssignmentCount > 0 && Authorization.Has(Claims.Config.UserFlag.Export); var hideAdvanced = Model.UserFlag.UserDevicesLinkedGroup == null && @@ -88,15 +90,15 @@ WriteLiteral("\r\n(hideAdvanced ? " Config_HideAdvanced" : null + #line 25 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" +, Tuple.Create(Tuple.Create("", 1444), Tuple.Create(hideAdvanced ? " Config_HideAdvanced" : null #line default #line hidden -, 1222), false) +, 1444), false) ); WriteLiteral(" style=\"width: 550px\""); @@ -110,7 +112,7 @@ WriteLiteral(">\r\n Id:\r\n \r\n \ WriteLiteral(" "); - #line 30 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 32 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.DisplayFor(model => model.UserFlag.Id)); @@ -120,55 +122,55 @@ WriteLiteral("\r\n \r\n \r\n \r\n " Name:\r\n \r\n \r\n"); - #line 38 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 40 "..\..\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" if (canConfig) { #line default #line hidden - #line 39 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 41 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.EditorFor(model => model.UserFlag.Name)); #line default #line hidden - #line 39 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 41 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 40 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 42 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxSave()); #line default #line hidden - #line 40 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 42 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 41 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 43 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxLoader()); #line default #line hidden - #line 41 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 43 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" @@ -184,7 +186,7 @@ WriteLiteral(">\r\n $(function () {\r\n " \'"); - #line 47 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 49 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Url.Action(MVC.API.UserFlag.UpdateName(Model.UserFlag.Id))); @@ -194,7 +196,7 @@ WriteLiteral("\',\r\n \'FlagName\'\r\n " });\r\n \r\n"); - #line 52 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 54 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } else { @@ -203,14 +205,14 @@ WriteLiteral("\',\r\n \'FlagName\'\r\n #line default #line hidden - #line 55 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 57 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.UserFlag.Name); #line default #line hidden - #line 55 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 57 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } @@ -221,55 +223,55 @@ WriteLiteral(" \r\n \r\n \r\n " Description:\r\n \r\n \r\n"); - #line 64 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 66 "..\..\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" if (canConfig) { #line default #line hidden - #line 65 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 67 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.EditorFor(model => model.UserFlag.Description)); #line default #line hidden - #line 65 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 67 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 66 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 68 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxSave()); #line default #line hidden - #line 66 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 68 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 67 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 69 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxLoader()); #line default #line hidden - #line 67 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 69 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" @@ -287,7 +289,7 @@ WriteLiteral(@"> '"); - #line 73 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 75 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Url.Action(MVC.API.UserFlag.UpdateDescription(Model.UserFlag.Id))); @@ -297,7 +299,7 @@ WriteLiteral("\',\r\n \'Description\'\r\n "\r\n });\r\n \r\n"); - #line 78 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 80 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } else { @@ -308,13 +310,13 @@ WriteLiteral("\',\r\n \'Description\'\r\n WriteLiteral("
\r\n");
 
             
-            #line 82 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
+            #line 84 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
                     
             
             #line default
             #line hidden
             
-            #line 82 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
+            #line 84 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
                      if (string.IsNullOrEmpty(Model.UserFlag.Description))
                     {
 
@@ -328,7 +330,7 @@ WriteLiteral("<None>");
 WriteLiteral("\r\n");
 
             
-            #line 85 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
+            #line 87 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
                     }
                     else
                     {
@@ -337,14 +339,14 @@ WriteLiteral("\r\n");
             #line default
             #line hidden
             
-            #line 88 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
+            #line 90 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
                    Write(Model.UserFlag.Description.ToHtmlComment());
 
             
             #line default
             #line hidden
             
-            #line 88 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
+            #line 90 "..\..\Areas\Config\Views\UserFlag\Show.cshtml"
                                                                    
                     }
 
@@ -354,7 +356,7 @@ WriteLiteral("\r\n");
 WriteLiteral("                    
\r\n"); - #line 91 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 93 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } @@ -365,7 +367,7 @@ WriteLiteral(" \r\n \r\n \r\n ""); - #line 99 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 101 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.CurrentAssignmentCount); @@ -374,7 +376,7 @@ WriteLiteral(" \r\n \r\n \r\n WriteLiteral(" user"); - #line 99 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 101 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.CurrentAssignmentCount != 1 ? "s" : null); @@ -383,7 +385,7 @@ WriteLiteral(" user"); WriteLiteral(" currently assigned
\r\n
"); - #line 100 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 102 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.TotalAssignmentCount); @@ -392,7 +394,7 @@ WriteLiteral(" currently assigned
\r\n
"); WriteLiteral(" total user historical assignment"); - #line 100 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 102 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.TotalAssignmentCount != 1 ? "s" : null); @@ -406,7 +408,7 @@ WriteLiteral(" id=\"Config_UserFlags_Icon\""); WriteLiteral(" data-icon=\""); - #line 108 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 110 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.UserFlag.Icon); @@ -417,7 +419,7 @@ WriteLiteral("\""); WriteLiteral(" data-colour=\""); - #line 108 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 110 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.UserFlag.IconColour); @@ -425,37 +427,37 @@ WriteLiteral(" data-colour=\""); #line hidden WriteLiteral("\""); -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) +WriteAttribute("class", Tuple.Create(" class=\"", 4608), Tuple.Create("\"", 4681) +, Tuple.Create(Tuple.Create("", 4616), Tuple.Create("fa", 4616), true) +, Tuple.Create(Tuple.Create(" ", 4618), Tuple.Create("fa-", 4619), true) - #line 108 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" - , Tuple.Create(Tuple.Create("", 4400), Tuple.Create(Model.UserFlag.Icon + #line 110 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + , Tuple.Create(Tuple.Create("", 4622), Tuple.Create(Model.UserFlag.Icon #line default #line hidden -, 4400), false) -, Tuple.Create(Tuple.Create(" ", 4422), Tuple.Create("fa-4x", 4423), true) -, Tuple.Create(Tuple.Create(" ", 4428), Tuple.Create("d-", 4429), true) +, 4622), false) +, Tuple.Create(Tuple.Create(" ", 4644), Tuple.Create("fa-4x", 4645), true) +, Tuple.Create(Tuple.Create(" ", 4650), Tuple.Create("d-", 4651), true) - #line 108 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" - , Tuple.Create(Tuple.Create("", 4431), Tuple.Create(Model.UserFlag.IconColour + #line 110 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + , Tuple.Create(Tuple.Create("", 4653), Tuple.Create(Model.UserFlag.IconColour #line default #line hidden -, 4431), false) +, 4653), false) ); WriteLiteral(">\r\n"); - #line 109 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 111 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 109 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 111 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (canConfig) { @@ -485,13 +487,13 @@ WriteLiteral(" class=\"icons\""); WriteLiteral(">\r\n"); - #line 116 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 118 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 116 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 118 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" foreach (var icon in Model.Icons) { @@ -503,7 +505,7 @@ WriteLiteral("
\r\n "save() {\r\n var url = \'"); - #line 185 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 187 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Url.Action(MVC.API.UserFlag.UpdateIconAndColour(id: Model.UserFlag.Id, redirect: true))); @@ -679,7 +681,7 @@ WriteLiteral(@"', "); - #line 207 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 209 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } @@ -688,13 +690,13 @@ WriteLiteral(@"', WriteLiteral(" \r\n \r\n"); - #line 210 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 212 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 210 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 212 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (hideAdvanced) { @@ -728,7 +730,7 @@ WriteLiteral(@">Show Advanced Options "); - #line 226 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 228 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } @@ -742,13 +744,13 @@ WriteLiteral(">\r\n \r\n On Assignment
Expres "\r\n \r\n"); - #line 232 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 234 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 232 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 234 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (canConfig) { @@ -756,56 +758,56 @@ WriteLiteral(">\r\n \r\n On Assignment
Expres #line default #line hidden - #line 234 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 236 "..\..\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 236 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 235 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 237 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxRemove()); #line default #line hidden - #line 235 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 237 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 236 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 238 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxSave()); #line default #line hidden - #line 236 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 238 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 237 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 239 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxLoader()); #line default #line hidden - #line 237 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 239 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" @@ -827,7 +829,7 @@ WriteLiteral(@"> '"); - #line 247 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 249 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Url.Action(MVC.API.UserFlag.UpdateOnAssignmentExpression(Model.UserFlag.Id))); @@ -855,7 +857,7 @@ WriteLiteral("\',\r\n \'OnAssignmentExpressio " \r\n"); - #line 276 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 278 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } else { @@ -872,7 +874,7 @@ WriteLiteral(" class=\"smallMessage\""); WriteLiteral("><None Specified>\r\n"); - #line 282 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 284 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } else { @@ -889,7 +891,7 @@ WriteLiteral(">\r\n"); WriteLiteral(" "); - #line 286 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 288 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.UserFlag.OnAssignmentExpression); @@ -898,7 +900,7 @@ WriteLiteral(" "); WriteLiteral("\r\n \r\n"); - #line 288 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 290 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } } @@ -928,13 +930,13 @@ WriteLiteral(">\r\n \r\n On Unassignment
Expr " \r\n \r\n"); - #line 302 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 304 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 302 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 304 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (canConfig) { @@ -942,56 +944,56 @@ WriteLiteral(">\r\n \r\n On Unassignment
Expr #line default #line hidden - #line 304 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 306 "..\..\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 306 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 305 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 307 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxRemove()); #line default #line hidden - #line 305 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 307 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 306 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 308 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxSave()); #line default #line hidden - #line 306 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 308 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 307 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 309 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(AjaxHelpers.AjaxLoader()); #line default #line hidden - #line 307 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 309 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" @@ -1013,7 +1015,7 @@ WriteLiteral(@"> '"); - #line 317 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 319 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Url.Action(MVC.API.UserFlag.UpdateOnUnassignmentExpression(Model.UserFlag.Id))); @@ -1051,7 +1053,7 @@ WriteLiteral(@"', "); - #line 346 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 348 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } else { @@ -1068,7 +1070,7 @@ WriteLiteral(" class=\"smallMessage\""); WriteLiteral("><None Specified>\r\n"); - #line 352 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 354 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } else { @@ -1085,7 +1087,7 @@ WriteLiteral(">\r\n"); WriteLiteral(" "); - #line 356 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 358 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Model.UserFlag.OnUnassignmentExpression); @@ -1094,7 +1096,7 @@ WriteLiteral(" "); WriteLiteral("\r\n \r\n"); - #line 358 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 360 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } } @@ -1126,7 +1128,7 @@ WriteLiteral(">\r\n \r\n Linked Groups:\r\n WriteLiteral(" "); - #line 374 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 376 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.Partial(MVC.Config.Shared.Views.LinkedGroupInstance, new LinkedGroupModel() { CanConfigure = canConfig, @@ -1145,7 +1147,7 @@ WriteLiteral("\r\n"); WriteLiteral(" "); - #line 383 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 385 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.Partial(MVC.Config.Shared.Views.LinkedGroupInstance, new LinkedGroupModel() { CanConfigure = canConfig, @@ -1162,13 +1164,13 @@ WriteLiteral(" "); WriteLiteral("\r\n"); - #line 392 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 394 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 392 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 394 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (canConfig) { @@ -1176,14 +1178,14 @@ WriteLiteral("\r\n"); #line default #line hidden - #line 394 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 396 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(Html.Partial(MVC.Config.Shared.Views.LinkedGroupShared)); #line default #line hidden - #line 394 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 396 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" } @@ -1193,8 +1195,8 @@ WriteLiteral("\r\n"); WriteLiteral(" \r\n \r\n \r\n \r\n\r\n"); - #line 401 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" - if (canBulkAssignment || canDelete || canShowUsers) + #line 403 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + if (canBulkAssignment || canDelete || canShowUsers || canExportCurrent || canExportAll) { @@ -1207,13 +1209,63 @@ WriteLiteral(" class=\"actionBar\""); WriteLiteral(">\r\n"); - #line 404 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 406 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" #line default #line hidden - #line 404 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 406 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + if (canExportCurrent) + { + + + #line default + #line hidden + + #line 408 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(Html.ActionLinkButton("Export Current Assignments", MVC.Config.UserFlag.Export(null, Model.UserFlag.Id, true), "Config_UserFlags_Actions_ExportCurrent_Button")); + + + #line default + #line hidden + + #line 408 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 410 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + if (canExportAll) + { + + + #line default + #line hidden + + #line 412 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + Write(Html.ActionLinkButton("Export All Assignments", MVC.Config.UserFlag.Export(null, Model.UserFlag.Id, false), "Config_UserFlags_Actions_ExportAll_Button")); + + + #line default + #line hidden + + #line 412 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 414 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" if (canBulkAssignment) { @@ -1299,7 +1351,7 @@ WriteLiteral(">\r\n user6
\r\n WriteLiteral(" "); - #line 437 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 447 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(ActiveDirectory.Context.PrimaryDomain.NetBiosName); @@ -1312,7 +1364,7 @@ WriteLiteral(" class=\"code\""); WriteLiteral(">user6,smi0099,"); - #line 439 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 449 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(ActiveDirectory.Context.PrimaryDomain.NetBiosName); @@ -1325,7 +1377,7 @@ WriteLiteral(" class=\"code\""); WriteLiteral(">user6;smi0099;"); - #line 440 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" + #line 450 "..\..\Areas\Config\Views\UserFlag\Show.cshtml" Write(ActiveDirectory.Context.PrimaryDomain.NetBiosName); @@ -1400,7 +1452,7 @@ WriteLiteral("