-
Notifications
You must be signed in to change notification settings - Fork 2
Added a button to edit the team name and description #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Added a button to edit the team name and description #94
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request adds the ability for team leaders to edit their team's name and description directly from the profile page. The motivation comes from a real user experience where the contributor needed to email administrators to fix a typo in their team name.
Key changes:
- Added an edit button next to the team name that is only visible to team leaders
- Implemented a modal dialog with a form for editing team name and description
- Added LiveView event handlers to manage modal state, form validation, and team updates
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| @impl true | ||
| def handle_event("close-edit-modal", _params, socket) do | ||
| {:noreply, assign(socket, show_edit_modal: false)} |
Copilot
AI
Jan 6, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the modal is closed without saving changes (via Cancel button or on_cancel), the form still contains any user-entered data. This could lead to confusion if the user reopens the modal later. Consider resetting the form to the current team values when closing the modal to ensure a clean state on next open.
| {:noreply, assign(socket, show_edit_modal: false)} | |
| user = socket.assigns.user | |
| team = user.team | |
| socket = | |
| if team && team.leader_id == user.id do | |
| assign(socket, | |
| show_edit_modal: false, | |
| form: to_form(Teams.change_team(team)) | |
| ) | |
| else | |
| assign(socket, show_edit_modal: false) | |
| end | |
| {:noreply, socket} |
enricoprazeres
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello! Thanks for the contribution! 💪
It makes total sense and it’s a really useful feature.
When you get a chance, please take a look at the review I just left. There are a few suggestions there.
Nice work!
| def mount(_params, _session, %{assigns: %{current_scope: %{user: user}}} = socket) | ||
| when not is_nil(user) do | ||
| team = | ||
| if user.team_id do | ||
| Teams.get_team!(user.team_id) | ||
| else | ||
| nil | ||
| end | ||
|
|
||
| {:ok, assign(socket, user: Map.put(user, :team, team))} | ||
| socket = assign(socket, user: Map.put(user, :team, team), show_edit_modal: false) | ||
|
|
||
| socket = | ||
| if team && team.leader_id == user.id do | ||
| assign(socket, form: to_form(Teams.change_team(team))) | ||
| else | ||
| socket | ||
| end | ||
|
|
||
| {:ok, socket} | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could do something more idiomatic with this:
@impl true
def mount(_params, _session, %{assigns: %{current_scope: %{user: user}}} = socket) when not is_nil(user) do
team = if user.team_id do
Teams.get_team!(user.team_id)
else
nil
end
socket = socket
|> assign(user: Map.put(user, :team, team), show_edit_modal: false)
|> maybe_assign_team_form(team, user)
{:ok, socket}
end
defp maybe_assign_team_form(socket, %{leader_id: id} = team, %{id: id})
when leader_id == user_id do
assign(socket, form: to_form(Teams.change_team_edition(team)))
end
defp maybe_assign_team_form(socket, _team, _user), do: socket
| def handle_event("validate-team", %{"team" => team_params}, socket) do | ||
| changeset = | ||
| socket.assigns.user.team | ||
| |> Teams.change_team(team_params) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| |> Teams.change_team(team_params) | |
| |> Teams.change_team_edition(team_params) |
Consider using the new change_team_edition/2 function, which relies on edition_changeset/2, to ensure that only the intended fields can be edited during team updates.
teams.ex
@doc """
Returns an `%Ecto.Changeset{}` for tracking team changes for team editions.
## Examples
iex> change_team_edition(team)
%Ecto.Changeset{data: %Team{}}
"""
def change_team_edition(%Team{} = team, attrs \\ %{}) do
Team.edition_changeset(team, attrs)
end
team.ex
def edition_changeset(team, attrs) do
team
|> cast(attrs, [
:name, :description
])
end
| @impl true | ||
| def handle_event("update-team", %{"team" => team_params}, socket) do | ||
| case Teams.update_team(socket.assigns.user.team, team_params) do | ||
| {:ok, _updated_team} -> | ||
| # Reload team to ensure we have the latest state and members preloaded | ||
| team = Teams.get_team!(socket.assigns.user.team_id) | ||
| user = Map.put(socket.assigns.user, :team, team) | ||
|
|
||
| {:noreply, | ||
| socket | ||
| |> assign(user: user, show_edit_modal: false) | ||
| |> put_flash(:info, "Team updated successfully")} | ||
|
|
||
| {:error, changeset} -> | ||
| {:noreply, assign(socket, form: to_form(changeset))} | ||
| end | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should verify here if the current user is the team leader.
| @impl true | |
| def handle_event("update-team", %{"team" => team_params}, socket) do | |
| case Teams.update_team(socket.assigns.user.team, team_params) do | |
| {:ok, _updated_team} -> | |
| # Reload team to ensure we have the latest state and members preloaded | |
| team = Teams.get_team!(socket.assigns.user.team_id) | |
| user = Map.put(socket.assigns.user, :team, team) | |
| {:noreply, | |
| socket | |
| |> assign(user: user, show_edit_modal: false) | |
| |> put_flash(:info, "Team updated successfully")} | |
| {:error, changeset} -> | |
| {:noreply, assign(socket, form: to_form(changeset))} | |
| end | |
| end | |
| @impl true | |
| def handle_event("update-team", %{"team" => team_params}, socket) do | |
| user = socket.assigns.user | |
| team = user.team | |
| if team && team.leader_id == user.id do | |
| case Teams.update_team(socket.assigns.user.team, team_params) do | |
| {:ok, _updated_team} -> | |
| team = Teams.get_team!(socket.assigns.user.team_id) | |
| user = Map.put(socket.assigns.user, :team, team) | |
| {:noreply, socket | |
| |> assign(user: user, show_edit_modal: false) | |
| |> put_flash(:info, "Team updated successfully") | |
| } | |
| {:error, changeset} -> | |
| {:noreply, assign(socket, form: to_form(changeset))} | |
| end | |
| else | |
| {:noreply, socket |> put_flash(:error, "You are not authorized to update this team.") |> assign(show_edit_modal: false)} | |
| end | |
| end |
|
|
||
| socket = | ||
| if team && team.leader_id == user.id do | ||
| assign(socket, form: to_form(Teams.change_team(team))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| assign(socket, form: to_form(Teams.change_team(team))) | |
| assign(socket, form: to_form(Teams.change_team_edition(team))) |
| @impl true | ||
| def handle_event("close-edit-modal", _params, socket) do | ||
| {:noreply, assign(socket, show_edit_modal: false)} | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the modal is closed without saving changes, the form still contains any user-entered data. This could lead to confusion if the user reopens the modal later. Consider resetting the form to the current team values when closing the modal to ensure a clean state on next open.
| @impl true | |
| def handle_event("close-edit-modal", _params, socket) do | |
| {:noreply, assign(socket, show_edit_modal: false)} | |
| end | |
| @impl true | |
| def handle_event("close-edit-modal", _params, socket) do | |
| user = socket.assigns.user | |
| team = user.team | |
| {:noreply, socket | |
| |> assign(show_edit_modal: false, form: to_form(Teams.change_team_edition(team))) | |
| |> maybe_assign_team_form(team, user)} | |
| end | |
Hello!
Origin story:
I created a team, but I had a dyslexia moment, and I entered the wrong name, so I sent an email asking to update.
But since I think it would be cool for team admins to be able to edit the team details, I decided to do it myself.
I hope this is useful.
Changes:
Greetings from NIAEFEUP 👋!