3.7 KiB · text 5af55d9
defmodule GitGudWeb.RepoLive.New do
use GitGudWeb, :live_view
alias GitGud.Organizations
alias GitGud.Repositories
alias GitGud.Repositories.Repository
alias GitGud.Repositories.Storage
@impl true
def mount(_params, _session, socket) do
user = socket.assigns.current_scope.user
orgs = Organizations.list_organizations_for(user) |> admin_only(user)
{:ok,
socket
|> assign(:page_title, "New repository")
|> assign(:user, user)
|> assign(:orgs, orgs)
|> assign(:namespace_choice, "user")
|> assign_form(Repository.create_changeset(%Repository{}, %{}))}
end
defp admin_only(orgs, user),
do: Enum.filter(orgs, &Organizations.org_admin?(&1, user))
@impl true
def handle_event("validate", %{"repository" => attrs} = params, socket) do
namespace = params["namespace"] || socket.assigns.namespace_choice
cs =
%Repository{}
|> Repository.create_changeset(attrs)
|> Map.put(:action, :validate)
{:noreply, socket |> assign(:namespace_choice, namespace) |> assign_form(cs)}
end
def handle_event("save", %{"repository" => attrs} = params, socket) do
namespace = params["namespace"] || socket.assigns.namespace_choice
user = socket.assigns.user
result =
case namespace do
"user" ->
Repositories.create_repository(user, attrs)
"org:" <> handle ->
org = Organizations.get_organization_by_handle!(handle)
Repositories.create_repository_for_org(org, user, attrs)
_ ->
{:error, :invalid_namespace}
end
case result do
{:ok, repo} ->
handle = namespace_handle(namespace, user)
{:noreply,
socket
|> put_flash(:info, "Repository created.")
|> push_navigate(to: ~p"/r/#{handle}/#{repo.name}")}
{:error, %Ecto.Changeset{} = cs} ->
{:noreply, assign_form(socket, cs)}
{:error, reason} ->
{:noreply, put_flash(socket, :error, "Could not create repository: #{inspect(reason)}")}
end
end
defp namespace_handle("user", user), do: Storage.owner_handle(user)
defp namespace_handle("org:" <> h, _user), do: h
defp assign_form(socket, cs), do: assign(socket, :form, to_form(cs))
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="space-y-4 max-w-lg">
<h1 class="text-2xl font-semibold">New repository</h1>
<.form
for={@form}
id="new-repo-form"
phx-change="validate"
phx-submit="save"
class="space-y-3"
>
<label class="flex flex-col gap-1">
<span class="text-sm opacity-70">Owner</span>
<select name="namespace" class="select select-bordered" phx-change="validate">
<option value="user" selected={@namespace_choice == "user"}>
{Storage.owner_handle(@user)} (you)
</option>
<option
:for={org <- @orgs}
value={"org:" <> org.handle}
selected={@namespace_choice == "org:" <> org.handle}
>
{org.handle}
</option>
</select>
</label>
<.input field={@form[:name]} label="Name" required />
<.input field={@form[:description]} label="Description" />
<.input
field={@form[:visibility]}
label="Visibility"
type="select"
options={[{"Private", "private"}, {"Internal", "internal"}, {"Public", "public"}]}
/>
<.input field={@form[:default_branch]} label="Default branch" value="main" />
<button type="submit" class="btn btn-primary">Create</button>
</.form>
</div>
</Layouts.app>
"""
end
end