Browse Source

hot_search

main
pvincent 1 month ago
parent
commit
b9968ae3b2
  1. 2
      Gemfile
  2. 138
      Gemfile.lock
  3. 3
      app/helpers/pagy_helper.rb
  4. 23
      app/javascript/controllers/hot_search_controller.js
  5. 3
      app/models/application_record.rb
  6. 13
      app/views/scores/_scores.html.erb
  7. 4
      config/environments/production.rb
  8. 6
      config/environments/test.rb
  9. 2
      config/initializers/backtrace_cleaning.rb
  10. 2
      config/initializers/hot_changes.rb
  11. 5
      config/initializers/rails_live_reload.rb
  12. 14
      db/schema.rb
  13. 20
      lib/semantic/ansi_formatter.rb

2
Gemfile

@ -1,6 +1,7 @@
source 'https://rubygems.org'
ruby '3.1.2'
gem 'amazing_print'
gem 'bootsnap', require: false
gem 'dotenv-rails'
gem 'importmap-rails'
@ -17,7 +18,6 @@ gem 'tailwindcss-rails'
gem 'turbo-rails'
group :development do
gem 'amazing_print'
gem 'debug'
gem 'error_highlight'
gem 'htmlbeautifier'

138
Gemfile.lock

@ -1,29 +1,29 @@
GEM
remote: https://rubygems.org/
specs:
actioncable (7.2.0)
actionpack (= 7.2.0)
activesupport (= 7.2.0)
actioncable (7.2.1)
actionpack (= 7.2.1)
activesupport (= 7.2.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (7.2.0)
actionpack (= 7.2.0)
activejob (= 7.2.0)
activerecord (= 7.2.0)
activestorage (= 7.2.0)
activesupport (= 7.2.0)
actionmailbox (7.2.1)
actionpack (= 7.2.1)
activejob (= 7.2.1)
activerecord (= 7.2.1)
activestorage (= 7.2.1)
activesupport (= 7.2.1)
mail (>= 2.8.0)
actionmailer (7.2.0)
actionpack (= 7.2.0)
actionview (= 7.2.0)
activejob (= 7.2.0)
activesupport (= 7.2.0)
actionmailer (7.2.1)
actionpack (= 7.2.1)
actionview (= 7.2.1)
activejob (= 7.2.1)
activesupport (= 7.2.1)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (7.2.0)
actionview (= 7.2.0)
activesupport (= 7.2.0)
actionpack (7.2.1)
actionview (= 7.2.1)
activesupport (= 7.2.1)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4, < 3.2)
@ -32,35 +32,35 @@ GEM
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actiontext (7.2.0)
actionpack (= 7.2.0)
activerecord (= 7.2.0)
activestorage (= 7.2.0)
activesupport (= 7.2.0)
actiontext (7.2.1)
actionpack (= 7.2.1)
activerecord (= 7.2.1)
activestorage (= 7.2.1)
activesupport (= 7.2.1)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.2.0)
activesupport (= 7.2.0)
actionview (7.2.1)
activesupport (= 7.2.1)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (7.2.0)
activesupport (= 7.2.0)
activejob (7.2.1)
activesupport (= 7.2.1)
globalid (>= 0.3.6)
activemodel (7.2.0)
activesupport (= 7.2.0)
activerecord (7.2.0)
activemodel (= 7.2.0)
activesupport (= 7.2.0)
activemodel (7.2.1)
activesupport (= 7.2.1)
activerecord (7.2.1)
activemodel (= 7.2.1)
activesupport (= 7.2.1)
timeout (>= 0.4.0)
activestorage (7.2.0)
actionpack (= 7.2.0)
activejob (= 7.2.0)
activerecord (= 7.2.0)
activesupport (= 7.2.0)
activestorage (7.2.1)
actionpack (= 7.2.1)
activejob (= 7.2.1)
activerecord (= 7.2.1)
activesupport (= 7.2.1)
marcel (~> 1.0)
activesupport (7.2.0)
activesupport (7.2.1)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
@ -111,7 +111,7 @@ GEM
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
logger (1.6.0)
logger (1.6.1)
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
@ -124,7 +124,7 @@ GEM
mini_mime (1.1.5)
minitest (5.25.1)
msgpack (1.7.2)
net-imap (0.4.14)
net-imap (0.4.16)
date
net-protocol
net-pop (0.1.2)
@ -146,13 +146,13 @@ GEM
racc (~> 1.4)
nokogiri (1.16.7-x86_64-linux)
racc (~> 1.4)
pagy (9.0.5)
pagy (9.0.8)
parallel (1.26.3)
parser (3.3.4.2)
parser (3.3.5.0)
ast (~> 2.4.1)
racc
pg (1.5.7)
prism (0.30.0)
prism (1.0.0)
psych (5.1.2)
stringio
puma (6.4.2)
@ -166,20 +166,20 @@ GEM
rackup (2.1.0)
rack (>= 3)
webrick (~> 1.8)
rails (7.2.0)
actioncable (= 7.2.0)
actionmailbox (= 7.2.0)
actionmailer (= 7.2.0)
actionpack (= 7.2.0)
actiontext (= 7.2.0)
actionview (= 7.2.0)
activejob (= 7.2.0)
activemodel (= 7.2.0)
activerecord (= 7.2.0)
activestorage (= 7.2.0)
activesupport (= 7.2.0)
rails (7.2.1)
actioncable (= 7.2.1)
actionmailbox (= 7.2.1)
actionmailer (= 7.2.1)
actionpack (= 7.2.1)
actiontext (= 7.2.1)
actionview (= 7.2.1)
activejob (= 7.2.1)
activemodel (= 7.2.1)
activerecord (= 7.2.1)
activestorage (= 7.2.1)
activesupport (= 7.2.1)
bundler (>= 1.15.0)
railties (= 7.2.0)
railties (= 7.2.1)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
@ -196,9 +196,9 @@ GEM
rack
railties (>= 5.1)
semantic_logger (~> 4.16)
railties (7.2.0)
actionpack (= 7.2.0)
activesupport (= 7.2.0)
railties (7.2.1)
actionpack (= 7.2.1)
activesupport (= 7.2.1)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
@ -213,27 +213,24 @@ GEM
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
rbs (3.5.2)
rbs (3.5.3)
logger
rdoc (6.7.0)
psych (>= 4.0.0)
regexp_parser (2.9.2)
reline (0.5.9)
io-console (~> 0.5)
rexml (3.3.5)
strscan
rubocop (1.65.1)
rubocop (1.66.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.4, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-ast (>= 1.32.2, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.32.1)
rubocop-ast (1.32.2)
parser (>= 3.3.1.0)
rubocop-packaging (0.5.2)
rubocop (>= 1.33, < 2.0)
@ -246,9 +243,9 @@ GEM
rubocop (~> 1.51)
rubocop-thread_safety (0.5.1)
rubocop (>= 0.90.0)
ruby-lsp (0.17.14)
ruby-lsp (0.17.17)
language_server-protocol (~> 3.17.0)
prism (>= 0.29.0, < 0.31)
prism (~> 1.0)
rbs (>= 3, < 4)
sorbet-runtime (>= 0.5.10782)
ruby-lsp-rails (0.3.13)
@ -257,7 +254,7 @@ GEM
securerandom (0.3.1)
semantic_logger (4.16.0)
concurrent-ruby (~> 1.0)
sorbet-runtime (0.5.11531)
sorbet-runtime (0.5.11554)
sprockets (4.2.1)
concurrent-ruby (~> 1.0)
rack (>= 2.2.4, < 4)
@ -268,7 +265,6 @@ GEM
stimulus-rails (1.3.4)
railties (>= 6.0.0)
stringio (3.1.1)
strscan (3.1.0)
syslog_protocol (0.9.2)
tailwindcss-rails (2.7.3)
railties (>= 7.0.0)
@ -282,7 +278,7 @@ GEM
railties (>= 7.0.0)
tailwindcss-rails (2.7.3-x86_64-linux)
railties (>= 7.0.0)
thor (1.3.1)
thor (1.3.2)
timeout (0.4.1)
turbo-rails (2.0.6)
actionpack (>= 6.0.0)
@ -296,7 +292,7 @@ GEM
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
zeitwerk (2.6.17)
zeitwerk (2.6.18)
PLATFORMS
aarch64-linux

3
app/helpers/pagy_helper.rb

@ -28,7 +28,8 @@ module PagyHelper
url = url_for(params:)
url += url.include?('?') ? '&' : '?'
url += "q[#{attribute}]="
args.last.merge!({ onkeypress: "if (event.key === \"Enter\") {Turbo.visit('#{url}'+event.target.value)}" })
args.last.merge!({ onkeypress: "if (event.key === \"Enter\") {event.preventDefault(); Turbo.visit('#{url}'+event.target.value, { frame: 'scores', turbo: true, acceptsStreamResponse: true })}" })
# args.last.merge!({ onkeypress: 'if (event.key === "Enter") {event.preventDefault()}' })
search_field_tag("q[#{attribute}]", value, *args)
end

23
app/javascript/controllers/hot_search_controller.js

@ -0,0 +1,23 @@
import { Controller } from "@hotwired/stimulus";
// Connects to data-controller="hot-search"
export default class extends Controller {
connect() {
this.debouncedSearch = debounce(this.debouncedSearch.bind(this), 400)
}
debouncedSearch() {
Turbo.visit('/scores?q[name_cont]=' + this.element.value, { frame: 'scores', turbo: true, acceptsStreamResponse: true })
}
}
function debounce(callback, delay) {
let timeoutId;
return (...args) => {
if (timeoutId) { clearTimeout(timeoutId) }
timeoutId = setTimeout(() => {
callback(...args)
timeoutId = null
}, delay)
}
}

3
app/models/application_record.rb

@ -1,4 +1,7 @@
# abstract default ActiveRecord class
class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
# returns a pretty name like: "MyModel#1"
def to_s = "#{self.class.name}##{id}"
end

13
app/views/scores/_scores.html.erb

@ -1,13 +1,17 @@
<%= turbo_frame_tag :scores do %>
INPUT:
<input data-controller="hot-search" type='text' data-action='input->hot-search#debouncedSearch'/>
<%= search_form_for @q do |f| %>
<hr/>
<%= pagy_search_field(@q, :name_cont, class: "text-sm w-full h-8 text-gray-800 dark:text-gray-400 bg-gray-200 dark:bg-gray-700") %>
<%= search_form_for @q do |f| %>
<%= f.label :name_cont %>
<%= f.search_field :name_cont %>
<%= f.submit %>
<% end %>
<% end %>
<%=turbo_frame_tag :scores do %>
<table class="min-w-full divide-gray-300 dark:divide-gray-500 divide-y-4 border-gray-200 dark:border-gray-600 border-2 dark:bg-gray-600">
<thead>
<tr class="whitespace-nowrap text-md text-left font-semibold text-gray-800 dark:text-gray-200 bg-gray-100 dark:bg-gray-700">
@ -27,6 +31,7 @@
<tr class="text-gray-800 bg-gray-100 dark:bg-gray-600 dark:text-gray-200">
<th class='p-1'>
<%= pagy_search_field(@q, :name_cont, class: "text-sm w-full h-8 text-gray-800 dark:text-gray-400 bg-gray-200 dark:bg-gray-700") %>
<input data-controller="hot-search" type='text' data-action='keypress->hot-search#debouncedSearch'/>
</th>
<th class='p-1'>
</th>

4
config/environments/production.rb

@ -93,4 +93,8 @@ Rails.application.configure do
# ]
# Skip DNS rebinding protection for the default health check endpoint.
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
#
config.after_initialize do
config.semantic_logger.add_appender(appender: :syslog, formatter: Semantic::BasicFormatter.new)
end
end

6
config/environments/test.rb

@ -1,4 +1,4 @@
require "active_support/core_ext/integer/time"
require 'active_support/core_ext/integer/time'
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
@ -15,12 +15,12 @@ Rails.application.configure do
# this is usually not necessary, and can slow down your test suite. However, it's
# recommended that you enable it in continuous integration systems to ensure eager
# loading is working properly before deploying your code.
config.eager_load = ENV["CI"].present?
config.eager_load = ENV['CI'].present?
# Configure public file server for tests with Cache-Control for performance.
config.public_file_server.enabled = true
config.public_file_server.headers = {
"Cache-Control" => "public, max-age=#{1.hour.to_i}"
'Cache-Control' => "public, max-age=#{1.hour.to_i}"
}
# Show full error reports and disable caching.

2
config/initializers/backtrace_cleaning.rb

@ -1,2 +1,2 @@
bc = Rails.backtrace_cleaner
bc.add_silencer { |line| %r{^lib/(monkey_patches|formatters)}.match?(line) }
bc.add_silencer { |line| %r{^lib/(monkey_patches|semantic)}.match?(line) }

2
config/initializers/hot_changes.rb

@ -1,4 +1,4 @@
return unless defined?(Rails::Server)
return unless Rails.application.server?
Rails.application.config.after_initialize do
Hot::Constants.on_change(:log_active_record) { |bool| ActiveRecord::Base.logger.level = bool ? :debug : :fatal }

5
config/initializers/rails_live_reload.rb

@ -1,6 +1,6 @@
if defined?(RailsLiveReload) && Rails.env.development?
return unless defined?(RailsLiveReload) && Rails.env.development?
RailsLiveReload.configure do |config|
RailsLiveReload.configure do |config|
# HOT Constants
config.watch(%r{/\.env$}, reload: :always)
config.watch(%r{/\.env\.sample$})
@ -14,5 +14,4 @@ if defined?(RailsLiveReload) && Rails.env.development?
# Default watched folders & files
config.watch %r{app/views/.+\.(erb|haml|slim)$}
end
end

14
db/schema.rb

@ -10,14 +10,14 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.1].define(version: 20_240_104_070_011) do
ActiveRecord::Schema[7.2].define(version: 2024_01_04_070011) do
# These are extensions that must be enabled in order to support this database
enable_extension 'plpgsql'
enable_extension "plpgsql"
create_table 'scores', force: :cascade do |t|
t.string 'name'
t.integer 'grade'
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
create_table "scores", force: :cascade do |t|
t.string "name"
t.integer "grade"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end

