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

ROAD-536 Add VersionJump model and admin integration #299

Merged
merged 4 commits into from
Sep 6, 2023
Merged
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
5 changes: 4 additions & 1 deletion app/assets/stylesheets/3-atoms/_badges.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
font-size: 11px;

&.archived {
background-color: rgba(29,78,216,0.2);
background-color: rgba(29, 78, 216, 0.2);
border-color: #1d4ed8;
}

Expand All @@ -19,4 +19,7 @@
border-color: #d77e72;
}

&.version-jump {
background-color: #57ce81;
}
}
1 change: 1 addition & 0 deletions app/assets/stylesheets/3-atoms/_forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ input[type="checkbox"] {
}

.field,
.select,
.actions {
margin-bottom: 10px;
}
1 change: 1 addition & 0 deletions app/controllers/madmin/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Madmin
class ApplicationController < Madmin::BaseController
include Pundit::Authorization
before_action :ensure_admin

def ensure_admin
Expand Down
4 changes: 4 additions & 0 deletions app/controllers/madmin/version_jumps_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Madmin
class VersionJumpsController < Madmin::ResourceController
end
end
6 changes: 3 additions & 3 deletions app/controllers/projects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def toggle_locked
end

def new_clone
@original = Project.includes(:projects, stories: :estimates).find(params[:id])
@original = Project.includes(:projects, :version_jump, stories: :estimates).find(params[:id])
end

def clone
Expand Down Expand Up @@ -111,11 +111,11 @@ def find_project
end

def projects_params
params.require(:project).permit(:title, :status, :parent_id)
params.require(:project).permit(:title, :status, :parent_id, :version_jump_id)
end

def clone_params
params.require(:project).permit(:title, :parent_id)
params.require(:project).permit(:title, :parent_id, :version_jump_id)
end

