Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update build, relax rails dep
Browse files Browse the repository at this point in the history
jaynetics committed Nov 12, 2024
1 parent a6b88b4 commit 32f8d1a
Showing 15 changed files with 72 additions and 40 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ jobs:

strategy:
matrix:
ruby: [ '3.0', 'ruby-head' ]
ruby: [ '3.2', '3.3' ]

steps:
- uses: actions/checkout@v3
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## Unreleased

### Fixed

- relaxed rails version requirement
- fixed handling of proc-based labels of activeadmin items
- fixed repeated DOM ids when using multiple omnibars on the same page
- fixed some items generated from active admin resources being mislabeled

## [1.8.0] - 2024-07-06

### Added
7 changes: 4 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -4,15 +4,16 @@ source 'https://rubygems.org'
gemspec

group :development, :test do
gem 'activeadmin', '~> 3.0' # to test activeadmin integration
gem 'activeadmin', '~> 4.0.0.beta13' # to test activeadmin integration
gem 'importmap-rails' # needed for activeadmin
gem 'capybara', '~> 3.0'
gem 'csv' # needed for activeadmin, standalone on Ruby >= 3.4
gem 'debug'
gem 'devise', '~> 4.8' # to test auth feature
gem 'factory_bot_rails', '~> 6.0'
gem 'puma', '~> 6.0'
gem 'rake', '~> 13.2'
gem 'rspec-rails', '~> 6.0'
gem 'selenium-webdriver', '~> 4.22'
gem 'sprockets-rails', '~> 3.4' # for activeadmin
gem 'sqlite3', '~> 1.4'
gem 'sqlite3', '~> 2.1'
end
4 changes: 3 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ task default: [:compile_js, :generate_spec_app, :spec]

desc 'Compile the JavaScript'
task :compile_js do
sh 'npm run compile'
sh 'npm run build'
end

desc 'Generate a dummy rails app for testing'
@@ -24,6 +24,7 @@ task :generate_spec_app do
--skip-action-text
--skip-active-job
--skip-active-storage
--skip-asset-pipeline
--skip-bootsnap
--skip-bundle
--skip-git
@@ -54,6 +55,7 @@ task :dev_js do
npm --prefix ../omnibar2 run build &&
rm -rf node_modules/omnibar2 &&
cp -r ../omnibar2 ./node_modules &&
rm -rf ./node_modules/omnibar2/node_modules &&
rake compile_js
SH
end
2 changes: 1 addition & 1 deletion bin/setup
Original file line number Diff line number Diff line change
@@ -5,4 +5,4 @@ set -vx

bundle install
npm install
npm run compile
npm run build
42 changes: 30 additions & 12 deletions javascript/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import React, {FunctionComponent, render} from "preact"
import habitat from "preact-habitat"
import Omnibar, {buildItemStyle} from "omnibar2"
import {Globals} from "csstype"
import {useDelayedLoadingStyle, useItemAction, useOmnibarExtensions} from "./hooks"
import {
useDelayedLoadingStyle,
useItemAction,
useOmnibarExtensions,
} from "./hooks"
import {useHotkey, useModal, useToggleFocus} from "./hooks"
import {AppArgs, INPUT_DATA_ID, Item, ModalArg} from "./types"
import {iconClass} from "./icon"

document.addEventListener("DOMContentLoaded", () => {
habitat(App).render({selector: "#mount-rails-omnibar"})
})
const mount = () =>
document.querySelectorAll(".mount-rails-omnibar").forEach((node) => {
const propScript = node.querySelector("script[type='application/json']")
if (!propScript) return

document.addEventListener("turbo:load", () => {
habitat(App).render({selector: "#mount-rails-omnibar"})
})
const props = JSON.parse(propScript.innerHTML) as AppArgs
propScript.remove()
render(<App {...props} />, node)
})

document.addEventListener("DOMContentLoaded", mount)

