Basic models for Fizzy do and searches working with them

This commit is contained in:
Jorge Manrubia
2025-05-05 17:28:57 +02:00
parent 8e0154addc
commit 65d809dd8d
15 changed files with 217 additions and 44 deletions
+25
View File
@@ -0,0 +1,25 @@
class CommandsController < ApplicationController
def create
command = parse_command(params[:command])
if command
result = command.execute
case result
when Command::Result::Redirection
redirect_to url_for(result.url)
else
redirect_back_or_to root_path
end
else
raise "Pending to handle invalid commands"
end
end
private
def parse_command(string)
Command::Parser.new(Current.user).parse(string).tap do |command|
Current.user.commands << command if command
end
end
end
@@ -0,0 +1,8 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = [ "input" ]
// Actions
}
+20
View File
@@ -0,0 +1,20 @@
class Command < ApplicationRecord
include Rails.application.routes.url_helpers
belongs_to :user
def execute
end
def undo
end
def can_undo?
false
end
private
def redirect_to(...)
Command::Result::Redirection.new(...)
end
end
+24
View File
@@ -0,0 +1,24 @@
class Command::GoToCard < Command
store_accessor :data, :card_id
def card=(card)
self.card_id = card.id
end
def execute
redirect_to card
end
def description
"Search '#{query}"
end
def to_command
query
end
private
def card
user.accessible_cards.find(card_id)
end
end
+15
View File
@@ -0,0 +1,15 @@
class Command::Parser
attr_reader :user
def initialize(user)
@user = user
end
def parse(string)
if card = user.accessible_cards.find_by_id(string)
Command::GoToCard.new(card: card)
else
Command::Search.new(query: string)
end
end
end
+1
View File
@@ -0,0 +1 @@
Command::Result::Redirection = Struct.new(:url)
+15
View File
@@ -0,0 +1,15 @@
class Command::Search < Command
store_accessor :data, :query
def execute
redirect_to cards_path("terms[]": query)
end
def description
"Search '#{query}"
end
def to_command
query
end
end
+1
View File
@@ -15,6 +15,7 @@ class User < ApplicationRecord
has_many :closures, dependent: :nullify
has_many :pins, dependent: :destroy
has_many :pinned_cards, through: :pins, source: :card
has_many :commands, dependent: :destroy
normalizes :email_address, with: ->(value) { value.strip.downcase }
+1 -1
View File
@@ -50,7 +50,7 @@
<div id="footer_frames" data-turbo-permanent="true">
<%= render "notifications/tray" %>
<%= render "my/pins/tray" %>
<%= turbo_frame_tag "terminal", src: terminal_path %>
<%= render "my/commands/input" %>
</div>
<% end %>
</footer>
+26
View File
@@ -0,0 +1,26 @@
<%= tag.div class: "terminal full-width flex flex-column gap justify-end", data: {
controller: "toggle-class commands",
toggle_class_toggle_class: "terminal--open" } do %>
<menu class="terminal__menu flex-column txt-align-start margin-none margin-block-end unpad">
<% # Should move to frame %>
<%= render partial: "terminals/event", collection: Current.user.accessible_events.chronologically.reverse_order.limit(20) %>
</menu>
<%= form_tag commands_path,
class: "flex align-center gap-half",
data: { controller: "form" } do %>
<label class="terminal__label txt-nowrap" for="fizzy_do">Fizzy do &gt;</label>
<%= text_field_tag "command", nil,
autocomplete: "off",
autocorrect: "off",
autocapitalize: "off",
class: "terminal__input input fill-transparent unpad",
data: {
commands_target: "input",
action: "keydown.up->toggle-class#add:prevent keydown.down->toggle-class#remove:prevent"
},
placeholder: "Search or type commands…" %>
<% end %>
<% end %>
+3 -3
View File
@@ -1,9 +1,9 @@
<%= turbo_frame_tag "terminal" do %>
<div class="terminal full-width flex flex-column gap justify-end" data-controller="toggle-class" data-toggle-class-toggle-class="terminal--open">
<menu class="terminal__menu flex-column txt-align-start margin-none margin-block-end unpad">
<%= render partial: "event", collection: @events %>
<%= render partial: "event", collection: @events %>
</menu>
<%= turbo_frame_tag "terminal_form" do %>
<%= link_to edit_terminal_path, class: "terminal__link flex align-center gap-half min-width", data: { action: "keydown.meta+shift+p@document->hotkey#click", controller: "hotkey" } do %>
<span class="terminal__label txt-nowrap">Fizzy do &gt;</span>
@@ -11,4 +11,4 @@
<% end %>
<% end %>
</div>
<% end %>
<% end %>
+2
View File
@@ -89,6 +89,8 @@ Rails.application.routes.draw do
end
end
resources :commands
namespace :my do
resources :pins
end
@@ -0,0 +1,10 @@
class CreateCommands < ActiveRecord::Migration[8.1]
def change
create_table :commands do |t|
t.references :user, null: false, foreign_key: true, index: true
t.json :data, default: {}
t.timestamps
end
end
end
Generated
+10 -2
View File
@@ -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_04_29_162506) do
ActiveRecord::Schema[8.1].define(version: 2025_05_05_123008) do
create_table "accesses", force: :cascade do |t|
t.integer "collection_id", null: false
t.datetime "created_at", null: false
@@ -159,6 +159,14 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_29_162506) do
t.index ["filter_id"], name: "index_collections_filters_on_filter_id"
end
create_table "commands", force: :cascade do |t|
t.datetime "created_at", null: false
t.json "data", default: {}
t.datetime "updated_at", null: false
t.integer "user_id", null: false
t.index ["user_id"], name: "index_commands_on_user_id"
end
create_table "comments", force: :cascade do |t|
t.integer "card_id", null: false
t.datetime "created_at", null: false
@@ -280,7 +288,6 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_29_162506) do
t.datetime "created_at", null: false
t.string "title"
t.datetime "updated_at", null: false
t.index ["title"], name: "index_tags_on_account_id_and_title", unique: true
end
create_table "users", force: :cascade do |t|
@@ -327,6 +334,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_29_162506) do
add_foreign_key "closures", "cards"
add_foreign_key "closures", "users"
add_foreign_key "collections", "workflows"
add_foreign_key "commands", "users"
add_foreign_key "comments", "cards"
add_foreign_key "events", "collections"
add_foreign_key "mentions", "users", column: "mentionee_id"
+56 -38
View File
@@ -80,7 +80,7 @@ columns:
default_function:
collation:
comment:
- &28 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
- &24 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: user_id
cast_type: *1
@@ -532,6 +532,29 @@ columns:
collections_filters:
- *22
- *18
commands:
- *5
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: data
cast_type: &25 !ruby/object:ActiveRecord::Type::Json
precision:
scale:
limit:
sql_type_metadata: &26 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
sql_type: json
type: :json
limit:
precision:
scale:
'null': true
default: "{}"
default_function:
collation:
comment:
- *6
- *9
- *24
comments:
- *21
- *5
@@ -579,16 +602,8 @@ columns:
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: particulars
cast_type: &24 !ruby/object:ActiveRecord::Type::Json
precision:
scale:
limit:
sql_type_metadata: &25 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
sql_type: json
type: :json
limit:
precision:
scale:
cast_type: *25
sql_type_metadata: *26
'null': true
default: "{}"
default_function:
@@ -601,8 +616,8 @@ columns:
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: fields
cast_type: *24
sql_type_metadata: *25
cast_type: *25
sql_type_metadata: *26
'null': false
default: "{}"
default_function:
@@ -667,7 +682,7 @@ columns:
default_function:
collation:
comment:
- &26 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
- &27 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: source_id
cast_type: *1
@@ -677,7 +692,7 @@ columns:
default_function:
collation:
comment:
- &27 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
- &28 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: source_type
cast_type: *7
@@ -711,16 +726,16 @@ columns:
default_function:
collation:
comment:
- *26
- *27
- *9
- *28
- *9
- *24
pins:
- *21
- *5
- *6
- *9
- *28
- *24
reactions:
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
@@ -800,7 +815,7 @@ columns:
default_function:
collation:
comment:
- *28
- *24
taggings:
- *21
- *5
@@ -862,7 +877,7 @@ columns:
- *5
- *6
- *9
- *28
- *24
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: watching
@@ -921,6 +936,7 @@ primary_keys:
closures: id
collections: id
collections_filters:
commands: id
comments: id
creators_filters:
events: id
@@ -957,6 +973,7 @@ data_sources:
closures: true
collections: true
collections_filters: true
commands: true
comments: true
creators_filters: true
events: true
@@ -1450,6 +1467,23 @@ indexes:
nulls_not_distinct:
comment:
valid: true
commands:
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: commands
name: index_commands_on_user_id
unique: false
columns:
- user_id
lengths: {}
orders: {}
opclasses: {}
where:
type:
using:
include:
nulls_not_distinct:
comment:
valid: true
comments:
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: comments
@@ -1905,23 +1939,7 @@ indexes:
nulls_not_distinct:
comment:
valid: true
tags:
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: tags
name: index_tags_on_account_id_and_title
unique: true
columns:
- title
lengths: {}
orders: {}
opclasses: {}
where:
type:
using:
include:
nulls_not_distinct:
comment:
valid: true
tags: []
users:
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: users
@@ -2006,4 +2024,4 @@ indexes:
comment:
valid: true
workflows: []
version: 20250429162506
version: 20250505123008