-
Notifications
You must be signed in to change notification settings - Fork 26
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
Project aliases #2644
Project aliases #2644
Changes from 22 commits
c94f5e2
b8f3756
3ac26fb
2229d1c
12c738d
5aac91a
fd9e403
744d015
f5e79bb
2ebaf43
ec1e816
829ea96
6fe4e88
a1ce799
8482da1
33946f2
bd5baf9
24233b7
fb4e4b7
2ad9e33
ab0ccf8
16236da
441c144
9493462
35a2c25
339eb57
ea2d105
12a46ed
edecd37
bdb6a9e
d8f0ba4
e6ed733
ebd42a5
15d7e37
e63b77e
aff4fd3
cd9ad1b
120b5c2
d9fd3a0
8ed460f
03a9b4d
737701c
2ad744d
121ed35
796de68
126b8a6
c5ec29e
b9ac087
dc8c31d
3c2bf02
1d4eab8
64d265b
b82e1b1
81b477e
225106b
5480e09
cdc7cb3
89c88e0
2493142
3ed48d0
7aac17b
6db7518
04cad07
7016f02
d397f42
d203a22
e1395bc
56d2698
228abaa
31e4ebe
e5536f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# frozen_string_literal: true | ||
|
||
module Projects | ||
class AliasesController < ApplicationController | ||
before_action :login_required | ||
before_action :pass_query_params, except: [:index] | ||
before_action :set_project_alias, only: [:show, :edit, :update, :destroy] | ||
|
||
def index | ||
@project = Project.find(params[:project_id]) | ||
@project_aliases = ProjectAlias.all | ||
respond_to do |format| | ||
format.html | ||
format.json { render(json: @project_aliases) } | ||
end | ||
end | ||
|
||
def show | ||
respond_to do |format| | ||
format.html | ||
format.json { render(json: @project_alias) } | ||
end | ||
end | ||
|
||
def new | ||
@project_alias = ProjectAlias.new(project_id: params.require(:project_id)) | ||
end | ||
|
||
def edit; end | ||
|
||
def create | ||
@project_alias = ProjectAlias.new(project_alias_params) | ||
|
||
respond_to do |format| | ||
if @project_alias.save | ||
format.html do | ||
project_alias_redirect(@project_alias) | ||
end | ||
format.json do | ||
render(json: @project_alias, status: :created, | ||
location: @project_alias) | ||
end | ||
else | ||
format.html { render(:new) } | ||
format.json do | ||
render(json: @project_alias.errors, status: :unprocessable_entity) | ||
end | ||
end | ||
end | ||
end | ||
|
||
def update | ||
respond_to do |format| | ||
if @project_alias.update(project_alias_params) | ||
format.html do | ||
redirect_to(project_alias_path( | ||
project_id: @project_alias.project_id, | ||
id: @project_alias.id | ||
), | ||
notice: :project_alias_updated.t) | ||
end | ||
format.json { render(json: @project_alias) } | ||
else | ||
format.html { render(:edit) } | ||
format.json do | ||
render(json: @project_alias.errors, status: :unprocessable_entity) | ||
end | ||
end | ||
end | ||
end | ||
|
||
def destroy | ||
project_id = @project_alias.project_id | ||
@project_alias.destroy | ||
respond_to do |format| | ||
format.html do | ||
redirect_to(project_aliases_pat(project_id:), | ||
notice: :project_alias_deleted.t) | ||
end | ||
format.json { head(:no_content) } | ||
end | ||
end | ||
|
||
private | ||
|
||
def project_alias_redirect(project_alias) | ||
redirect_to(project_alias_path( | ||
project_id: project_alias.project_id, | ||
id: project_alias.id | ||
), | ||
notice: :project_alias_created.t) | ||
end | ||
|
||
def set_project_alias | ||
@project_alias = ProjectAlias.find(params[:id]) | ||
end | ||
|
||
def project_alias_params | ||
params.require(:project_alias).permit(:name, :project_id, :target_type, | ||
:location_id, :user_id) | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# frozen_string_literal: true | ||
|
||
class ProjectAlias < ApplicationRecord | ||
belongs_to :target, polymorphic: true | ||
belongs_to :project | ||
|
||
validates :name, presence: true | ||
|
||
def location_id=(id) | ||
self.target_id = id | ||
end | ||
|
||
def user_id=(id) | ||
self.target_id = id | ||
end | ||
|
||
def target_type=(type) | ||
type.capitalize | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<% | ||
type = project_alias.target_type.downcase.to_sym || :location | ||
value = project_alias.target.name || "" | ||
%> | ||
<%= form_with(model: project_alias, | ||
data: { controller: :autocompleter, type: }) do |form| %> | ||
<% if project_alias.errors.any? %> | ||
<div id="error_explanation"> | ||
<h2><%= pluralize(project_alias.errors.count, "error") %> prohibited this project alias from being saved:</h2> | ||
<ul> | ||
<% project_alias.errors.full_messages.each do |message| %> | ||
<li><%= message %></li> | ||
<% end %> | ||
</ul> | ||
</div> | ||
<% end %> | ||
|
||
<div class="field"> | ||
<%= text_field_with_label(form:, field: :name, label: "#{:Name.t}:", inline: true) %> | ||
</div> | ||
mo-nathan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
<div class="field"> | ||
<%= form.hidden_field(:project_id, value: project_alias.project_id) %> | ||
</div> | ||
|
||
<%= tag.div(class: "form-group dropdown", | ||
data: { autocompleter_target: "wrap" } ) do %> | ||
<div class="field"> | ||
<%= select_with_label(form:, | ||
field: :target_type, | ||
label: "#{:project_alias_type.t}:", | ||
options: [[:USER.l, :user], [:LOCATION.l, :location]], | ||
inline: true, | ||
selected: type, | ||
data: { autocompleter_target: "select", | ||
action: "autocompleter#swap" }) %> | ||
</div> | ||
|
||
<%= autocompleter_hidden_field(form:, type:) %> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this needs the arg I anticipate an issue here, because if I understand correctly you're asking for the stimulus controller to do something magical that it does not yet have the ability to do. There is only ever one hidden field and one field in the HTML, and although the type can swap only the initial values can be prefilled. If you want each type's default option (whether Location or User) to be prefilled if the user changes back and forth in the select, it seems we will need to store both of these hidden prefill values as data attributes on the Stimulus root autocompleter element, as something like Then we will need to add a mechanism to the Stimulus autocompleter controller There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm using:
which seems to be working fine. If you think there's still an issue, let me know how to see it. |
||
<%= form.text_field( | ||
:term, value: value, class: "form-control", | ||
data: { autocompleter_target: "input" } | ||
) %> | ||
<%= autocompleter_dropdown %> | ||
<% end %> | ||
|
||
<div class="actions"> | ||
<%= form.submit %> | ||
</div> | ||
mo-nathan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<% end %> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<% | ||
add_project_banner(@project_alias.project) | ||
@container = :wide | ||
mo-nathan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
project_id = @project_alias.project_id | ||
%> | ||
|
||
<h1>Editing Project Alias</h1> | ||
|
||
<%= render('form', project_alias: @project_alias) %> | ||
|
||
<%= link_to 'Show', project_alias_path(project_id:, id: @project_alias.id) %> | | ||
<%= link_to 'Back', project_aliases_path(project_id:) %> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<% | ||
add_project_banner(@project) | ||
@container = :wide | ||
project_id = @project.id | ||
%> | ||
|
||
<h1>Project Aliases</h1> | ||
|
||
<table class="table table-striped table-project-members mt-3"> | ||
<thead> | ||
<tr> | ||
<th>Name</th> | ||
<th>Target Type</th> | ||
<th>Target</th> | ||
<th>Actions</th> | ||
</tr> | ||
</thead> | ||
|
||
<tbody> | ||
<% @project_aliases.each do |project_alias| %> | ||
<tr> | ||
<td><%= project_alias.name %></td> | ||
<td><%= project_alias.target_type %></td> | ||
<td><%= project_alias.target.try(:name) %></td> | ||
<td> | ||
<%= link_to 'Show', project_alias_path(project_id:, id: project_alias.id) %> | ||
<%= link_to 'Edit', edit_project_alias_path(project_id:, id: project_alias.id) %> | ||
<%= link_to 'Delete', project_alias_path(project_id:, id: project_alias.id), method: :delete, data: { confirm: 'Are you sure?' } %> | ||
</td> | ||
</tr> | ||
<% end %> | ||
</tbody> | ||
</table> | ||
|
||
<%= link_to 'New Project Alias', new_project_alias_path(project_id:) %> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<% | ||
add_project_banner(@project_alias.project) | ||
@container = :wide | ||
mo-nathan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
project_id = @project_alias.project_id | ||
%> | ||
|
||
<h1>New Project Alias</h1> | ||
|
||
<%= render('form', project_alias: @project_alias) %> | ||
|
||
<%= link_to('Back', project_aliases_path(project_id: @project_alias.project_id)) %> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<% | ||
add_project_banner(@project_alias.project) | ||
@container = :wide | ||
project_id = @project_alias.project_id | ||
%> | ||
|
||
<p> | ||
<strong>Name:</strong> | ||
<%= @project_alias.name %> | ||
</p> | ||
|
||
<p> | ||
<strong>Target Type:</strong> | ||
<%= @project_alias.target_type %> | ||
</p> | ||
|
||
<p> | ||
<strong>Target:</strong> | ||
<%= @project_alias.target.try(:name) %> | ||
</p> | ||
|
||
<%= link_to 'Edit', edit_project_alias_path(project_id:, id: @project_alias.id) %> | | ||
<%= link_to 'Back', project_aliases_path %> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# frozen_string_literal: true | ||
|
||
class CreateProjectAliases < ActiveRecord::Migration[7.1] | ||
def change | ||
create_table(:project_aliases) do |t| | ||
t.integer(:project_id, null: false) | ||
t.integer(:target_id, null: false) | ||
t.string(:target_type, null: false) | ||
t.string(:name) | ||
|
||
t.timestamps | ||
|
||
t.foreign_key(:projects) | ||
t.index([:target_type, :target_id]) | ||
t.index(:project_id) | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html | ||
|
||
one: | ||
target: rolf | ||
target_type: User | ||
name: MyString | ||
project: eol_project | ||
|
||
two: | ||
target: albion | ||
target_type: Location | ||
name: MyString | ||
project: eol_project |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# frozen_string_literal: true | ||
|
||
require "test_helper" | ||
|
||
class ProjectAliasTest < ActiveSupport::TestCase | ||
test "valid user aliases" do | ||
pa = Project.find_by(target_type: "User") | ||
assert_equal("User", pa.target_type) | ||
assert_equal(User, pa.target.class) | ||
end | ||
|
||
test "valid location aliases" do | ||
pa = Project.find_by(target_type: "Location") | ||
assert_equal(Location, pa.target.class) | ||
mo-nathan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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.
Note that this Stimulus controller has a method
verbose
. If you switch yourto
and then uncomment the actual method body of
verbose
, it will log a whole trace of what it's executing (as defined by wherever Jason and I left lines that saythis.verbose("Say something");
However that may give you more info than you want.