document.addEventListener("turbo:load", mount)

const App: FunctionComponent<AppArgs> = (args) => {
const itemModal = useModal()
@@ -27,7 +36,7 @@ const App: FunctionComponent<AppArgs> = (args) => {
const RailsOmnibar: FunctionComponent<AppArgs & ModalArg> = (args) => {
const extensions = useOmnibarExtensions(args)
const itemAction = useItemAction(args.itemModal)
const loadingStyle = useDelayedLoadingStyle();
const loadingStyle = useDelayedLoadingStyle()

return (
<>
@@ -41,7 +50,10 @@ const RailsOmnibar: FunctionComponent<AppArgs & ModalArg> = (args) => {
placeholder={args.placeholder}
children={(props) => renderItem({...props, modal: args.modal})}
showEmpty
style={{...(args.modal ? MODAL_ROW_STYLE : ROW_STYLE), ...loadingStyle.style}}
style={{
...(args.modal ? MODAL_ROW_STYLE : ROW_STYLE),
...loadingStyle.style,
}}
/>
{args.itemModal.modal}
</>
@@ -59,12 +71,18 @@ const renderItem = (
props: Omnibar.ResultRendererArgs<Item> & {modal: boolean}
) => {
const {item, onMouseEnter, onMouseLeave, onClick} = props
const handlers = {onMouseEnter, onMouseLeave, onClick} as Record<string, (e: any) => void>
const handlers = {onMouseEnter, onMouseLeave, onClick} as Record<
string,
(e: any) => void
>
const style = buildItemStyle<Item>(props) as React.JSX.CSSProperties
const Icon = iconClass(item.icon)

return (
<div {...handlers} style={{...style, ...(props.modal ? MODAL_ROW_STYLE : ROW_STYLE)}}>
<div
{...handlers}
style={{...style, ...(props.modal ? MODAL_ROW_STYLE : ROW_STYLE)}}
>
{Icon && <Icon name={item.icon} style={ICON_STYLE} />}
{item.title}
</div>
16 changes: 11 additions & 5 deletions javascript/src/hooks/use_delayed_loading_style.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import {useState} from "preact/hooks"
import {useEffect, useRef, useState} from "preact/hooks"

export const useDelayedLoadingStyle = () => {
const [enabled, setEnabled] = useState(false)
const [timer, setTimer] = useState<ReturnType<typeof setTimeout> | null>(null)
const timer = useRef<ReturnType<typeof setTimeout> | null>(null)
const clear = () => {
timer.current && clearTimeout(timer.current)
timer.current = null
}

const startTimer = () => {
if (timer) clearTimeout(timer)
setTimer(setTimeout(() => setEnabled(true), 100))
clear()
timer.current = setTimeout(() => setEnabled(true), 100)
}

const stop = () => {
if (timer) clearTimeout(timer)
clear()
setEnabled(false)
}

useEffect(() => () => { clear() }, [])

return { style : enabled ? LOADING_STYLE : {}, startTimer, stop }
}

1 change: 1 addition & 0 deletions lib/rails_omnibar/item/webadmin.rb
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ def add_active_admin_items(icon: default_admin_item_icon, prefix: nil, suffix: n
next unless (res.controller.action_methods & ['index', :index]).any?
next unless index = res.route_collection_path rescue next
next unless label = res.menu_item&.label.presence
label = label.call if label.respond_to?(:call)

title = [prefix, label, suffix].compact.join(' ')
add_item(title: title, url: index, icon: icon, suggested: suggested)
2 changes: 1 addition & 1 deletion lib/rails_omnibar/rendering.rb
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ def render(context = nil)
@context = context
<<~HTML.html_safe
<script src='#{urls.js_path}?v=#{RailsOmnibar::VERSION}' type='text/javascript'></script>
<div id='mount-rails-omnibar'>
<div class='mount-rails-omnibar'>
<script type="application/json">#{to_json}</script>
</div>
HTML
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
{
"scripts": {
"compile": "npx webpack",
"build": "npx webpack",
"test": "bundle exec rake"
},
"dependencies": {
"@heroicons/react": "^2.0.14",
"fuzzysort": "^2.0.4",
"omnibar2": "^2.5.0",
"preact": "^10.11.3",
"preact-habitat": "^3.3.0",
"react-modal": "^3.16.1",
"yaam": "^1.1.1"
},
2 changes: 1 addition & 1 deletion rails_omnibar.gemspec
Original file line number Diff line number Diff line change
@@ -19,5 +19,5 @@ Gem::Specification.new do |spec|
spec.required_ruby_version = '>= 2.7'

spec.add_dependency 'js_regex'
spec.add_dependency 'rails', ['>= 6.0', '< 8.0']
spec.add_dependency 'rails', ['>= 6.0']
end
15 changes: 6 additions & 9 deletions spec/system/rails_omnibar_spec.rb
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
expect(User.pluck(:id).sort).to eq [1, 2] # sanity check

visit main_app.root_path
expect(page).to have_selector '#mount-rails-omnibar' # sanity check
expect(page).to have_selector '.mount-rails-omnibar' # sanity check

# test visibility toggling with hotkey
expect(page).not_to have_selector 'input'
@@ -32,6 +32,7 @@
expect(page).to have_content 'important URL'
expect(page).to have_content 'boring URL'

sleep 0.1
type('ori')
expect(page).not_to have_content 'important URL'
expect(page).to have_content 'boring URL'
@@ -85,23 +86,19 @@
auth = ->(controller) { controller.user_signed_in? || true }
MyOmnibar.auth = auth
expect(auth).to receive(:call).at_least(:once).and_call_original
sleep 0.1 # not sure why this is needed ...
type('')
expect(page).not_to have_content '2'
type('count users')
sleep 0.1
expect(page).to have_content '2'

# test activeadmin integration
# stub sprockets so we don't need sassc etc.
allow_any_instance_of(Sprockets::Rails::Helper)
.to receive(:compute_asset_path)
.and_return('')

submit('Admin: Useroos')
expect(page).to have_current_path('/admin/users')
end

it 'can have more than one omnibar' do
visit main_app.root_path
expect(page).to have_selector '#mount-rails-omnibar' # sanity check
expect(page).to have_selector '.mount-rails-omnibar' # sanity check

expect(page).not_to have_selector 'input'
send_keys([:meta, 'a']) # custom hotkey, c.f. other_omnibar_template.rb
2 changes: 1 addition & 1 deletion spec/templates/app_template.rb
Original file line number Diff line number Diff line change
@@ -4,11 +4,11 @@
gem 'csv'
gem 'devise'
gem 'activeadmin'
gem 'activeadmin_assets'

insert_into_file 'config/application.rb', <<~RUBY, after: /action_mailer.*\n/
require 'action_mailer/railtie' # needed to make devise work
require 'devise'
require 'sprockets/railtie' # needed to make activeadmin work
RUBY

# https://github.com/activeadmin/activeadmin/pull/7235#issuecomment-1000823435
2 changes: 1 addition & 1 deletion spec/templates/my_omnibar_template.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
MyOmnibar = RailsOmnibar.configure do |c|
MyOmnibar = Class.new(RailsOmnibar).configure do |c|
c.modal = true

c.add_item(title: 'important URL', url: 'https://www.disney.com', suggested: true)
3 changes: 1 addition & 2 deletions spec/templates/other_omnibar_template.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
OtherOmnibar = Class.new(RailsOmnibar)
OtherOmnibar.configure do |c|
OtherOmnibar = Class.new(RailsOmnibar).configure do |c|
c.modal = true

c.add_item(title: 'disney', url: 'https://www.disney.com', suggested: true)

0 comments on commit 32f8d1a

Please sign in to comment.