Skip to content
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

Fix copy version: add missing assocs and assign skill to characters #1044

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
Welcome to Champions of Mirra Configurator
</.header>

<.link href={~p"/versions/new"}>
<.button>New Version</.button>
<.link href={~p"/versions/copy"}>
<.button>Copy Version</.button>
</.link>
<.link href={~p"/versions/show_current_version"}>
<.button>See Current Version</.button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,48 @@
defmodule ConfiguratorWeb.VersionController do
use ConfiguratorWeb, :controller

require Logger
alias GameBackend.Configuration
alias GameBackend.Configuration.Version
alias Configurator.Utils

def index(conn, _params) do
versions = Configuration.list_versions()
render(conn, :index, versions: versions)
end

def new(conn, _params) do
last_version = GameBackend.Configuration.get_current_version()
skills = Utils.list_curse_skills_by_version_grouped_by_type(last_version.id)
def copy(conn, _params) do
versions = Configuration.list_versions()
render(conn, :copy, versions: versions)
end

def create_copy(conn, params) do
selected_version = Configuration.get_preloaded_version!(params["version_id"])

params =
Map.from_struct(last_version)
|> Map.put(:characters, schema_to_map(last_version.characters))
|> Map.put(:consumable_items, schema_to_map(last_version.consumable_items))
|> Map.put(:game_configuration, schema_to_map(last_version.game_configuration))
|> Map.put(:map_configurations, schema_to_map(last_version.map_configurations))
|> Map.put(:skills, schema_to_map(last_version.skills))

changeset = Configuration.change_version(%Version{}, params)
render(conn, :new, changeset: changeset, last_version: last_version, skills: skills)
Map.from_struct(selected_version)
|> Map.put(:characters, schema_to_map(selected_version.characters))
|> Map.put(:consumable_items, schema_to_map(selected_version.consumable_items))
|> Map.put(:game_configuration, schema_to_map(selected_version.game_configuration))
|> Map.put(:map_configurations, schema_to_map(selected_version.map_configurations))
|> Map.put(:skills, schema_to_map(selected_version.skills))
|> Map.put(:name, params["name"])
|> Map.put(:current, false)

case Configuration.copy_version(params) do
{:ok, %{version: version}} ->
conn
|> put_flash(:info, "Version created successfully.")
|> redirect(to: ~p"/versions/#{version}")

{:error, :version, %Ecto.Changeset{} = changeset, _changes_so_far} ->
Logger.info("Insertion failed. Changeset: #{changeset}")
versions = Configuration.list_versions()
render(conn, :index, versions: versions)

{:error, :link_character_skills, %Ecto.Changeset{} = changeset, _changes_so_far} ->
Logger.info("Link character skills failed. Changeset: #{changeset}")
versions = Configuration.list_versions()
render(conn, :index, versions: versions)
end
end

# TODO: We have a cycle in our Skill.Mechanic assocs so this is to end that loop.
Expand All @@ -42,6 +61,16 @@ defmodule ConfiguratorWeb.VersionController do

def schema_to_map(%_struct{} = schema) do
schema
|> Map.reject(fn {k, _v} ->
k in [
:on_arrival_mechanic_id,
:parent_mechanic_id,
:version_id,
:dash_skill_id,
:ultimate_skill_id,
:basic_skill_id
]
end)
|> Map.from_struct()
|> Enum.map(fn {key, value} -> {key, schema_to_map(value)} end)
|> Enum.into(%{})
Expand All @@ -59,36 +88,6 @@ defmodule ConfiguratorWeb.VersionController do

def schema_to_map(value), do: value

def create(conn, %{"version" => version_params}) do
version_params =
case Map.get(version_params, "map_configurations") do
nil ->
version_params

map_configurations ->
Map.put(
version_params,
"map_configurations",
Map.new(map_configurations, fn {key, map_params} ->
{key, Utils.parse_json_params(map_params)}
end)
)
end

case Configuration.create_version(version_params) do
{:ok, version} ->
conn
|> put_flash(:info, "Version created successfully.")
|> redirect(to: ~p"/versions/#{version}")

{:error, %Ecto.Changeset{} = changeset} ->
last_version = GameBackend.Configuration.get_current_version()
skills = Utils.list_curse_skills_by_version_grouped_by_type(last_version.id)

render(conn, :new, changeset: changeset, last_version: last_version, skills: skills)
end
end

def show(conn, %{"id" => id}) do
version = Configuration.get_version!(id)
render(conn, :show, version: version)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<.simple_form :let={f} for={%{}} action="/versions/create_copy">
<.header>
Copy version
<:subtitle>Use this form to create a new version record in your database.</:subtitle>
</.header>

<.input
field={f[:version_id]}
type="select"
options={Enum.map(@versions, fn version -> {version.name, version.id} end)}
label="Version to copy from"
value={Enum.find(@versions, %{}, fn version -> version.current end) |> Map.get(:id)}
/>

<.input field={f[:name]} type="text" label="New copy version name" />

<:actions>
<.button>Create new copy version</.button>
</:actions>
</.simple_form>

