Skip to content

Commit

Permalink
Adds tagging to tickets on items (#1796)
Browse files Browse the repository at this point in the history
# What it does

Allows admins to tag tickets and see them on the ticket index and show
pages.

# Why it is important

#1746 

# UI Change Screenshot

Tags on the index page:
![Screenshot 2024-12-18 at 3 35
29 PM](https://github.com/user-attachments/assets/eab9fcc3-331f-4ad4-bbea-71435ced7af2)

Tags on the show page:
![Screenshot 2024-12-18 at 3 37
17 PM](https://github.com/user-attachments/assets/f618af96-f482-4040-ae3a-823d05295e82)

Tags on the edit page: 
![Screenshot 2024-12-18 at 3 37
26 PM](https://github.com/user-attachments/assets/a187ebc9-a1a1-44db-9407-67a46553f7a4)

Tags on the new page:
![Screenshot 2024-12-18 at 3 37
41 PM](https://github.com/user-attachments/assets/92f99a96-4836-48c1-acbd-fb3ee995c741)

# Implementation notes

I rebased #1795 into this since the tagging gem requires `>= 3.2` Ruby.
Once that's merged this diff should be a little easier to understand.

Right now the tags just appear as light gray chips or pills. We could
add special styles for special tags (eg 'Urgent' with a red background)
but I think this is a good first pass.

The tags look case sensitive but actually aren't. So if you're the first
person to tag something as `Urgent` it will show up as `Urgent` event if
you change it to `urgent`. That also goes for any other tickets that are
tagged `Urgent`.

In terms of tests, I just added onto some existing controller tests.
Maybe system tests for this ticket stuff, but converting them felt like
a lot for right now. In the process of troubleshooting the gem setup I
added a model test that probably isn't _really_ necessary but that file
was empty anyway.
  • Loading branch information
crismali authored Jan 11, 2025
1 parent fa9ed20 commit 1ccd96f
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 9 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,5 @@ gem "ahoy_matey", "~> 5.2"
gem "good_job", "~> 4.7"

gem "blazer", "~> 3.1"

gem "acts-as-taggable-on", "~> 12.0"
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ GEM
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
acts-as-taggable-on (12.0.0)
activerecord (>= 7.1, < 8.1)
zeitwerk (>= 2.4, < 3.0)
acts_as_list (1.2.4)
activerecord (>= 6.1)
activesupport (>= 6.1)
Expand Down Expand Up @@ -588,6 +591,7 @@ PLATFORMS

DEPENDENCIES
activerecord-postgres_enum
acts-as-taggable-on (~> 12.0)
acts_as_list
acts_as_tenant
ahoy_matey (~> 5.2)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/admin/items/tickets_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def set_ticket
end

def ticket_params
params.require(:ticket).permit(:title, :body, :status).merge(creator_id: current_user.id)
params.require(:ticket).permit(:title, :body, :status, :tag_list).merge(creator_id: current_user.id)
end
end
end
Expand Down
4 changes: 3 additions & 1 deletion app/models/ticket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ class Ticket < ApplicationRecord

has_rich_text :body

acts_as_taggable_on :tags

validates :title, presence: true
validates :status, inclusion: {in: Ticket.statuses.keys}

audited
audited except: :tag_list
acts_as_tenant :library

scope :active, -> { where(status: Ticket.statuses.values_at(:assess, :parts, :repairing)) }
Expand Down
1 change: 1 addition & 0 deletions app/views/admin/items/tickets/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<%= form.text_field :title %>
<%= form.rich_text_area :body %>
<%= form.select :status, options_for_select(ticket_status_options, ticket.status), label: "Ticket Status" %>
<%= form.text_field :tag_list, label: "Tags", value: ticket.tag_list.join(", "), hint: "Comma separated e.g. 'Urgent, Quick Fix, etc'" %>

<%= form.actions do %>
<%= form.submit %>
Expand Down
6 changes: 6 additions & 0 deletions app/views/admin/items/tickets/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<tr>
<th>Title</th>
<th>Status</th>
<th>Tags</th>
<th>Last Updated</th>
</tr>
</thead>
Expand All @@ -13,6 +14,11 @@
<tr>
<td><%= link_to ticket.title, admin_item_ticket_path(@item, ticket) %></td>
<td><span class="chip bg-primary"><%= ticket_status_name ticket.status %></span></td>
<td>
<% ticket.tag_list.each do |tag| %>
<span class="chip"><%= tag %></span>
<% end %>
</td>
<td><%= display_date ticket.updated_at, :short_date %></td>
</tr>
<% end %>
Expand Down
4 changes: 4 additions & 0 deletions app/views/admin/items/tickets/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
</h2>
<p class="mb-3">
<span class="chip bg-primary"><%= ticket_status_name @ticket.status %></span>
<% @ticket.tag_list.each do |tag| %>
<span class="chip"><%= tag %></span>
<% end %>
<br>
Created by <%= link_to_member(@ticket.creator.member) %> on <%= display_date @ticket.created_at, :short_date %>
</p>

Expand Down
1 change: 1 addition & 0 deletions config/initializers/acts_as_taggable_on.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ActsAsTaggableOn.force_lowercase = true
36 changes: 36 additions & 0 deletions db/migrate/20241218224853_acts_as_taggable_on_migration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
class ActsAsTaggableOnMigration < ActiveRecord::Migration[7.2]
def change
create_table "taggings", force: :cascade do |t|
t.bigint "tag_id"
t.string "taggable_type"
t.bigint "taggable_id"
t.string "tagger_type"
t.bigint "tagger_id"
t.string "context", limit: 128
t.datetime "created_at", precision: nil
t.string "tenant", limit: 128
t.index ["context"], name: "index_taggings_on_context"
t.index ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true
t.index ["tag_id"], name: "index_taggings_on_tag_id"
t.index ["taggable_id", "taggable_type", "context"], name: "taggings_taggable_context_idx"
t.index ["taggable_id", "taggable_type", "tagger_id", "context"], name: "taggings_idy"
t.index ["taggable_id"], name: "index_taggings_on_taggable_id"
t.index ["taggable_type", "taggable_id"], name: "index_taggings_on_taggable_type_and_taggable_id"
t.index ["taggable_type"], name: "index_taggings_on_taggable_type"
t.index ["tagger_id", "tagger_type"], name: "index_taggings_on_tagger_id_and_tagger_type"
t.index ["tagger_id"], name: "index_taggings_on_tagger_id"
t.index ["tagger_type", "tagger_id"], name: "index_taggings_on_tagger_type_and_tagger_id"
t.index ["tenant"], name: "index_taggings_on_tenant"
end

create_table "tags", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "taggings_count", default: 0
t.index ["name"], name: "index_tags_on_name", unique: true
end

add_foreign_key "taggings", "tags"
end
end
34 changes: 33 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.2].define(version: 2024_12_18_023052) do
ActiveRecord::Schema[7.2].define(version: 2024_12_18_224853) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -855,6 +855,37 @@
t.index ["question_id"], name: "index_stems_on_question_id"
end

create_table "taggings", force: :cascade do |t|
t.bigint "tag_id"
t.string "taggable_type"
t.bigint "taggable_id"
t.string "tagger_type"
t.bigint "tagger_id"
t.string "context", limit: 128
t.datetime "created_at", precision: nil
t.string "tenant", limit: 128
t.index ["context"], name: "index_taggings_on_context"
t.index ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true
t.index ["tag_id"], name: "index_taggings_on_tag_id"
t.index ["taggable_id", "taggable_type", "context"], name: "taggings_taggable_context_idx"
t.index ["taggable_id", "taggable_type", "tagger_id", "context"], name: "taggings_idy"
t.index ["taggable_id"], name: "index_taggings_on_taggable_id"
t.index ["taggable_type", "taggable_id"], name: "index_taggings_on_taggable_type_and_taggable_id"
t.index ["taggable_type"], name: "index_taggings_on_taggable_type"
t.index ["tagger_id", "tagger_type"], name: "index_taggings_on_tagger_id_and_tagger_type"
t.index ["tagger_id"], name: "index_taggings_on_tagger_id"
t.index ["tagger_type", "tagger_id"], name: "index_taggings_on_tagger_type_and_tagger_id"
t.index ["tenant"], name: "index_taggings_on_tenant"
end

create_table "tags", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "taggings_count", default: 0
t.index ["name"], name: "index_tags_on_name", unique: true
end

create_table "ticket_updates", force: :cascade do |t|
t.integer "time_spent"
t.bigint "ticket_id", null: false
Expand Down Expand Up @@ -959,6 +990,7 @@
add_foreign_key "reservations", "users", column: "reviewer_id"
add_foreign_key "reservations", "users", column: "submitted_by_id"
add_foreign_key "stems", "questions"
add_foreign_key "taggings", "tags"
add_foreign_key "ticket_updates", "audits"
add_foreign_key "ticket_updates", "tickets"
add_foreign_key "ticket_updates", "users", column: "creator_id"
Expand Down
10 changes: 7 additions & 3 deletions test/controllers/admin/items/tickets_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
status = "assess"
title = "A ticket title"
body = "A ticket body"
tags = ["a", "b", "c"]

assert_difference("Ticket.count") do
post admin_item_tickets_url(@item), params: {ticket: {status:, title:, body:}}
post admin_item_tickets_url(@item), params: {ticket: {status:, title:, body:, tag_list: tags.join(", ")}}
end

assert_redirected_to admin_item_ticket_url(@item, Ticket.last)
Expand All @@ -43,6 +44,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
assert_equal status, ticket.status
assert_equal title, ticket.title
assert_equal body, ticket.body.to_plain_text
assert_equal tags, ticket.tag_list
end

test "creating a ticket with any status besides 'retired' updates the ticket's status to 'maintenance'" do
Expand Down Expand Up @@ -91,17 +93,19 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
end

test "should update ticket" do
@ticket = create(:ticket, item: @item)
@ticket = create(:ticket, item: @item, tag_list: %w[foo bar])
status = "parts"
body = "Waiting on parts"
tags = ["a", "b", "c"]

patch admin_item_ticket_url(@item, @ticket), params: {ticket: {status:, body:}}
patch admin_item_ticket_url(@item, @ticket), params: {ticket: {status:, body:, tag_list: tags.join(", ")}}

assert_redirected_to admin_item_ticket_url(@item, @ticket)

@ticket.reload
assert_equal status, @ticket.status
assert_equal body, @ticket.body.to_plain_text
assert_equal tags, @ticket.tag_list
end

test "updating a ticket to retired makes the item retired" do
Expand Down
20 changes: 17 additions & 3 deletions test/models/ticket_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
require "test_helper"

class TicketTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
test "has tags" do
ticket = create(:ticket)

ticket.tag_list.add("aWesoMe", "NOT awesome")
assert ticket.save

ticket.reload

assert_equal ["awesome", "not awesome"], ticket.tag_list

ticket.tag_list.remove("not awesome")

assert ticket.save

ticket.reload
assert_equal ["awesome"], ticket.tag_list
end
end

0 comments on commit 1ccd96f

Please sign in to comment.