mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
create default workspace
This commit is contained in:
@ -46,6 +46,25 @@ pub struct QueryAppParams {
|
||||
pub is_trash: bool,
|
||||
}
|
||||
|
||||
impl QueryAppParams {
|
||||
pub fn new(app_id: &str) -> Self {
|
||||
Self {
|
||||
app_id: app_id.to_string(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_belongings(mut self) -> Self {
|
||||
self.read_belongings = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn trash(mut self) -> Self {
|
||||
self.is_trash = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<QueryAppParams> for QueryAppRequest {
|
||||
type Error = WorkspaceError;
|
||||
|
||||
|
@ -53,6 +53,30 @@ pub struct UpdateAppParams {
|
||||
pub is_trash: Option<bool>,
|
||||
}
|
||||
|
||||
impl UpdateAppParams {
|
||||
pub fn new(app_id: &str) -> Self {
|
||||
Self {
|
||||
app_id: app_id.to_string(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(mut self, name: &str) -> Self {
|
||||
self.name = Some(name.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn desc(mut self, desc: &str) -> Self {
|
||||
self.desc = Some(desc.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn trash(mut self) -> Self {
|
||||
self.is_trash = Some(true);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<UpdateAppParams> for UpdateAppRequest {
|
||||
type Error = WorkspaceError;
|
||||
|
||||
|
@ -44,6 +44,25 @@ pub struct QueryViewParams {
|
||||
pub read_belongings: bool,
|
||||
}
|
||||
|
||||
impl QueryViewParams {
|
||||
pub fn new(view_id: &str) -> Self {
|
||||
Self {
|
||||
view_id: view_id.to_owned(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trash(mut self) -> Self {
|
||||
self.is_trash = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn read_belongings(mut self) -> Self {
|
||||
self.read_belongings = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<QueryViewParams> for QueryViewRequest {
|
||||
type Error = WorkspaceError;
|
||||
|
||||
|
@ -41,6 +41,29 @@ pub struct UpdateViewParams {
|
||||
pub is_trash: Option<bool>,
|
||||
}
|
||||
|
||||
impl UpdateViewParams {
|
||||
pub fn new(view_id: &str) -> Self {
|
||||
Self {
|
||||
view_id: view_id.to_owned(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trash(mut self) -> Self {
|
||||
self.is_trash = Some(true);
|
||||
self
|
||||
}
|
||||
pub fn name(mut self, name: &str) -> Self {
|
||||
self.name = Some(name.to_owned());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn desc(mut self, desc: &str) -> Self {
|
||||
self.desc = Some(desc.to_owned());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<UpdateViewParams> for UpdateViewRequest {
|
||||
type Error = WorkspaceError;
|
||||
|
||||
|
@ -78,9 +78,9 @@ impl Workspace {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Default, ProtoBuf)]
|
||||
pub struct Workspaces {
|
||||
pub struct RepeatedWorkspace {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<Workspace>,
|
||||
}
|
||||
|
||||
impl_def_and_def_mut!(Workspaces, Workspace);
|
||||
impl_def_and_def_mut!(RepeatedWorkspace, Workspace);
|
||||
|
@ -20,6 +20,20 @@ pub struct QueryWorkspaceParams {
|
||||
pub read_apps: bool,
|
||||
}
|
||||
|
||||
impl QueryWorkspaceParams {
|
||||
pub fn new(workspace_id: &str) -> Self {
|
||||
Self {
|
||||
workspace_id: workspace_id.to_owned(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_apps(mut self) -> Self {
|
||||
self.read_apps = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<QueryWorkspaceParams> for QueryWorkspaceRequest {
|
||||
type Error = WorkspaceError;
|
||||
|
||||
|
@ -44,8 +44,8 @@ pub async fn read_workspace(
|
||||
#[tracing::instrument(name = "get_all_workspaces", skip(controller))]
|
||||
pub async fn read_all_workspaces(
|
||||
controller: Unit<Arc<WorkspaceController>>,
|
||||
) -> DataResult<Workspaces, WorkspaceError> {
|
||||
) -> DataResult<RepeatedWorkspace, WorkspaceError> {
|
||||
let workspaces = controller.read_workspaces_belong_to_user().await?;
|
||||
|
||||
data_result(Workspaces { items: workspaces })
|
||||
data_result(RepeatedWorkspace { items: workspaces })
|
||||
}
|
||||
|
@ -768,7 +768,7 @@ impl ::protobuf::reflect::ProtobufValue for Workspace {
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct Workspaces {
|
||||
pub struct RepeatedWorkspace {
|
||||
// message fields
|
||||
pub items: ::protobuf::RepeatedField<Workspace>,
|
||||
// special fields
|
||||
@ -776,14 +776,14 @@ pub struct Workspaces {
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a Workspaces {
|
||||
fn default() -> &'a Workspaces {
|
||||
<Workspaces as ::protobuf::Message>::default_instance()
|
||||
impl<'a> ::std::default::Default for &'a RepeatedWorkspace {
|
||||
fn default() -> &'a RepeatedWorkspace {
|
||||
<RepeatedWorkspace as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl Workspaces {
|
||||
pub fn new() -> Workspaces {
|
||||
impl RepeatedWorkspace {
|
||||
pub fn new() -> RepeatedWorkspace {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
@ -813,7 +813,7 @@ impl Workspaces {
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for Workspaces {
|
||||
impl ::protobuf::Message for RepeatedWorkspace {
|
||||
fn is_initialized(&self) -> bool {
|
||||
for v in &self.items {
|
||||
if !v.is_initialized() {
|
||||
@ -887,8 +887,8 @@ impl ::protobuf::Message for Workspaces {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> Workspaces {
|
||||
Workspaces::new()
|
||||
fn new() -> RepeatedWorkspace {
|
||||
RepeatedWorkspace::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
@ -897,37 +897,37 @@ impl ::protobuf::Message for Workspaces {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage<Workspace>>(
|
||||
"items",
|
||||
|m: &Workspaces| { &m.items },
|
||||
|m: &mut Workspaces| { &mut m.items },
|
||||
|m: &RepeatedWorkspace| { &m.items },
|
||||
|m: &mut RepeatedWorkspace| { &mut m.items },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<Workspaces>(
|
||||
"Workspaces",
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<RepeatedWorkspace>(
|
||||
"RepeatedWorkspace",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static Workspaces {
|
||||
static instance: ::protobuf::rt::LazyV2<Workspaces> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(Workspaces::new)
|
||||
fn default_instance() -> &'static RepeatedWorkspace {
|
||||
static instance: ::protobuf::rt::LazyV2<RepeatedWorkspace> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(RepeatedWorkspace::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for Workspaces {
|
||||
impl ::protobuf::Clear for RepeatedWorkspace {
|
||||
fn clear(&mut self) {
|
||||
self.items.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for Workspaces {
|
||||
impl ::std::fmt::Debug for RepeatedWorkspace {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for Workspaces {
|
||||
impl ::protobuf::reflect::ProtobufValue for RepeatedWorkspace {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
@ -941,43 +941,43 @@ static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\tR\x04desc\x12\x17\n\x07user_id\x18\x03\x20\x01(\tR\x06userId\"e\n\tWor\
|
||||
kspace\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04name\x18\
|
||||
\x02\x20\x01(\tR\x04name\x12\x12\n\x04desc\x18\x03\x20\x01(\tR\x04desc\
|
||||
\x12\x20\n\x04apps\x18\x04\x20\x01(\x0b2\x0c.RepeatedAppR\x04apps\".\n\n\
|
||||
Workspaces\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.WorkspaceR\x05item\
|
||||
sJ\xb1\x05\n\x06\x12\x04\0\0\x14\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\t\
|
||||
\n\x02\x03\0\x12\x03\x01\0\x1a\n\n\n\x02\x04\0\x12\x04\x03\0\x06\x01\n\n\
|
||||
\n\x03\x04\0\x01\x12\x03\x03\x08\x1e\n\x0b\n\x04\x04\0\x02\0\x12\x03\x04\
|
||||
\x04\x14\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\
|
||||
\x02\0\x01\x12\x03\x04\x0b\x0f\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x04\
|
||||
\x12\x13\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x05\x04\x14\n\x0c\n\x05\x04\0\
|
||||
\x02\x01\x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x05\
|
||||
\x0b\x0f\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x05\x12\x13\n\n\n\x02\x04\
|
||||
\x01\x12\x04\x07\0\x0b\x01\n\n\n\x03\x04\x01\x01\x12\x03\x07\x08\x1d\n\
|
||||
\x0b\n\x04\x04\x01\x02\0\x12\x03\x08\x04\x14\n\x0c\n\x05\x04\x01\x02\0\
|
||||
\x05\x12\x03\x08\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x08\x0b\x0f\
|
||||
\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\x08\x12\x13\n\x0b\n\x04\x04\x01\
|
||||
\x02\x01\x12\x03\t\x04\x14\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\t\x04\
|
||||
\n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\t\x0b\x0f\n\x0c\n\x05\x04\x01\
|
||||
\x02\x01\x03\x12\x03\t\x12\x13\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\n\x04\
|
||||
\x17\n\x0c\n\x05\x04\x01\x02\x02\x05\x12\x03\n\x04\n\n\x0c\n\x05\x04\x01\
|
||||
\x02\x02\x01\x12\x03\n\x0b\x12\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\n\
|
||||
\x15\x16\n\n\n\x02\x04\x02\x12\x04\x0c\0\x11\x01\n\n\n\x03\x04\x02\x01\
|
||||
\x12\x03\x0c\x08\x11\n\x0b\n\x04\x04\x02\x02\0\x12\x03\r\x04\x12\n\x0c\n\
|
||||
\x05\x04\x02\x02\0\x05\x12\x03\r\x04\n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\
|
||||
\x03\r\x0b\r\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\r\x10\x11\n\x0b\n\x04\
|
||||
\x04\x02\x02\x01\x12\x03\x0e\x04\x14\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\
|
||||
\x03\x0e\x04\n\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\x0e\x0b\x0f\n\x0c\
|
||||
\n\x05\x04\x02\x02\x01\x03\x12\x03\x0e\x12\x13\n\x0b\n\x04\x04\x02\x02\
|
||||
\x02\x12\x03\x0f\x04\x14\n\x0c\n\x05\x04\x02\x02\x02\x05\x12\x03\x0f\x04\
|
||||
\n\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03\x0f\x0b\x0f\n\x0c\n\x05\x04\
|
||||
\x02\x02\x02\x03\x12\x03\x0f\x12\x13\n\x0b\n\x04\x04\x02\x02\x03\x12\x03\
|
||||
\x10\x04\x19\n\x0c\n\x05\x04\x02\x02\x03\x06\x12\x03\x10\x04\x0f\n\x0c\n\
|
||||
\x05\x04\x02\x02\x03\x01\x12\x03\x10\x10\x14\n\x0c\n\x05\x04\x02\x02\x03\
|
||||
\x03\x12\x03\x10\x17\x18\n\n\n\x02\x04\x03\x12\x04\x12\0\x14\x01\n\n\n\
|
||||
\x03\x04\x03\x01\x12\x03\x12\x08\x12\n\x0b\n\x04\x04\x03\x02\0\x12\x03\
|
||||
\x13\x04!\n\x0c\n\x05\x04\x03\x02\0\x04\x12\x03\x13\x04\x0c\n\x0c\n\x05\
|
||||
\x04\x03\x02\0\x06\x12\x03\x13\r\x16\n\x0c\n\x05\x04\x03\x02\0\x01\x12\
|
||||
\x03\x13\x17\x1c\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x13\x1f\x20b\x06p\
|
||||
roto3\
|
||||
\x12\x20\n\x04apps\x18\x04\x20\x01(\x0b2\x0c.RepeatedAppR\x04apps\"5\n\
|
||||
\x11RepeatedWorkspace\x12\x20\n\x05items\x18\x01\x20\x03(\x0b2\n.Workspa\
|
||||
ceR\x05itemsJ\xb1\x05\n\x06\x12\x04\0\0\x14\x01\n\x08\n\x01\x0c\x12\x03\
|
||||
\0\0\x12\n\t\n\x02\x03\0\x12\x03\x01\0\x1a\n\n\n\x02\x04\0\x12\x04\x03\0\
|
||||
\x06\x01\n\n\n\x03\x04\0\x01\x12\x03\x03\x08\x1e\n\x0b\n\x04\x04\0\x02\0\
|
||||
\x12\x03\x04\x04\x14\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x04\x04\n\n\x0c\
|
||||
\n\x05\x04\0\x02\0\x01\x12\x03\x04\x0b\x0f\n\x0c\n\x05\x04\0\x02\0\x03\
|
||||
\x12\x03\x04\x12\x13\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x05\x04\x14\n\x0c\
|
||||
\n\x05\x04\0\x02\x01\x05\x12\x03\x05\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\
|
||||
\x12\x03\x05\x0b\x0f\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x05\x12\x13\n\
|
||||
\n\n\x02\x04\x01\x12\x04\x07\0\x0b\x01\n\n\n\x03\x04\x01\x01\x12\x03\x07\
|
||||
\x08\x1d\n\x0b\n\x04\x04\x01\x02\0\x12\x03\x08\x04\x14\n\x0c\n\x05\x04\
|
||||
\x01\x02\0\x05\x12\x03\x08\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\
|
||||
\x08\x0b\x0f\n\x0c\n\x05\x04\x01\x02\0\x03\x12\x03\x08\x12\x13\n\x0b\n\
|
||||
\x04\x04\x01\x02\x01\x12\x03\t\x04\x14\n\x0c\n\x05\x04\x01\x02\x01\x05\
|
||||
\x12\x03\t\x04\n\n\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\t\x0b\x0f\n\x0c\
|
||||
\n\x05\x04\x01\x02\x01\x03\x12\x03\t\x12\x13\n\x0b\n\x04\x04\x01\x02\x02\
|
||||
\x12\x03\n\x04\x17\n\x0c\n\x05\x04\x01\x02\x02\x05\x12\x03\n\x04\n\n\x0c\
|
||||
\n\x05\x04\x01\x02\x02\x01\x12\x03\n\x0b\x12\n\x0c\n\x05\x04\x01\x02\x02\
|
||||
\x03\x12\x03\n\x15\x16\n\n\n\x02\x04\x02\x12\x04\x0c\0\x11\x01\n\n\n\x03\
|
||||
\x04\x02\x01\x12\x03\x0c\x08\x11\n\x0b\n\x04\x04\x02\x02\0\x12\x03\r\x04\
|
||||
\x12\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\r\x04\n\n\x0c\n\x05\x04\x02\
|
||||
\x02\0\x01\x12\x03\r\x0b\r\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\r\x10\
|
||||
\x11\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0e\x04\x14\n\x0c\n\x05\x04\x02\
|
||||
\x02\x01\x05\x12\x03\x0e\x04\n\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\
|
||||
\x0e\x0b\x0f\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0e\x12\x13\n\x0b\n\
|
||||
\x04\x04\x02\x02\x02\x12\x03\x0f\x04\x14\n\x0c\n\x05\x04\x02\x02\x02\x05\
|
||||
\x12\x03\x0f\x04\n\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03\x0f\x0b\x0f\n\
|
||||
\x0c\n\x05\x04\x02\x02\x02\x03\x12\x03\x0f\x12\x13\n\x0b\n\x04\x04\x02\
|
||||
\x02\x03\x12\x03\x10\x04\x19\n\x0c\n\x05\x04\x02\x02\x03\x06\x12\x03\x10\
|
||||
\x04\x0f\n\x0c\n\x05\x04\x02\x02\x03\x01\x12\x03\x10\x10\x14\n\x0c\n\x05\
|
||||
\x04\x02\x02\x03\x03\x12\x03\x10\x17\x18\n\n\n\x02\x04\x03\x12\x04\x12\0\
|
||||
\x14\x01\n\n\n\x03\x04\x03\x01\x12\x03\x12\x08\x19\n\x0b\n\x04\x04\x03\
|
||||
\x02\0\x12\x03\x13\x04!\n\x0c\n\x05\x04\x03\x02\0\x04\x12\x03\x13\x04\
|
||||
\x0c\n\x0c\n\x05\x04\x03\x02\0\x06\x12\x03\x13\r\x16\n\x0c\n\x05\x04\x03\
|
||||
\x02\0\x01\x12\x03\x13\x17\x1c\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x13\
|
||||
\x1f\x20b\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -16,6 +16,6 @@ message Workspace {
|
||||
string desc = 3;
|
||||
RepeatedApp apps = 4;
|
||||
}
|
||||
message Workspaces {
|
||||
message RepeatedWorkspace {
|
||||
repeated Workspace items = 1;
|
||||
}
|
||||
|
@ -169,9 +169,18 @@ pub async fn delete_workspace_request(
|
||||
params: DeleteWorkspaceParams,
|
||||
url: &str,
|
||||
) -> Result<(), WorkspaceError> {
|
||||
let _ = HttpRequestBuilder::delete(&url.to_owned())
|
||||
let _ = HttpRequestBuilder::delete(url)
|
||||
.protobuf(params)?
|
||||
.send()
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn read_workspace_list_request(url: &str) -> Result<RepeatedWorkspace, WorkspaceError> {
|
||||
let workspaces = HttpRequestBuilder::get(url)
|
||||
.send()
|
||||
.await?
|
||||
.response::<RepeatedWorkspace>()
|
||||
.await?;
|
||||
Ok(workspaces)
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
use crate::helper::*;
|
||||
use flowy_workspace::{
|
||||
entities::workspace::{CreateWorkspaceRequest, QueryWorkspaceRequest, Workspace, Workspaces},
|
||||
entities::workspace::{
|
||||
CreateWorkspaceRequest,
|
||||
QueryWorkspaceRequest,
|
||||
RepeatedWorkspace,
|
||||
Workspace,
|
||||
},
|
||||
event::WorkspaceEvent::*,
|
||||
prelude::*,
|
||||
};
|
||||
@ -23,7 +28,7 @@ fn workspace_read_all_success() {
|
||||
let workspaces = SingleUserTestBuilder::new()
|
||||
.event(ReadAllWorkspace)
|
||||
.sync_send()
|
||||
.parse::<Workspaces>();
|
||||
.parse::<RepeatedWorkspace>();
|
||||
|
||||
dbg!(&workspaces);
|
||||
}
|
||||
|
Reference in New Issue
Block a user