diff --git a/app/javascript/controllers/terminal_controller.js b/app/javascript/controllers/terminal_controller.js
index e951695f0..26cbde90b 100644
--- a/app/javascript/controllers/terminal_controller.js
+++ b/app/javascript/controllers/terminal_controller.js
@@ -20,6 +20,11 @@ export default class extends Controller {
}
}
+ restoreCommand(event) {
+ this.#reset(event.target.dataset.line)
+ this.focus()
+ }
+
async #handleErrorResponse(response) {
const status = response.status
const message = await response.text()
diff --git a/app/models/command/parser.rb b/app/models/command/parser.rb
index e389b2d64..fa758154b 100644
--- a/app/models/command/parser.rb
+++ b/app/models/command/parser.rb
@@ -8,20 +8,27 @@ class Command::Parser
end
def parse(string)
- command_name, *command_arguments = string.strip.split(" ")
-
- case command_name
- when "/assign", "/assignto"
- Command::Assign.new(assignee_ids: assignees_from(command_arguments).collect(&:id), card_ids: cards.ids)
- when "/close"
- Command::Close.new(card_ids: cards.ids, reason: command_arguments.join(" "))
- when /^@/
- Command::GoToUser.new(user_id: assignee_from(command_name)&.id)
- else
- parse_free_string(string)
+ parse_command(string).tap do |command|
+ command&.line = string
end
end
+ private
+ def parse_command(string)
+ command_name, *command_arguments = string.strip.split(" ")
+
+ case command_name
+ when "/assign", "/assignto"
+ Command::Assign.new(assignee_ids: assignees_from(command_arguments).collect(&:id), card_ids: cards.ids)
+ when "/close"
+ Command::Close.new(card_ids: cards.ids, reason: command_arguments.join(" "))
+ when /^@/
+ Command::GoToUser.new(user_id: assignee_from(command_name)&.id)
+ else
+ parse_free_string(string)
+ end
+ end
+
private
def assignees_from(strings)
Array(strings).filter_map do |string|
diff --git a/app/views/commands/_command.html.erb b/app/views/commands/_command.html.erb
index c10b933e3..f034130b9 100644
--- a/app/views/commands/_command.html.erb
+++ b/app/views/commands/_command.html.erb
@@ -1,5 +1,5 @@
-
+
<% if command.undoable? %>
<%= button_to "Undo", command_undo_path(command), class: "btn btn--plain terminal__button flex-item-justify-end", data: { turbo_confirm: "Are you sure you want to undo '#{command.title}'?", turbo_frame: "_top" } %>
diff --git a/db/migrate/20250507095113_add_line_to_commands.rb b/db/migrate/20250507095113_add_line_to_commands.rb
new file mode 100644
index 000000000..2978f9869
--- /dev/null
+++ b/db/migrate/20250507095113_add_line_to_commands.rb
@@ -0,0 +1,5 @@
+class AddLineToCommands < ActiveRecord::Migration[8.1]
+ def change
+ add_column :commands, :line, :text
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index a483fa57b..ddcbf6956 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[8.1].define(version: 2025_05_05_123008) do
+ActiveRecord::Schema[8.1].define(version: 2025_05_07_095113) do
create_table "accesses", force: :cascade do |t|
t.integer "collection_id", null: false
t.datetime "created_at", null: false
@@ -162,6 +162,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_05_05_123008) do
create_table "commands", force: :cascade do |t|
t.datetime "created_at", null: false
t.json "data", default: {}
+ t.text "line"
t.string "type"
t.datetime "updated_at", null: false
t.integer "user_id", null: false
diff --git a/db/schema_cache.yml b/db/schema_cache.yml
index 80a9473e8..1ae033f77 100644
--- a/db/schema_cache.yml
+++ b/db/schema_cache.yml
@@ -553,6 +553,16 @@ columns:
collation:
comment:
- *6
+ - !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
+ auto_increment:
+ name: line
+ cast_type: *14
+ sql_type_metadata: *15
+ 'null': true
+ default:
+ default_function:
+ collation:
+ comment:
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: type
@@ -2051,4 +2061,4 @@ indexes:
comment:
valid: true
workflows: []
-version: 20250505123008
+version: 20250507095113
diff --git a/test/models/command/parser_test.rb b/test/models/command/parser_test.rb
index c4d442dee..a1d648a1f 100644
--- a/test/models/command/parser_test.rb
+++ b/test/models/command/parser_test.rb
@@ -1 +1,12 @@
+require "test_helper"
+
# The parser is tested through the tests of specific commands. See +Command::AssignTests+, etc.
+class Command::ParserTest < ActionDispatch::IntegrationTest
+ include CommandTestHelper
+
+ test "the parsed command contains the raw line" do
+ result = parse_command "assign @kevin"
+ assert_equal "assign @kevin", result.line
+ end
+end
+