Сделал вывод табличных данных
This commit is contained in:
parent
b7500158cf
commit
c26b883fa1
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CarRepairShopContracts.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class ColumnAttribute : Attribute
|
||||
{
|
||||
public ColumnAttribute(string title="", bool visible = true, int width=0, GridViewAutoSize gridViewAutoSize = GridViewAutoSize.None, bool isUseAutoSize = false)
|
||||
{
|
||||
Title = title;
|
||||
Visible = visible;
|
||||
Width = width;
|
||||
GridViewAutoSize = gridViewAutoSize;
|
||||
IsUseAutoSize = isUseAutoSize;
|
||||
}
|
||||
public string Title { get; private set; }
|
||||
public bool Visible { get; private set; }
|
||||
public int Width { get; private set; }
|
||||
public GridViewAutoSize GridViewAutoSize { get; private set; }
|
||||
public bool IsUseAutoSize { get; private set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CarRepairShopContracts.Attributes
|
||||
{
|
||||
public enum GridViewAutoSize
|
||||
{
|
||||
NotSet = 0,
|
||||
|
||||
None = 1,
|
||||
|
||||
ColumnHeader = 2,
|
||||
|
||||
AllCellsExceptHeader = 4,
|
||||
|
||||
AllCells = 6,
|
||||
|
||||
DisplayedCellsExceptHeader = 8,
|
||||
|
||||
DisplayedCells = 10,
|
||||
|
||||
Fill = 16
|
||||
}
|
||||
}
|
@ -20,5 +20,7 @@ namespace CarRepairShopContracts.BindingModels
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
|
||||
public string Body { get; set; } = string.Empty;
|
||||
|
||||
public int Id => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using CarRepairShopDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using CarRepairShopContracts.Attributes;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -10,15 +10,16 @@ namespace CarRepairShopContracts.ViewModels
|
||||
{
|
||||
public class ClientViewModel : IClientModel
|
||||
{
|
||||
[Column(visible:false)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[DisplayName("ФИО клиента")]
|
||||
[Column(title:"ФИО клиента", width:150)]
|
||||
public string ClientFIO { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Логин (эл. почта)")]
|
||||
[Column(title:"Логин (эл.почта)", gridViewAutoSize:GridViewAutoSize.Fill, isUseAutoSize:true)]
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Пароль")]
|
||||
[Column(title:"Пароль", width:150)]
|
||||
public string Password { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using CarRepairShopDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using CarRepairShopContracts.Attributes;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -10,12 +10,13 @@ namespace CarRepairShopContracts.ViewModels
|
||||
{
|
||||
public class ComponentViewModel : IComponentModel
|
||||
{
|
||||
[Column(visible:false)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[DisplayName("Название компонента")]
|
||||
[Column(title:"Название компонента", gridViewAutoSize:GridViewAutoSize.Fill, isUseAutoSize:true)]
|
||||
public string ComponentName { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Цена")]
|
||||
[Column(title:"Цена", width:150)]
|
||||
public double Cost { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using CarRepairShopDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using CarRepairShopContracts.Attributes;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -10,18 +10,19 @@ namespace CarRepairShopContracts.ViewModels
|
||||
{
|
||||
public class ImplementerViewModel : IImplementerModel
|
||||
{
|
||||
[Column(visible:false)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[DisplayName("ФИО исполнителя")]
|
||||
|
||||
[Column(title:"ФИО исполнителя", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
|
||||
public string ImplementerFIO { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Пароль")]
|
||||
[Column(title: "Пароль", width:150)]
|
||||
public string Password { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Опыт работы")]
|
||||
[Column(title: "Опыт работы", width: 150)]
|
||||
public int WorkExperience { get; set; }
|
||||
|
||||
[DisplayName("Квалификация")]
|
||||
[Column(title: "Квалификация", width: 150)]
|
||||
public int Qualification { get; set; }
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using CarRepairShopDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using CarRepairShopContracts.Attributes;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -10,20 +10,24 @@ namespace CarRepairShopContracts.ViewModels
|
||||
{
|
||||
public class MessageInfoViewModel : IMessageInfoModel
|
||||
{
|
||||
[Column(visible:false)]
|
||||
public string MessageId { get; set; } = string.Empty;
|
||||
|
||||
[Column(visible:false)]
|
||||
public int? ClientId { get; set; }
|
||||
|
||||
[DisplayName("Почта отправителя")]
|
||||
[Column(title: "Почта отправителя", width: 150)]
|
||||
public string SenderName { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Дата получения")]
|
||||
[Column(title: "Дата получения", width: 150)]
|
||||
public DateTime DateDelivery { get; set; }
|
||||
|
||||
[DisplayName("Заголовок")]
|
||||
[Column(title: "Заголовок", width: 150)]
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Текст письма")]
|
||||
[Column(title: "Текст письма", gridViewAutoSize:GridViewAutoSize.Fill, isUseAutoSize:true)]
|
||||
public string Body { get; set; } = string.Empty;
|
||||
|
||||
[Column(visible: false)]
|
||||
public int Id => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ using CarRepairShopDataModels.Enums;
|
||||
using CarRepairShopDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using CarRepairShopContracts.Attributes;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -12,35 +12,38 @@ namespace CarRepairShopContracts.ViewModels
|
||||
{
|
||||
public class OrderViewModel : IOrderModel
|
||||
{
|
||||
[DisplayName("Номер")]
|
||||
[Column(title: "Номер", width: 50)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column(visible: false)]
|
||||
public int RepairId { get; set; }
|
||||
[Column(visible: false)]
|
||||
public int ClientId { get; set; }
|
||||
[Column(visible: false)]
|
||||
public int? ImplementerId { get; set; }
|
||||
|
||||
[DisplayName("ФИО клиента")]
|
||||
[Column(title: "ФИО клиента", gridViewAutoSize:GridViewAutoSize.Fill, isUseAutoSize:true)]
|
||||
public string ClientFIO { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("ФИО исполнителя")]
|
||||
[Column(title: "ФИО исполнителя", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
|
||||
public string ImplementerFIO { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Ремонт")]
|
||||
[Column(title: "Ремонт", width: 100)]
|
||||
public string RepairName { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Количество")]
|
||||
[Column(title: "Количество", width: 80)]
|
||||
public int Count { get; set; }
|
||||
|
||||
[DisplayName("Сумма")]
|
||||
[Column(title: "Сумма", width: 100)]
|
||||
public double Sum { get; set; }
|
||||
|
||||
[DisplayName("Статус")]
|
||||
[Column(title: "Статус", width: 120)]
|
||||
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
|
||||
|
||||
[DisplayName("Дата создания")]
|
||||
[Column(title: "Дата создания", width: 110)]
|
||||
public DateTime DateCreate { get; set; } = DateTime.Now;
|
||||
|
||||
[DisplayName("Дата выполнения")]
|
||||
[Column(title: "Дата выполнения", width: 100)]
|
||||
public DateTime? DateImplement { get; set; }
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using CarRepairShopDataModels.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using CarRepairShopContracts.Attributes;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -10,14 +10,16 @@ namespace CarRepairShopContracts.ViewModels
|
||||
{
|
||||
public class RepairViewModel : IRepairModel
|
||||
{
|
||||
[Column(visible:false)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[DisplayName("Название ремонта")]
|
||||
[Column(title: "Название ремонта", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)]
|
||||
public string RepairName { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Цена")]
|
||||
[Column(title: "Цена", width: 150)]
|
||||
public double Price { get; set; }
|
||||
|
||||
[Column(visible: false)]
|
||||
public Dictionary<int, (IComponentModel, int)> RepairComponents { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace CarRepairShopDataModels.Models
|
||||
{
|
||||
public interface IMessageInfoModel
|
||||
public interface IMessageInfoModel : IId
|
||||
{
|
||||
string MessageId { get; }
|
||||
int? ClientId { get; }
|
||||
|
@ -51,5 +51,7 @@ namespace CarRepairShopDatabaseImplement.Models
|
||||
Subject = Subject,
|
||||
DateDelivery = DateDelivery,
|
||||
};
|
||||
|
||||
public int Id => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
@ -70,5 +70,7 @@ namespace CarRepairShopFileImplement.Models
|
||||
new XElement("Subject", Subject),
|
||||
new XElement("Body", Body),
|
||||
new XElement("SenderName", SenderName));
|
||||
|
||||
public int Id => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
@ -46,5 +46,7 @@ namespace CarRepairShopListImplement.Models
|
||||
Subject = Subject,
|
||||
Body = Body,
|
||||
};
|
||||
|
||||
public int Id => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
42
CarRepairShop/CarRepairShopView/DataGridViewExtension.cs
Normal file
42
CarRepairShop/CarRepairShopView/DataGridViewExtension.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using CarRepairShopContracts.Attributes;
|
||||
|
||||
|
||||
namespace CarRepairShopView
|
||||
{
|
||||
public static class DataGridViewExtension
|
||||
{
|
||||
public static void FillandConfigGrid<T>(this DataGridView grid, List<T>? data)
|
||||
{
|
||||
if (data == null) return;
|
||||
grid.DataSource = data;
|
||||
var type = typeof(T);
|
||||
var properties = type.GetProperties();
|
||||
foreach(DataGridViewColumn column in grid.Columns)
|
||||
{
|
||||
var property = properties.FirstOrDefault(x => x.Name == column.Name);
|
||||
if (property == null)
|
||||
{
|
||||
throw new InvalidOperationException($"В типе {type.Name} не найдено свойство с именем {column.Name}");
|
||||
}
|
||||
var attribute = property.GetCustomAttributes(typeof(ColumnAttribute), true).SingleOrDefault();
|
||||
if(attribute == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Не найден атрибут типа ColumnAttribute для свойства {property.Name}");
|
||||
}
|
||||
if(attribute is ColumnAttribute columnAttr)
|
||||
{
|
||||
column.HeaderText = columnAttr.Title;
|
||||
column.Visible = columnAttr.Visible;
|
||||
if (columnAttr.IsUseAutoSize)
|
||||
{
|
||||
column.AutoSizeMode = (DataGridViewAutoSizeColumnMode)Enum.Parse(typeof(DataGridViewAutoSizeColumnMode), columnAttr.GridViewAutoSize.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
column.Width = columnAttr.Width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -34,13 +34,7 @@ namespace CarRepairShopView
|
||||
{
|
||||
try
|
||||
{
|
||||
var list = _logic.ReadList(null);
|
||||
if (list != null)
|
||||
{
|
||||
dataGridView.DataSource = list;
|
||||
dataGridView.Columns["Id"].Visible = false;
|
||||
dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
|
||||
}
|
||||
dataGridView.FillandConfigGrid(_logic.ReadList(null));
|
||||
_logger.LogInformation("Загрузка клиентов");
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -32,13 +32,7 @@ namespace CarRepairShopView
|
||||
{
|
||||
try
|
||||
{
|
||||
var list = _logic.ReadList(null);
|
||||
if (list != null)
|
||||
{
|
||||
dataGridView.DataSource = list;
|
||||
dataGridView.Columns["Id"].Visible = false;
|
||||
dataGridView.Columns["ComponentName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
|
||||
}
|
||||
dataGridView.FillandConfigGrid(_logic.ReadList(null));
|
||||
_logger.LogInformation("Загрузка компонентов");
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -27,13 +27,7 @@ namespace CarRepairShopView
|
||||
{
|
||||
try
|
||||
{
|
||||
var list = _logic.ReadList(null);
|
||||
if (list != null)
|
||||
{
|
||||
dataGridView.DataSource = list;
|
||||
dataGridView.Columns["Id"].Visible = false;
|
||||
dataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
|
||||
}
|
||||
dataGridView.FillandConfigGrid(_logic.ReadList(null));
|
||||
_logger.LogInformation("Загрузка исполнителей");
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -27,13 +27,7 @@ namespace CarRepairShopView
|
||||
private void FormLetters_Load(object sender, EventArgs e)
|
||||
{
|
||||
_logger.LogInformation("Загрузка писем");
|
||||
var list = _logic.ReadList(null);
|
||||
if(list != null )
|
||||
{
|
||||
dataGridView.DataSource = list;
|
||||
dataGridView.Columns["MessageId"].Visible = false;
|
||||
dataGridView.Columns["ClientId"].Visible = false;
|
||||
}
|
||||
dataGridView.FillandConfigGrid(_logic.ReadList(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
28
CarRepairShop/CarRepairShopView/FormMain.Designer.cs
generated
28
CarRepairShop/CarRepairShopView/FormMain.Designer.cs
generated
@ -39,11 +39,11 @@
|
||||
ClientsToolStripMenuItem = new ToolStripMenuItem();
|
||||
workStartToolStripMenuItem = new ToolStripMenuItem();
|
||||
implementersToolStripMenuItem = new ToolStripMenuItem();
|
||||
почтаToolStripMenuItem = new ToolStripMenuItem();
|
||||
dataGridView = new DataGridView();
|
||||
buttonCreateOrder = new Button();
|
||||
buttonIssuedOrder = new Button();
|
||||
buttonRef = new Button();
|
||||
почтаToolStripMenuItem = new ToolStripMenuItem();
|
||||
menuStrip1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
|
||||
SuspendLayout();
|
||||
@ -53,7 +53,7 @@
|
||||
menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчетыToolStripMenuItem, ClientsToolStripMenuItem, workStartToolStripMenuItem, implementersToolStripMenuItem, почтаToolStripMenuItem });
|
||||
menuStrip1.Location = new Point(0, 0);
|
||||
menuStrip1.Name = "menuStrip1";
|
||||
menuStrip1.Size = new Size(1059, 24);
|
||||
menuStrip1.Size = new Size(1256, 24);
|
||||
menuStrip1.TabIndex = 0;
|
||||
menuStrip1.Text = "menuStrip1";
|
||||
//
|
||||
@ -127,6 +127,13 @@
|
||||
implementersToolStripMenuItem.Text = "Исполнители";
|
||||
implementersToolStripMenuItem.Click += implementersToolStripMenuItem_Click;
|
||||
//
|
||||
// почтаToolStripMenuItem
|
||||
//
|
||||
почтаToolStripMenuItem.Name = "почтаToolStripMenuItem";
|
||||
почтаToolStripMenuItem.Size = new Size(53, 20);
|
||||
почтаToolStripMenuItem.Text = "Почта";
|
||||
почтаToolStripMenuItem.Click += почтаToolStripMenuItem_Click;
|
||||
//
|
||||
// dataGridView
|
||||
//
|
||||
dataGridView.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||
@ -139,13 +146,13 @@
|
||||
dataGridView.RowHeadersVisible = false;
|
||||
dataGridView.RowTemplate.Height = 25;
|
||||
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
|
||||
dataGridView.Size = new Size(827, 349);
|
||||
dataGridView.Size = new Size(1024, 398);
|
||||
dataGridView.TabIndex = 1;
|
||||
//
|
||||
// buttonCreateOrder
|
||||
//
|
||||
buttonCreateOrder.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
||||
buttonCreateOrder.Location = new Point(844, 54);
|
||||
buttonCreateOrder.Location = new Point(1041, 54);
|
||||
buttonCreateOrder.Name = "buttonCreateOrder";
|
||||
buttonCreateOrder.Size = new Size(198, 28);
|
||||
buttonCreateOrder.TabIndex = 2;
|
||||
@ -156,7 +163,7 @@
|
||||
// buttonIssuedOrder
|
||||
//
|
||||
buttonIssuedOrder.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
||||
buttonIssuedOrder.Location = new Point(844, 109);
|
||||
buttonIssuedOrder.Location = new Point(1041, 109);
|
||||
buttonIssuedOrder.Name = "buttonIssuedOrder";
|
||||
buttonIssuedOrder.Size = new Size(198, 28);
|
||||
buttonIssuedOrder.TabIndex = 5;
|
||||
@ -167,7 +174,7 @@
|
||||
// buttonRef
|
||||
//
|
||||
buttonRef.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
||||
buttonRef.Location = new Point(844, 164);
|
||||
buttonRef.Location = new Point(1041, 164);
|
||||
buttonRef.Name = "buttonRef";
|
||||
buttonRef.Size = new Size(198, 28);
|
||||
buttonRef.TabIndex = 6;
|
||||
@ -175,18 +182,11 @@
|
||||
buttonRef.UseVisualStyleBackColor = true;
|
||||
buttonRef.Click += buttonRef_Click;
|
||||
//
|
||||
// почтаToolStripMenuItem
|
||||
//
|
||||
почтаToolStripMenuItem.Name = "почтаToolStripMenuItem";
|
||||
почтаToolStripMenuItem.Size = new Size(53, 20);
|
||||
почтаToolStripMenuItem.Text = "Почта";
|
||||
почтаToolStripMenuItem.Click += почтаToolStripMenuItem_Click;
|
||||
//
|
||||
// FormMain
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(1059, 377);
|
||||
ClientSize = new Size(1256, 426);
|
||||
Controls.Add(buttonRef);
|
||||
Controls.Add(buttonIssuedOrder);
|
||||
Controls.Add(buttonCreateOrder);
|
||||
|
@ -37,14 +37,7 @@ namespace CarRepairShopView
|
||||
private void LoadData()
|
||||
{
|
||||
_logger.LogInformation("Загрузка заказов");
|
||||
var _list = _orderLogic.ReadList(null);
|
||||
if (_list != null)
|
||||
{
|
||||
dataGridView.DataSource = _list;
|
||||
dataGridView.Columns["RepairId"].Visible = false;
|
||||
dataGridView.Columns["ImplementerId"].Visible = false;
|
||||
dataGridView.Columns["ClientId"].Visible = false;
|
||||
}
|
||||
dataGridView.FillandConfigGrid(_orderLogic.ReadList(null));
|
||||
}
|
||||
|
||||
private void компонентыToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
|
@ -33,14 +33,7 @@ namespace CarRepairShopView
|
||||
{
|
||||
try
|
||||
{
|
||||
var list = _logic.ReadList(null);
|
||||
if (list != null)
|
||||
{
|
||||
dataGridView.DataSource = list;
|
||||
dataGridView.Columns["Id"].Visible = false;
|
||||
dataGridView.Columns["RepairComponents"].Visible = false;
|
||||
dataGridView.Columns["RepairName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
|
||||
}
|
||||
dataGridView.FillandConfigGrid(_logic.ReadList(null));
|
||||
_logger.LogInformation("Загрузка ремонта");
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
Loading…
Reference in New Issue
Block a user