feat: leave workspace
This commit is contained in:
parent
ab9496c248
commit
65491b921f
|
|
@ -64,6 +64,12 @@ pub struct Invite {
|
||||||
pub pending_workspace_invitations: Vec<AFWorkspaceInvitation>,
|
pub pending_workspace_invitations: Vec<AFWorkspaceInvitation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(path = "components/shared_workspaces.html")]
|
||||||
|
pub struct SharedWorkspaces {
|
||||||
|
pub shared_workspaces: Vec<AFWorkspace>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "components/admin_navigate.html")]
|
#[template(path = "components/admin_navigate.html")]
|
||||||
pub struct AdminNavigate;
|
pub struct AdminNavigate;
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ pub async fn invite_accept_handler(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
session: UserSession,
|
session: UserSession,
|
||||||
Path(invite_id): Path<String>,
|
Path(invite_id): Path<String>,
|
||||||
) -> Result<WebApiResponse<()>, WebApiError<'static>> {
|
) -> Result<HeaderMap, WebApiError<'static>> {
|
||||||
accept_workspace_invitation(
|
accept_workspace_invitation(
|
||||||
&session.token.access_token,
|
&session.token.access_token,
|
||||||
&invite_id,
|
&invite_id,
|
||||||
|
|
@ -160,9 +160,7 @@ pub async fn invite_accept_handler(
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(WebApiResponse::<()>::from_str(
|
Ok(htmx_trigger("workspaceInvitationAccepted"))
|
||||||
"Invitation accepted.\nPlease refresh page to see changes".into(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn change_password_handler(
|
pub async fn change_password_handler(
|
||||||
|
|
@ -300,6 +298,12 @@ pub async fn login_refresh_handler(
|
||||||
))
|
))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
verify_token_cloud(
|
||||||
|
token.access_token.as_str(),
|
||||||
|
state.appflowy_cloud_url.as_str(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let new_session_id = uuid::Uuid::new_v4();
|
let new_session_id = uuid::Uuid::new_v4();
|
||||||
let new_session = session::UserSession::new(new_session_id.to_string(), token);
|
let new_session = session::UserSession::new(new_session_id.to_string(), token);
|
||||||
state.session_store.put_user_session(&new_session).await?;
|
state.session_store.put_user_session(&new_session).await?;
|
||||||
|
|
@ -390,6 +394,12 @@ fn htmx_redirect(url: &str) -> HeaderMap {
|
||||||
h
|
h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn htmx_trigger(trigger: &str) -> HeaderMap {
|
||||||
|
let mut h = HeaderMap::new();
|
||||||
|
h.insert("HX-Trigger", trigger.parse().unwrap());
|
||||||
|
h
|
||||||
|
}
|
||||||
|
|
||||||
fn new_session_cookie(id: uuid::Uuid) -> Cookie<'static> {
|
fn new_session_cookie(id: uuid::Uuid) -> Cookie<'static> {
|
||||||
let mut cookie = Cookie::new("session_id", id.to_string());
|
let mut cookie = Cookie::new("session_id", id.to_string());
|
||||||
cookie.set_path("/");
|
cookie.set_path("/");
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,9 @@ pub fn component_router() -> Router<AppState> {
|
||||||
// User actions
|
// User actions
|
||||||
.route("/user/navigate", get(user_navigate_handler))
|
.route("/user/navigate", get(user_navigate_handler))
|
||||||
.route("/user/user", get(user_user_handler))
|
.route("/user/user", get(user_user_handler))
|
||||||
.route("/user/change_password", get(user_change_password_handler))
|
.route("/user/change-password", get(user_change_password_handler))
|
||||||
.route("/user/invite", get(user_invite_handler))
|
.route("/user/invite", get(user_invite_handler))
|
||||||
|
.route("/user/shared-workspaces", get(shared_workspaces_handler))
|
||||||
.route("/user/user-usage", get(user_usage_handler))
|
.route("/user/user-usage", get(user_usage_handler))
|
||||||
.route("/user/workspace-usage", get(workspace_usage_handler))
|
.route("/user/workspace-usage", get(workspace_usage_handler))
|
||||||
|
|
||||||
|
|
@ -93,14 +94,34 @@ pub async fn admin_navigate_handler() -> Result<Html<String>, WebAppError> {
|
||||||
render_template(templates::AdminNavigate)
|
render_template(templates::AdminNavigate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn shared_workspaces_handler(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
session: UserSession,
|
||||||
|
) -> Result<Html<String>, WebAppError> {
|
||||||
|
let user_workspaces =
|
||||||
|
get_user_workspaces(&session.token.access_token, &state.appflowy_cloud_url).await?;
|
||||||
|
|
||||||
|
let profile = get_user_profile(
|
||||||
|
session.token.access_token.as_str(),
|
||||||
|
state.appflowy_cloud_url.as_str(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let shared_workspaces = user_workspaces
|
||||||
|
.into_iter()
|
||||||
|
.filter(|workspace| workspace.owner_uid != profile.uid)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
render_template(templates::SharedWorkspaces { shared_workspaces })
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn user_invite_handler(
|
pub async fn user_invite_handler(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
session: UserSession,
|
session: UserSession,
|
||||||
) -> Result<Html<String>, WebAppError> {
|
) -> Result<Html<String>, WebAppError> {
|
||||||
let user_workspaces =
|
let user_workspaces =
|
||||||
get_user_workspaces(&session.token.access_token, &state.appflowy_cloud_url).await;
|
get_user_workspaces(&session.token.access_token, &state.appflowy_cloud_url).await?;
|
||||||
|
|
||||||
let user_workspaces = user_workspaces?;
|
|
||||||
let profile = get_user_profile(
|
let profile = get_user_profile(
|
||||||
session.token.access_token.as_str(),
|
session.token.access_token.as_str(),
|
||||||
state.appflowy_cloud_url.as_str(),
|
state.appflowy_cloud_url.as_str(),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<div>
|
<div>
|
||||||
<h3>Password Change</h3>
|
<h3>Password Change</h3>
|
||||||
<form hx-post="/web-api/change_password" hx-target="#none">
|
<form hx-post="/web-api/change-password" hx-target="#none">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>New Password:</td>
|
<td>New Password:</td>
|
||||||
|
|
|
||||||
|
|
@ -24,20 +24,13 @@
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<h4>Workspaces shared with you</h4>
|
<h4>Workspaces shared with you</h4>
|
||||||
<table class="cyan-table table">
|
<div
|
||||||
<thead>
|
hx-get="/web/components/user/shared-workspaces"
|
||||||
<tr>
|
hx-trigger="workspaceInvitationAccepted from:body"
|
||||||
<th>Workspace Name</th>
|
hx-swap="innerHTML"
|
||||||
<th>Owner Name</th>
|
>
|
||||||
</tr>
|
{% include "shared_workspaces.html" %}
|
||||||
</thead>
|
</div>
|
||||||
{% for shared_workspace in shared_workspaces %}
|
|
||||||
<tr>
|
|
||||||
<td> {{ shared_workspace.workspace_name|escape }} </td>
|
|
||||||
<td> {{ shared_workspace.owner_name|escape }} </td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<h4>Invite another user to your workspace</h4>
|
<h4>Invite another user to your workspace</h4>
|
||||||
|
|
@ -87,7 +80,11 @@
|
||||||
<td> {{ pending_workspace_invitation.workspace_name|default("")|escape }} </td>
|
<td> {{ pending_workspace_invitation.workspace_name|default("")|escape }} </td>
|
||||||
<td> {{ pending_workspace_invitation.inviter_email|default("")|escape }} </td>
|
<td> {{ pending_workspace_invitation.inviter_email|default("")|escape }} </td>
|
||||||
<td>
|
<td>
|
||||||
<form hx-post="/web-api/invite/{{ pending_workspace_invitation.invite_id|escape }}/accept" hx-target="#none">
|
<form
|
||||||
|
hx-post="/web-api/invite/{{ pending_workspace_invitation.invite_id|escape }}/accept"
|
||||||
|
hx-target="closest tr"
|
||||||
|
hx-swap="delete"
|
||||||
|
>
|
||||||
<button class="button cyan" type="submit">Accept</button>
|
<button class="button cyan" type="submit">Accept</button>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<table class="cyan-table table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Workspace Name</th>
|
||||||
|
<th>Owner Name</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for shared_workspace in shared_workspaces %}
|
||||||
|
<tr>
|
||||||
|
<td> {{ shared_workspace.workspace_name|escape }} </td>
|
||||||
|
<td> {{ shared_workspace.owner_name|escape }} </td>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
class="button red"
|
||||||
|
hx-delete="/web-api/workspace/{{ shared_workspace.workspace_id|escape }}/leave"
|
||||||
|
hx-confirm="Are you sure?"
|
||||||
|
hx-target="closest tr"
|
||||||
|
hx-swap="delete"
|
||||||
|
>
|
||||||
|
Leave
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<div
|
<div
|
||||||
class="sidebar-item"
|
class="sidebar-item"
|
||||||
hx-target="#sidebar-content"
|
hx-target="#sidebar-content"
|
||||||
hx-get="/web/components/user/change_password"
|
hx-get="/web/components/user/change-password"
|
||||||
>
|
>
|
||||||
Change Password
|
Change Password
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue