Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
aerosol committed Jan 24, 2025
1 parent c386da4 commit 26f7e48
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 64 deletions.
82 changes: 51 additions & 31 deletions lib/plausible_web/live/components/team.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule PlausibleWeb.Live.Components.Team do
attr :user, User, required: true
attr :label, :string, default: nil
attr :role, :atom, default: nil
attr :my_role, :atom, required: true
attr :disabled, :boolean, default: false

def member(assigns) do
Expand All @@ -19,7 +20,7 @@ defmodule PlausibleWeb.Live.Components.Team do
:if={@label}
class="ml-1 dark:bg-indigo-600 dark:text-gray-200 bg-gray-100 text-gray-500 text-xs px-1 rounded"
>
{@label}
{@label}
</span>
<br /><span class="text-gray-500 text-xs">{@user.email}</span>
Expand All @@ -31,48 +32,51 @@ defmodule PlausibleWeb.Live.Components.Team do
<Heroicons.chevron_down mini class="size-4 mt-0.5" />
</:button>
<:menu class="dropdown-items max-w-60">
<.dropdown_item
href="#"
disabled={@disabled or @role == :admin}
<.role_item
phx-value-email={@user.email}
phx-value-name={@user.name}
role={:owner}
disabled={@disabled or @role == :owner}
phx-click="update-role"
phx-value-role={:admin}
>
Manage the team without restrictions
</.role_item>
<.role_item
phx-value-email={@user.email}
phx-value-name={@user.name}
role={:admin}
disabled={@disabled or @role == :admin}
phx-click="update-role"
>
<div>Admin</div>
<div class="text-gray-500 dark:text-gray-400 text-xs/5">
Manage all team settings
</div>
</.dropdown_item>
<.dropdown_item
href="#"
Manage all team settings
</.role_item>
<.role_item
phx-value-email={@user.email}
phx-value-name={@user.name}
role={:editor}
disabled={@disabled or @role == :editor}
phx-click="update-role"
phx-value-role={:editor}
>
Create and view new sites
</.role_item>
<.role_item
phx-value-email={@user.email}
phx-value-name={@user.name}
>
<div>Editor</div>
<div class="text-gray-500 dark:text-gray-400 text-xs/5">
Create and view new sites
</div>
</.dropdown_item>
<.dropdown_item
href="#"
disabled={@disabled or @role == :viewer}
role={:billing}
disabled={@disabled or @role == :billing}
phx-click="update-role"
phx-value-role={:viewer}
>
Manage subscription
</.role_item>
<.role_item
phx-value-email={@user.email}
phx-value-name={@user.name}
role={:viewer}
disabled={@disabled or @role == :viewer}
phx-click="update-role"
>
<div>Viewer</div>
<div class="text-gray-500 dark:text-gray-400 text-xs/5">
Can only view all sites under your team
</div>
</.dropdown_item>
View all sites under your team
</.role_item>
<.dropdown_divider />
<.dropdown_item
href="#"
Expand All @@ -95,4 +99,20 @@ defmodule PlausibleWeb.Live.Components.Team do
</div>
"""
end

attr :role, :atom, required: true
attr :disabled, :boolean, default: false
slot :inner_block, required: true
attr :rest, :global

def role_item(assigns) do
~H"""
<.dropdown_item href="#" phx-value-role={@role} disabled={@disabled} {@rest}>
<div>{@role |> Atom.to_string() |> String.capitalize()}</div>
<div class="text-gray-500 dark:text-gray-400 text-xs/5">
{render_slot(@inner_block)}
</div>
</.dropdown_item>
"""
end
end
134 changes: 103 additions & 31 deletions lib/plausible_web/live/team_management.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,36 @@ defmodule PlausibleWeb.Live.TeamManagement do
{:ok, reset(socket)}
end

defp reset(socket) do
my_team = socket.assigns.my_team

{:ok, my_role} = Teams.Memberships.team_role(my_team, socket.assigns.current_user)
all_members = Teams.Memberships.all_members(my_team)
invitations_sent = Plausible.Teams.Invitations.find_team_invitations(my_team)
invitations_pending = []
invitations_to_delete = []
memberships_to_delete = []

invitations_to_update = []
memberships_to_update = []

selected_input_role = :viewer

assign(socket,
my_role: my_role,
all_members: all_members,
invitations_pending: invitations_pending,
invitations_sent: invitations_sent,
selected_invitation_role: :admin,
team_layout_changed?: false,
invitations_to_delete: invitations_to_delete,
memberships_to_delete: memberships_to_delete,
selected_input_role: selected_input_role,
invitations_to_update: invitations_to_update,
memberships_to_update: memberships_to_update
)
end

def render(assigns) do
~H"""
<.flash_messages flash={@flash} />
Expand All @@ -33,15 +63,41 @@ defmodule PlausibleWeb.Live.TeamManagement do
<.dropdown class="relative">
<:button class="role border rounded border-indigo-700 bg-transparent text-gray-800 dark:text-gray-100 hover:bg-gray-50 dark:hover:bg-gray-700 focus-visible:outline-gray-100 whitespace-nowrap truncate inline-flex items-center gap-x-2 font-medium rounded-md px-3 py-2 text-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:bg-gray-400 dark:disabled:text-white dark:disabled:text-gray-400 dark:disabled:bg-gray-700">
Admin <Heroicons.chevron_down mini class="size-4 mt-0.5" />
{@selected_input_role |> Atom.to_string() |> String.capitalize()}
<Heroicons.chevron_down mini class="size-4 mt-0.5" />
</:button>
<:menu class="dropdown-items max-w-60">
<.dropdown_item href="#" phx-click="update-role" phx-value-role={:admin}>
<div>Admin</div>
<div class="text-gray-500 dark:text-gray-400 text-xs/5">
Manage all team settings
</div>
</.dropdown_item>
<.role_item role={:owner} disabled={@my_role != :owner} phx-click="switch-role">
Manage the team without restrictions
</.role_item>
<.role_item
role={:admin}
disabled={@my_role not in [:owner, :admin]}
phx-click="switch-role"
>
Manage all team settings
</.role_item>
<.role_item
role={:editor}
disabled={@my_role not in [:owner, :admin]}
phx-click="switch-role"
>
Create and view new sites
</.role_item>
<.role_item
role={:billing}
disabled={@my_role not in [:owner, :admin]}
phx-click="switch-role"
>
Manage subscription
</.role_item>
<.role_item
role={:viewer}
disabled={@my_role not in [:owner, :admin]}
phx-click="switch-role"
>
View all sites under your team
</.role_item>
</:menu>
</.dropdown>
Expand All @@ -56,20 +112,23 @@ defmodule PlausibleWeb.Live.TeamManagement do
user={%User{email: invitation.email, name: "Invited User"}}
role={invitation.role}
label="Invitation Pending"
my_role={@my_role}
/>
<.member
:for={invitation <- @invitations_sent}
user={%User{email: invitation.email, name: "Invited User"}}
role={invitation.role}
label="Invitation Sent"
my_role={@my_role}
/>
<.member
:for={team_membership <- @all_members}
user={team_membership.user}
role={team_membership.role}
label={if @current_user.id == team_membership.user.id, do: "You"}
my_role={@my_role}
/>
<.button type="submit" phx-click="save-team-layout" disabled={not @team_layout_changed?}>
Expand All @@ -79,7 +138,15 @@ defmodule PlausibleWeb.Live.TeamManagement do
"""
end

def handle_event("queue-invitation", %{"invitee" => email} = params, socket) do
@roles Plausible.Teams.Membership.roles()
@roles_str Enum.map(@roles, &to_string(&1))

def handle_event("switch-role", %{"role" => role}, socket) when role in @roles_str do
socket = assign(socket, selected_input_role: String.to_existing_atom(role))
{:noreply, socket}
end

def handle_event("queue-invitation", %{"invitee" => email}, socket) do
invitations_pending = socket.assigns.invitations_pending
email = String.trim(email)

Expand All @@ -88,7 +155,7 @@ defmodule PlausibleWeb.Live.TeamManagement do
socket
|> assign(
invitations_pending: [
%{email: email, role: :admin} | invitations_pending
%{email: email, role: socket.assigns.selected_input_role} | invitations_pending
],
team_layout_changed?: true
)
Expand Down Expand Up @@ -232,34 +299,39 @@ defmodule PlausibleWeb.Live.TeamManagement do
end

def handle_event("update-role", %{"name" => name, "email" => email, "role" => role}, socket) do
IO.inspect(binding())
raise "stop"
invitations_sent = socket.assigns.invitations_sent

socket =
cond do
invitation_sent = Enum.find(invitations_sent, &(&1.email == email)) ->
invitations_to_update = socket.assigns.invitations_to_update
altered_invitation = %{invitation_sent | role: role}

invitations_sent =
Enum.reduce(invitations_sent, [], fn invitation, acc ->
if invitation.email == email do
[altered_invitation | acc]
else
[invitation | acc]
end
end)
|> Enum.reverse()

assign(socket,
invitations_sent: invitations_sent,
team_layout_changed?: true,
invitations_to_update: [altered_invitation | invitations_to_update]
)
end

IO.inspect(socket.assigns.invitations_to_update, label: :to_upd)
{:noreply, socket}
end

defp valid_email?(email) do
String.contains?(email, "@") and String.contains?(email, ".")
end

defp reset(socket) do
my_team = socket.assigns.my_team

all_members = Teams.Memberships.all_members(my_team)
invitations_sent = Plausible.Teams.Invitations.find_team_invitations(my_team)
invitations_pending = []
invitations_to_delete = []
memberships_to_delete = []

assign(socket,
all_members: all_members,
invitations_pending: invitations_pending,
invitations_sent: invitations_sent,
selected_invitation_role: :admin,
team_layout_changed?: false,
invitations_to_delete: invitations_to_delete,
memberships_to_delete: memberships_to_delete
)
end

defp already_in?(socket, email) do
not is_nil(
Enum.find(socket.assigns.invitations_sent, &(&1.email == email)) ||
Expand Down
8 changes: 6 additions & 2 deletions lib/plausible_web/live/team_setup.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ defmodule PlausibleWeb.Live.TeamSetup do
my_team = socket.assigns.my_team
enabled? = Teams.enabled?(my_team)

{:ok, my_role} = Teams.Memberships.team_role(my_team, socket.assigns.current_user)
true = my_role in [:owner, :admin]
socket = assign(socket, my_role: my_role)

# XXX: remove dev param, once manual testing is considered done
socket =
case {enabled?, my_team, params["dev"]} do
Expand Down Expand Up @@ -99,10 +103,10 @@ defmodule PlausibleWeb.Live.TeamSetup do
</div>
</.form>
<.member user={@current_user} role={:owner} disabled={true} label="You" />
<.member user={@current_user} role={@my_role} disabled={true} label="You" my_role={@my_role} />
<%= for {{email, name}, role} <- @candidates_selected do %>
<.member user={%User{email: email, name: name}} role={role} />
<.member user={%User{email: email, name: name}} role={role} my_role={@my_role} />
<% end %>
<:footer>
Expand Down

0 comments on commit 26f7e48

Please # to comment.