def parent_id
Expand Down
7 changes: 7 additions & 0 deletions app/helpers/projects_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ def link_unless_archived(project, text, url, classes: nil, method: :get, remote:
end
end

def version_jump_badge(project)
return "" unless project.version_jump

jump = project.version_jump
content_tag(:span, jump.to_label, class: "status-badge version-jump")
end

private

def text_content(icon, text)
Expand Down
1 change: 1 addition & 0 deletions app/madmin/resources/project_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class ProjectResource < Madmin::Resource
attribute :users
attribute :parent
attribute :projects
attribute :version_jump

def self.display_name(record)
record.title.truncate(20)
Expand Down
24 changes: 24 additions & 0 deletions app/madmin/resources/version_jump_resource.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class VersionJumpResource < Madmin::Resource
# Attributes
attribute :id, form: false
attribute :technology
attribute :initial_version
attribute :target_version

# Associations
attribute :projects, form: false

# Uncomment this to customize the display name of records in the admin area.
def self.display_name(record)
record.to_label
end

# Uncomment this to customize the default sort column and direction.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can/should we get rid of these comments if we aren't customizing the default_sort_column?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was already there commented out in the other resources. Not sure why that was not removed before, so I'd say to note remove it just for this resource (maybe some low-priority story can be about cleaning up these comments, I don't want to change files that I don't need to change for a comment)

# def self.default_sort_column
# "created_at"
# end
#
# def self.default_sort_direction
# "desc"
# end
end
5 changes: 5 additions & 0 deletions app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class Project < ApplicationRecord
has_many :stories
has_many :estimates, through: :stories
has_many :users, through: :estimates
belongs_to :version_jump, optional: true

belongs_to :parent, class_name: "Project", required: false
has_many :projects, class_name: "Project", foreign_key: :parent_id, dependent: :destroy
Expand Down Expand Up @@ -52,6 +53,10 @@ def archived?
status == "archived"
end

def locked?
locked_at.present?
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can revert this change, but was really simple to add (I updated some code that was using project.locekd_at.nil? directly)


def breadcrumb
parent.present? ? "#{parent.breadcrumb} » #{title}" : title
end
Expand Down
10 changes: 10 additions & 0 deletions app/models/version_jump.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class VersionJump < ApplicationRecord
has_many :projects

validates :technology, :initial_version, :target_version, presence: true
validates :technology, uniqueness: {scope: [:initial_version, :target_version]}

def to_label
"#{technology} / #{initial_version} - #{target_version}"
end
end
2 changes: 2 additions & 0 deletions app/policies/estimate_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class EstimatePolicy < ApplicationPolicy
end
2 changes: 2 additions & 0 deletions app/policies/project_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ def initialize(user, project)
end

def update?
return false unless project.is_a?(Project)

return !project.locked_at? if project.parent_id.nil?

!project.parent.locked_at?
Expand Down
2 changes: 2 additions & 0 deletions app/policies/story_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class StoryPolicy < ApplicationPolicy
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to create all the policies to be able to use this Pundit feature in the admin panel

2 changes: 2 additions & 0 deletions app/policies/user_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class UserPolicy < ApplicationPolicy
end
9 changes: 9 additions & 0 deletions app/policies/version_jump_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class VersionJumpPolicy < ApplicationPolicy
def update?
true
end

def create?
true
end
end
10 changes: 9 additions & 1 deletion app/views/madmin/application/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
</svg>
<% end %>
</form>

<% if policy(resource).create? %>
<%= link_to resource.new_path, class: "bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow" do %>
New <span class="hidden md:inline"><%= resource.friendly_name %></span>
<% end %>
<% end %>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took this back from the original gem

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the original gem? madmin?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

</div>
</div>

Expand Down Expand Up @@ -48,7 +54,9 @@

<td class="px-4 py-2 text-center">
<%= link_to "View", resource.show_path(record), class: "text-indigo-500" %>
<%# = link_to "Edit", resource.edit_path(record), class: "text-indigo-500" %>
<% if policy(resource).update? %>
<%= link_to "Edit", resource.edit_path(record), class: "text-indigo-500" %>
<% end %>
</td>
</tr>
<% end %>
Expand Down
8 changes: 6 additions & 2 deletions app/views/madmin/application/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@

<div class="flex items-center px-4">
<div class="mr-2">
<%# = link_to "Edit", resource.edit_path(@record), class: "block bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow" %>
<% if policy(resource).update? %>
<%= link_to "Edit", resource.edit_path(@record), class: "block bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow" %>
<% end %>
</div>
<%# = button_to "Delete", resource.show_path(@record), method: :delete, data: { turbo_confirm: "Are you sure?" }, class: "bg-white hover:bg-gray-100 text-red-500 font-semibold py-2 px-4 border border-red-500 rounded shadow pointer-cursor" %>
<% if policy(resource).destroy? %>
<%= button_to "Delete", resource.show_path(@record), method: :delete, data: { turbo_confirm: "Are you sure?" }, class: "bg-white hover:bg-gray-100 text-red-500 font-semibold py-2 px-4 border border-red-500 rounded shadow pointer-cursor" %>
<% end %>
</div>
</div>

Expand Down
5 changes: 5 additions & 0 deletions app/views/projects/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
<%= f.text_field :title, placeholder: "Project Title", class: "project-story-title", autofocus: true %>
</div>

<div class="select">
<%= f.label :version_jump_id %>
<%= f.select :version_jump_id, options_from_collection_for_select(VersionJump.all, :id, :to_label) %>
</div>

<div class="btn-group">
<%= f.submit yield(:button_text), class: "button green", id: "edit" %>
</div>
Expand Down
5 changes: 5 additions & 0 deletions app/views/projects/_sub_project_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
<%= f.hidden_field :parent_id, value: parent.id %>
</div>

<div class="select">
<%= f.label :version_jump_id %>
<%= f.select :version_jump_id, options_from_collection_for_select(VersionJump.all, :id, :to_label) %>
</div>

<div class="btn-group">
<%= f.submit yield(:button_text), class: "button green", id: "edit" %>
</div>
Expand Down
9 changes: 7 additions & 2 deletions app/views/projects/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@
<%= link_to project_path(project.id) do %>
<div>
<h2><%= project.title %></h2>
<span class="status-badge locked <%= "hide" if project.locked_at.nil? %>">Locked</span>
<span class="status-badge <%= project.status %>"><%= project.status %></span>
<% if project.locked? %>
<span class="status-badge locked">Locked</span>
<% end %>
<% if project.status.present? %>
<span class="status-badge <%= project.status %>"><%= project.status %></span>
<% end %>
<%= version_jump_badge(project) %>
</div>
<% end %>
<div class="sortable-projects" data-url="<%= sort_project_path(project.id) %>">
Expand Down
5 changes: 5 additions & 0 deletions app/views/projects/new_clone.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
<%= f.select :parent_id, options_from_collection_for_select(Project.active.parents, :id, :title, selected: @original.parent_id), include_blank: "None" %>
</div>

<div class="select">
<%= f.label :version_jump_id %>
<%= f.select :version_jump_id, options_from_collection_for_select(VersionJump.all, :id, :to_label) %>
</div>

<% if @original.projects.any? %>
<div id="sub-projects-to-clone">
<h4>Sub-projects to clone</h4>
Expand Down
1 change: 1 addition & 0 deletions app/views/projects/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
<% end %>

<%= link_to 'Clone Project', new_clone_project_path(@project.id), class: "button green" %>
<%= link_to 'Edit Project', edit_project_path(@project.id), class: "button green" %>

<% if is_unlocked?(@project) %>
<%= link_unless_archived(@project, "Add Sub-Project", project_new_sub_project_path(@project), classes: :green) unless @project.parent_id.present? %>
Expand Down
1 change: 1 addition & 0 deletions app/views/shared/_project_title.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<% end %>

<div>
<%= version_jump_badge(project) %>
<span class="status-badge locked <%= "hide" if project.locked_at.nil? %>">Locked</span>
<span class="status-badge <%= project.status %> <%= "hide" if project.status.nil? %>"><%= project.status %></span>
</div>
1 change: 1 addition & 0 deletions config/routes/madmin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
resources :stories
resources :estimates, except: [:update, :edit, :create]
resources :users, except: [:update, :edit, :create]
resources :version_jumps
root to: "dashboard#show"
end
11 changes: 11 additions & 0 deletions db/migrate/20230830143908_create_version_jumps.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateVersionJumps < ActiveRecord::Migration[7.0]
def change
create_table :version_jumps do |t|
t.string :technology
t.string :initial_version
t.string :target_version

t.timestamps
end
end
end
5 changes: 5 additions & 0 deletions db/migrate/20230831175732_add_version_jump_to_projects.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddVersionJumpToProjects < ActiveRecord::Migration[7.0]
def change
add_reference :projects, :version_jump
end
end
12 changes: 11 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2022_06_21_141342) do
ActiveRecord::Schema[7.0].define(version: 2023_08_31_175732) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand All @@ -31,6 +31,8 @@
t.integer "parent_id"
t.integer "position"
t.datetime "locked_at", precision: nil
t.bigint "version_jump_id"
t.index ["version_jump_id"], name: "index_projects_on_version_jump_id"
end