<.back navigate={~p"/versions"}>Back to versions</.back>
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<.header>
Listing Versions
<:actions>
<.link href={~p"/versions/new"}>
<.button>New Version</.button>
<.link href={~p"/versions/copy_current_version"} data-confirm="You're about to create a new Version. Proceed?">
<.button>Copy Current Version</.button>
</.link>
</:actions>
</.header>
Expand Down

This file was deleted.

4 changes: 3 additions & 1 deletion apps/configurator/lib/configurator_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ defmodule ConfiguratorWeb.Router do

scope "/versions" do
get "/show_current_version", VersionController, :show_current_version
resources "/", VersionController
get "/copy", VersionController, :copy
post "/create_copy", VersionController, :create_copy
resources "/", VersionController, except: [:new]
put "/:id/current", VersionController, :mark_as_current

scope "/:version_id" do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,8 @@
end
end

describe "new version" do
test "renders form", %{conn: conn} do
conn = get(conn, ~p"/versions/new")
assert html_response(conn, 200) =~ "New Version"
end
end

describe "create version" do
test "redirects to show when data is valid", %{conn: conn} do

Check failure on line 21 in apps/configurator/test/configurator_web/controllers/version_controller_test.exs

View workflow job for this annotation

GitHub Actions / Build and test (1.16.0, 26.0.2)

test create version redirects to show when data is valid (ConfiguratorWeb.VersionControllerTest)
conn = post(conn, ~p"/versions", version: @create_attrs)

assert %{id: id} = redirected_params(conn)
Expand All @@ -35,7 +28,7 @@
assert html_response(conn, 200) =~ "Version #{id}"
end

test "renders errors when data is invalid", %{conn: conn} do

Check failure on line 31 in apps/configurator/test/configurator_web/controllers/version_controller_test.exs

View workflow job for this annotation

GitHub Actions / Build and test (1.16.0, 26.0.2)

test create version renders errors when data is invalid (ConfiguratorWeb.VersionControllerTest)
conn = post(conn, ~p"/versions", version: @invalid_attrs)
assert html_response(conn, 200) =~ "New Version"
end
Expand Down
62 changes: 62 additions & 0 deletions apps/game_backend/lib/game_backend/configuration.ex
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,33 @@ defmodule GameBackend.Configuration do
"""
def get_version!(id), do: Repo.get!(Version, id)

def get_preloaded_version!(id) do
consumable_items_preload =
from(ci in GameBackend.Items.ConsumableItem,
preload: [
mechanics: [:on_arrival_mechanic, :on_explode_mechanics, :parent_mechanic]
]
)

q =
from(v in Version,
where: v.id == ^id,
preload: [
[consumable_items: ^consumable_items_preload],
[skills: [mechanics: [:on_arrival_mechanic, :on_explode_mechanics]]],
:map_configurations,
:game_configuration,
characters: [
[basic_skill: [mechanics: [:on_arrival_mechanic, :on_explode_mechanics, :parent_mechanic]]],
[ultimate_skill: [mechanics: [:on_arrival_mechanic, :on_explode_mechanics, :parent_mechanic]]],
[dash_skill: [mechanics: [:on_arrival_mechanic, :on_explode_mechanics, :parent_mechanic]]]
]
]
)

Repo.one!(q)
end

@doc """
Creates a version.

Expand All @@ -425,6 +452,41 @@ defmodule GameBackend.Configuration do
|> Repo.insert()
end

def copy_version(attrs \\ %{}) do
Multi.new()
|> Multi.insert(
:version,
%Version{}
|> Version.changeset(attrs)
)
|> Multi.run(:link_character_skills, fn repo, changes ->
characters = changes.version.characters
skills = changes.version.skills

characters
|> Enum.each(fn character ->
character
|> Character.changeset(%{})
|> Ecto.Changeset.put_change(
:basic_skill_id,
Enum.find(skills, fn skill -> skill.name == character.basic_skill.name end).id
)
|> Ecto.Changeset.put_change(
:dash_skill_id,
Enum.find(skills, fn skill -> skill.name == character.dash_skill.name end).id
)
|> Ecto.Changeset.put_change(
:ultimate_skill_id,
Enum.find(skills, fn skill -> skill.name == character.ultimate_skill.name end).id
)
|> repo.update!()
end)

{:ok, :ok}
end)
|> Repo.transaction()
end

@doc """
Updates a arena_server.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ defmodule GameBackend.Units.Characters.Character do
:ultimate_skill_id,
:version_id
])
|> cast_assoc(:basic_skill)
|> cast_assoc(:ultimate_skill)
|> cast_assoc(:basic_skill, with: &Skill.assoc_changeset/2)
|> cast_assoc(:dash_skill, with: &Skill.assoc_changeset/2)
|> cast_assoc(:ultimate_skill, with: &Skill.assoc_changeset/2)
|> unique_constraint([:game_id, :name, :version_id])
|> validate_required([:game_id, :name, :active, :faction])
|> mana_recovery_strategy_validation()
Expand Down
Loading