Basic models for Fizzy do and searches working with them
This commit is contained in:
@@ -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
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
Command::Result::Redirection = Struct.new(:url)
|
||||
@@ -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
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 ></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 %>
|
||||
|
||||
@@ -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 ></span>
|
||||
@@ -11,4 +11,4 @@
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user