create_table "stories", force: :cascade do |t|
Expand Down Expand Up @@ -65,4 +67,12 @@
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end

create_table "version_jumps", force: :cascade do |t|
t.string "technology"
t.string "initial_version"
t.string "target_version"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

end
1 change: 1 addition & 0 deletions spec/factories/projects.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
FactoryBot.define do
factory :project do
title { Faker::Company.name }
version_jump
trait :locked do
locked_at { Time.current }
end
Expand Down
7 changes: 7 additions & 0 deletions spec/factories/version_jump.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FactoryBot.define do
factory :version_jump do
sequence(:technology) { |n| ["Rails", "Ruby", "Node", "React"].sample + n.to_s }
initial_version { ["2.3", "3.0", "3.1", "3.2", "4.0", "4.1", "4.2"].sample }
target_version { ["5.0", "5.1", "5.2", "6.0", "6.1", "7.0"].sample }
end
end
26 changes: 19 additions & 7 deletions spec/features/projects_manage_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
RSpec.describe "managing projects", js: true do
let(:user) { FactoryBot.create(:user) }
let(:project) { FactoryBot.create(:project) }
let!(:version_jump) { VersionJump.create(technology: "Rails", initial_version: "4.2", target_version: "5.0") }

before do
login_as(user, scope: :user)
Expand All @@ -16,9 +17,16 @@
it "allows me to add a project" do
visit root_path
click_link "Add a Project"
fill_in "project[title]", with: "Super Project"
click_button "Create"
expect(Project.count).to eq 1
fill_in "Title", with: "Super Project"
select "Rails / 4.2 - 5.0", from: "Version jump"

expect {
click_button "Create"
}.to change(Project, :count).by 1

project = Project.last
expect(project.title).to eq "Super Project"
expect(project.version_jump.to_label).to eq "Rails / 4.2 - 5.0"
end

context "when the project is archived" do
Expand Down Expand Up @@ -84,10 +92,14 @@
it "allows me to add sub projects" do
visit project_path(id: project.id)
click_link "Add Sub-Project"
fill_in "project[title]", with: "Super Sub Project"
click_button "Create"
expect(page).to have_content "Project created!"
fill_in "Title", with: "Super Sub Project"
expect {
click_button "Create"
}.to change(Project, :count).by 1
expect(current_path).to eq project_path(id: project.id)

sub = project.projects.last
expect(sub.title).to eq "Super Sub Project"
end

it "lists available sub projects with a link" do
Expand Down Expand Up @@ -203,7 +215,7 @@

expect(page).to have_text("Clone project #{project.title}")

fill_in :project_title, with: "Cloned Project"
fill_in "Title", with: "Cloned Project"

expect {
click_button "Clone"
Expand Down
Loading
Loading