20
lib/semantic/ansi_formatter.rb

@ -1,7 +1,3 @@
require_relative 'ansi_wrapper'
require_relative 'ansi_colors'
require_relative 'ansi_dimensions'
require 'io/console'
require 'amazing_print'
require 'json'
@ -85,7 +81,7 @@ module Semantic
rails = "#{@memory}"
before = 0
end
log.dimensions = AnsiDimensions.new(rails:, before:)
log.dimensions = Semantic::AnsiDimensions.new(rails:, before:)
@memory = nil
log.message = two_captures_last_as_bold(log.message, /(^Started \w* )"(.*?)"/)
elsif log.message.starts_with?('Parameters')
@ -105,14 +101,14 @@ module Semantic
duration = duration > TOTAL_RENDERED_VIEW_DURATION ? " in #{m3}ms #{m4}" : ''
log.message = "Completed #{BOLD}#{http_code}#{CLEAR} #{m2}#{duration}"
if http_code / 100 == 2
log.dimensions = AnsiDimensions.new(rails: TERMINUS_STRING, after: 1)
log.dimensions = Semantic::AnsiDimensions.new(rails: TERMINUS_STRING, after: 1)
elsif http_code / 100 == 3
@memory = '║'
log.dimensions = AnsiDimensions.new(rails: "#{@memory}")
log.dimensions = Semantic::AnsiDimensions.new(rails: "#{@memory}")
elsif http_code / 100 == 4
log.dimensions = AnsiDimensions.new(rails: '╙╨╜')
log.dimensions = Semantic::AnsiDimensions.new(rails: '╙╨╜')
elsif http_code / 100 == 5
log.dimensions = AnsiDimensions.new(rails: "#{draw_fatal}")
log.dimensions = Semantic::AnsiDimensions.new(rails: "#{draw_fatal}")
end
elsif log.message =~ /^(Processing|Parameters)/
log.level = :debug
@ -125,7 +121,7 @@ module Semantic
log.message = two_captures_last_as_bold(log.message, @regex_redirected)
end
elsif log.exception
log.dimensions = AnsiDimensions.new(
log.dimensions = Semantic::AnsiDimensions.new(
rails: "#{draw_fatal(log.level.to_s.chr.upcase)}",
after: 1,
terminus: true
@ -231,11 +227,11 @@ module Semantic
continuation = build_prefix('┆')
result = items.map do |item|
AnsiWrapper.wrap(item, length, prefix, continuation)
Semantic::AnsiWrapper.wrap(item, length, prefix, continuation)
end
if log.dimensions&.terminus
terminus = AnsiWrapper.wrap(' ', length, build_terminus)
terminus = Semantic::AnsiWrapper.wrap(' ', length, build_terminus)
result << terminus
end

Loading…
Cancel
Save