From 2590057dbd71face61b1b0640256800c3599a704 Mon Sep 17 00:00:00 2001 From: "Brenton \"B-Train\" Fletcher" Date: Fri, 12 Jun 2015 23:17:35 +1000 Subject: [PATCH] Add Bootstrap 2 framework; ReAdd simple_form and convert search form to use it; Refactor Items search into query object; Fix Book#page_urls URL generation; Add preferences model and UI --- Gemfile | 5 +- Gemfile.lock | 24 ++-- app/assets/javascripts/application.js | 1 + app/assets/javascripts/index.js | 6 +- app/assets/stylesheets/application.css | 8 -- app/assets/stylesheets/application.scss | 10 ++ app/assets/stylesheets/index.scss | 103 ++++++++++++++ app/assets/stylesheets/style.css | 71 +--------- app/controllers/items_controller.rb | 58 +------- app/controllers/preferences_controller.rb | 37 +++++ app/helpers/items_helper.rb | 2 +- app/models/book.rb | 2 +- app/models/preference.rb | 10 ++ app/services/items_query.rb | 73 ++++++++++ app/views/items/_search_form.html.haml | 13 ++ app/views/items/index.html.haml | 6 +- app/views/preferences/_form.html.haml | 5 + app/views/preferences/edit.html.haml | 4 + app/views/preferences/index.html.haml | 26 ++++ app/views/preferences/new.html.haml | 4 + config/initializers/formtastic.rb | 54 ------- config/initializers/simple_form.rb | 142 +++++++++++++++++++ config/initializers/simple_form_bootstrap.rb | 45 ++++++ config/locales/simple_form.en.yml | 26 ++++ config/routes.rb | 2 + db/migrate/20150612083701_add_preferences.rb | 13 ++ db/schema.rb | 9 +- 27 files changed, 551 insertions(+), 208 deletions(-) delete mode 100644 app/assets/stylesheets/application.css create mode 100644 app/assets/stylesheets/application.scss create mode 100644 app/assets/stylesheets/index.scss create mode 100644 app/controllers/preferences_controller.rb create mode 100644 app/models/preference.rb create mode 100644 app/services/items_query.rb create mode 100644 app/views/items/_search_form.html.haml create mode 100644 app/views/preferences/_form.html.haml create mode 100644 app/views/preferences/edit.html.haml create mode 100644 app/views/preferences/index.html.haml create mode 100644 app/views/preferences/new.html.haml delete mode 100644 config/initializers/formtastic.rb create mode 100644 config/initializers/simple_form.rb create mode 100644 config/initializers/simple_form_bootstrap.rb create mode 100644 config/locales/simple_form.en.yml create mode 100644 db/migrate/20150612083701_add_preferences.rb diff --git a/Gemfile b/Gemfile index 35b1d11..a1c1ae5 100644 --- a/Gemfile +++ b/Gemfile @@ -15,18 +15,19 @@ gem 'acts-as-taggable-on', '2.3.3' gem 'carrierwave', '0.10.0' gem 'rubyzip', '0.9.4' gem 'sendfile', '1.2.2' -gem 'formtastic', :git => 'git://github.com/justinfrench/formtastic.git', :ref => '038357cae3fbe4ce9d64' gem 'naturally', '>= 1.0.3', '<= 1.3.1' gem 'haml' +gem 'simple_form' gem 'test-unit', '~> 3.0' group :assets do - #gem 'sass-rails', "~> 3.1.0" #gem 'coffee-rails', "~> 3.1.0" gem 'uglifier' gem 'jquery-rails' gem 'turbo-sprockets-rails3' + gem 'bootstrap-sass', '2.3.2' + gem 'sass-rails' end group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index c9d4165..20eafd1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,13 +1,3 @@ -GIT - remote: git://github.com/justinfrench/formtastic.git - revision: 038357cae3fbe4ce9d648249a4c6d0b1f520a1f4 - ref: 038357cae3fbe4ce9d64 - specs: - formtastic (1.0.0.beta) - actionpack (>= 2.3.0) - activesupport (>= 2.3.0) - i18n (>= 0.4.0) - GIT remote: git://github.com/rails/rails.git revision: b344986bc3d94ca7821fc5e0eef1874882ac6cbb @@ -62,6 +52,8 @@ GEM acts-as-taggable-on (2.3.3) rails (~> 3.0) arel (3.0.3) + bootstrap-sass (2.3.2.0) + sass (~> 3.2) builder (3.0.4) byebug (5.0.0) columnize (= 0.9.0) @@ -134,6 +126,11 @@ GEM rspec-support (~> 3.2.0) rspec-support (3.2.2) rubyzip (0.9.4) + sass (3.4.14) + sass-rails (3.2.6) + railties (~> 3.2.0) + sass (>= 3.1.10) + tilt (~> 1.3) sendfile (1.2.2) sidekiq (3.3.4) celluloid (>= 0.16.0) @@ -143,6 +140,9 @@ GEM redis-namespace (>= 1.3.1) sidekiq-failures (0.4.4) sidekiq (>= 2.16.0) + simple_form (2.1.2) + actionpack (~> 3.0) + activemodel (~> 3.0) sinatra (1.4.6) rack (~> 1.4) rack-protection (~> 1.4) @@ -175,10 +175,10 @@ PLATFORMS DEPENDENCIES acts-as-taggable-on (= 2.3.3) + bootstrap-sass (= 2.3.2) byebug carrierwave (= 0.10.0) foreman - formtastic! haml jquery-rails naturally (>= 1.0.3, <= 1.3.1) @@ -189,9 +189,11 @@ DEPENDENCIES rmagick (= 2.15.0) rspec-rails (~> 3.0) rubyzip (= 0.9.4) + sass-rails sendfile (= 1.2.2) sidekiq sidekiq-failures + simple_form sinatra test-unit (~> 3.0) turbo-sprockets-rails3 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 6e5cb28..cf5ca7f 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,5 +1,6 @@ //= require jquery //= require jquery_ujs +//= require bootstrap //= require utils //= require lib/URI.js //= require lib/featherlight.min.js diff --git a/app/assets/javascripts/index.js b/app/assets/javascripts/index.js index 272fa46..2977e20 100755 --- a/app/assets/javascripts/index.js +++ b/app/assets/javascripts/index.js @@ -17,11 +17,7 @@ $(update_items); $(function() { - $(".selector li a").click(function(event) { - event.preventDefault(); - }); - $(".selector li").click(function(event) { - $("#" + $(this).parent().data("name")).val($(this).data("value")); + $("#search_form select").change(function(event) { $('#search_form').submit(); }); diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css deleted file mode 100644 index 503afcc..0000000 --- a/app/assets/stylesheets/application.css +++ /dev/null @@ -1,8 +0,0 @@ -/* -*= require style.css -*= require lib/featherlight.min.css -*= require formtastic.css -*= require formtastic_changes.css -*= require show.css -*= require thumbnail_sizes.css -*/ \ No newline at end of file diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss new file mode 100644 index 0000000..6e99da2 --- /dev/null +++ b/app/assets/stylesheets/application.scss @@ -0,0 +1,10 @@ +$baseFontSize: 16px; +$baseLineHeight: 22px; +$textColor: #000000; + +@import "bootstrap"; +@import "style"; +@import "lib/featherlight.min"; +@import "index"; +@import "show"; +@import "thumbnail_sizes"; \ No newline at end of file diff --git a/app/assets/stylesheets/index.scss b/app/assets/stylesheets/index.scss new file mode 100644 index 0000000..d212cc1 --- /dev/null +++ b/app/assets/stylesheets/index.scss @@ -0,0 +1,103 @@ +#items-index { + ul { margin: 0; } + + #header { padding: 10px; } + #search_form { + margin-bottom: 0; + } + #actions { float: right; } + + #wrapper { position: relative; background-color: #000000; } + + #tag_cloud, #header { background-color: #ffffff; } + #tag_cloud { position: absolute; top: 0; right: 0; z-index: 1000; width: 500px; background-color: #ffffff; padding: 15px; } + #tag_cloud .size_1 { font-size: 1.0em; } + #tag_cloud .size_2 { font-size: 1.2em; } + #tag_cloud .size_3 { font-size: 1.4em; } + #tag_cloud .size_4 { font-size: 1.6em; } + + .title { } + #items { + padding: 2px 0 0 2px; + + li { + margin: 0 2px 2px 0; + float: left; + list-style-type: none; + position: relative; + overflow: hidden; + + .emblems, .actions { + display: block; + position: absolute; + top: 0; + right: 0; + padding: 1px; + line-height: 0; + background-color: #ffffff; + } + + .actions { + display: none; + right: auto; + left: 0; + width: 32px; + } + + .wrapper { + position: relative; + } + + .info-wrapper { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background-color: #ffffff; + } + + .info { + padding: 2px; + img { + vertical-align: middle; + } + } + + &.no_results { + color: #ffffff; + width: auto; + float: none; + text-align: center; + padding: 40px 0; + } + + &:hover { + .actions { + display: block; + } + } + } + + .tag_list { + min-height: 1.2em; + + &:hover { + background-color: #ffffaa; + } + } + + input { + width: 100%; + } + + .title_image { + float: left; + margin-right: 15px; + } + + #info { + float: left; + width: 315px; + } + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/style.css b/app/assets/stylesheets/style.css index a8d5e27..94728f1 100644 --- a/app/assets/stylesheets/style.css +++ b/app/assets/stylesheets/style.css @@ -1,73 +1,14 @@ -* { margin: 0; padding: 0; font: 16px/1.3em 'Open Sans', Helvetica, Arial, sans-serif; } -body { color: #000000; padding: 2px; } +* { font-family: 'Open Sans', Helvetica, Arial, sans-serif; } +body { color: #000000; } img { border: none; vertical-align: middle; } -li { margin-left: 30px; } p, ul { margin-bottom: 1.3em; } .clear { clear: both; } -#header { padding: 10px; } -#search { width: 300px; border: 1px solid #a0a0a0; } -#actions { float: right; } - -input[type="text"], select { padding: 1px; } -.selector { display: inline; margin-right: 20px; } -.selector li { display: inline; margin-left: 0; margin-right: 5px; } -.selector li:last-child { margin-right: 0; } -.selector li.selected a { font-weight: bold; text-decoration: none; color: #000000; } - -#wrapper { position: relative; background-color: #000000; } - -#tag_cloud, #header { background-color: #ffffff; } -#tag_cloud { position: absolute; top: 0; right: 0; z-index: 1000; width: 500px; background-color: #ffffff; padding: 15px; } -#tag_cloud .size_1 { font-size: 1.0em; } -#tag_cloud .size_2 { font-size: 1.2em; } -#tag_cloud .size_3 { font-size: 1.4em; } -#tag_cloud .size_4 { font-size: 1.6em; } - -.title { } -#items { padding: 2px 0 0 2px; } -#items li { margin: 0 2px 2px 0; float: left; list-style-type: none; position: relative; overflow: hidden; } -#items li .emblems, #items li .actions { display: block; position: absolute; top: 0; right: 0; padding: 1px; line-height: 0; background-color: #ffffff; } -#items li .actions { display: none; right: auto; left: 0; width: 32px; } -#items li .wrapper { position: relative; } -#items li .info-wrapper { - position: absolute; - bottom: 0; - left: 0; - right: 0; - background-color: #ffffff; -} -#items li .info { padding: 2px; } -#items li .info img { vertical-align: middle; } -#items .tag_list { min-height: 1.2em; } -#items .tag_list:hover { background-color: #ffffaa; } -#items input { width: 100%; } - -#items li.no_results { color: #ffffff; width: auto; float: none; text-align: center; padding: 40px 0; } -/*#items .tags form { display: none; }*/ - -#items li:hover .actions { display: block; } - -#item .title_image { float: left; margin-right: 15px; } -#item #info { float: left; width: 315px; } - -/* -#items-index body { - background-image: -webkit-gradient( - linear, - left top, - right bottom, - color-stop(0.39, rgb(0,0,0)), - color-stop(0.73, rgb(46,46,46)) -); - background-image: -moz-linear-gradient( - left top, - rgb(0,0,0) 39%, - rgb(46,46,46) 73% -); -}*/ - @media screen and (max-width: 844px) { .desktop-only { display: none; } } + +.table { + width: auto; +} \ No newline at end of file diff --git a/app/controllers/items_controller.rb b/app/controllers/items_controller.rb index d7af1d8..b22df36 100644 --- a/app/controllers/items_controller.rb +++ b/app/controllers/items_controller.rb @@ -2,16 +2,15 @@ raise "Wrong ActsAsTaggableOn version!" unless ActsAsTaggableOn::VERSION == "2.3.3" #Needed to ensure our joins_values hack doesn't fail silently in new versions of AATO class ItemsController < ApplicationController - SORT_OPTIONS = [['Published', 'published_on'], ['A-Z', 'sort_key'], ['Last opened at', 'last_opened_at'], ['Date added', 'created_at'], ['Pages', 'pages'], ['Popularity', 'opens']] - def index - @items = _search_results.order(params[:sort_direction] == "RAND" ? "RANDOM()" : "#{params[:sort]} #{params[:sort_direction]}").paginate(:page => params[:page], :per_page => 100) + @query = ItemsQuery.new(params[:query]) + @items = @query.results.paginate(page: params[:page], per_page: 100) @tags = Item.tag_counts_on(:tags).order("name ASC") end def bulk_export - _search_results.each { |i| i.export } + ItemsQuery.new(params[:query]).results.each { |i| i.export } end def more_info @@ -73,55 +72,4 @@ def quit def dynamic_stylesheet self.formats = [:css] end - - private - def _search_results - params[:sort] ||= 'published_on' - params[:sort_direction] ||= 'DESC' - if !params[:search].blank? - included_terms, excluded_terms = ActsAsTaggableOn::TagList.from(params[:search]).partition { |t| t.gsub!(/^-/, ''); $& != '-' } - included_tags = included_terms.empty? ? [] : ActsAsTaggableOn::Tag.named_any(included_terms) - excluded_tags = excluded_terms.empty? ? [] : ActsAsTaggableOn::Tag.named_any(excluded_terms) - - results = Item - - results = results.where("opens > 0") if included_terms.delete 's:read' - results = results.where("opens = 0") if excluded_terms.delete 's:read' - results = results.where("opens <= 3") if included_terms.delete 's:readish' - results = results.where("opens > 3") if excluded_terms.delete 's:readish' - results = results.where("opens = 0") if included_terms.delete 's:unread' - results = results.where("opens > 0") if excluded_terms.delete 's:unread' - results = results.where("page_count >= 150") if included_terms.delete 's:tank' - results = results.where("page_count < 150") if excluded_terms.delete 's:tank' - results = results.where("page_count >= 80") if included_terms.delete 's:long' - results = results.where("page_count < 80") if excluded_terms.delete 's:long' - results = results.where("page_count <= 30") if included_terms.delete 's:short' - results = results.where("page_count > 30") if excluded_terms.delete 's:short' - #results = results.where("COUNT(taggings.id) > 0") if included_tags.delete 's:tagged' - - unless excluded_terms.empty? - results = results.tagged_with(excluded_tags, :exclude => true) unless excluded_tags.empty? - results = results.where(excluded_terms.map { |t| "NOT items.title LIKE #{qt t}" }.join(" AND ")) - end - - unless included_terms.empty? - included_terms_sql = included_terms.map { |t| "items.title LIKE #{qt t}" }.join(" AND ") - if included_tags.empty? - results = results.where(included_terms_sql) - else - results = results.tagged_with(included_tags) - results.joins_values.first.insert(0, "LEFT ") - results = results.where("tag_id NOTNULL OR (#{included_terms_sql})") - end - end - - results - else - Item - end - end - - def qt(term) - Item.connection.quote("%#{term}%") - end end diff --git a/app/controllers/preferences_controller.rb b/app/controllers/preferences_controller.rb new file mode 100644 index 0000000..40c0d48 --- /dev/null +++ b/app/controllers/preferences_controller.rb @@ -0,0 +1,37 @@ +class PreferencesController < ApplicationController + def index + @preferences = Preference.all + end + + def new + @preference = Preference.new + end + + def create + @preference = Preference.new(params[:preference]) + if @preference.save + redirect_to action: :index + else + render action: :new + end + end + + def edit + @preference = Preference.find(params[:id]) + end + + def update + @preference = Preference.find(params[:id]) + if @preference.update_attributes!(params[:preference]) + redirect_to action: :index + else + render action: :edit + end + end + + def destroy + @preference = Preference.find(params[:id]) + @preference.destroy + redirect_to action: :index + end +end \ No newline at end of file diff --git a/app/helpers/items_helper.rb b/app/helpers/items_helper.rb index 71ae286..406c7b9 100755 --- a/app/helpers/items_helper.rb +++ b/app/helpers/items_helper.rb @@ -19,7 +19,7 @@ def item_title(item, show) end def selector(name, options) - out = %Q{