solidus_prototypes 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +26 -0
  3. data/README.md +39 -0
  4. data/Rakefile +30 -0
  5. data/app/assets/javascripts/spree/backend/select_prototype_ajax.js +11 -0
  6. data/app/assets/javascripts/spree/backend/solidus_prototypes.js +4 -0
  7. data/app/assets/javascripts/spree/frontend/solidus_prototypes.js +2 -0
  8. data/app/assets/stylesheets/spree/backend/solidus_prototypes.css +4 -0
  9. data/app/assets/stylesheets/spree/frontend/solidus_prototypes.css +4 -0
  10. data/app/concerns/solidus_prototypes/option_type_prototype_concern.rb +10 -0
  11. data/app/concerns/solidus_prototypes/permitted_attributes_concern.rb +15 -0
  12. data/app/concerns/solidus_prototypes/product_prototype_concern.rb +34 -0
  13. data/app/concerns/solidus_prototypes/products_loader_concern.rb +15 -0
  14. data/app/concerns/solidus_prototypes/property_prototype_concern.rb +10 -0
  15. data/app/concerns/solidus_prototypes/prototype_product_display_permission_concern.rb +8 -0
  16. data/app/concerns/solidus_prototypes/prototype_product_management_permission_concern.rb +8 -0
  17. data/app/concerns/solidus_prototypes/taxon_prototype_concern.rb +10 -0
  18. data/app/controllers/spree/admin/prototypes_controller.rb +26 -0
  19. data/app/models/spree/option_type_prototype.rb +6 -0
  20. data/app/models/spree/property_prototype.rb +6 -0
  21. data/app/models/spree/prototype.rb +14 -0
  22. data/app/models/spree/prototype_taxon.rb +6 -0
  23. data/app/overrides/decorate_admin_product_tabs.rb +7 -0
  24. data/app/overrides/decorate_admin_products_new.rb +15 -0
  25. data/app/overrides/decorate_product_properties_form.rb +7 -0
  26. data/app/overrides/decorate_product_properties_index.rb +7 -0
  27. data/app/views/spree/admin/prototypes/_form.html.erb +36 -0
  28. data/app/views/spree/admin/prototypes/_products_new.html.erb +6 -0
  29. data/app/views/spree/admin/prototypes/_products_new_clearfix.html.erb +3 -0
  30. data/app/views/spree/admin/prototypes/_prototypes.html.erb +25 -0
  31. data/app/views/spree/admin/prototypes/available.js.erb +2 -0
  32. data/app/views/spree/admin/prototypes/edit.html.erb +15 -0
  33. data/app/views/spree/admin/prototypes/index.html.erb +50 -0
  34. data/app/views/spree/admin/prototypes/new.html.erb +9 -0
  35. data/app/views/spree/admin/prototypes/new.js.erb +5 -0
  36. data/app/views/spree/admin/prototypes/select.js.erb +4 -0
  37. data/app/views/spree/admin/prototypes/show.html.erb +42 -0
  38. data/app/views/spree/shared/_prototypes_product_properties_toolbar.html.erb +5 -0
  39. data/app/views/spree/shared/_prototypes_products_sub_menu_tab.html.erb +3 -0
  40. data/config/locales/en.yml +21 -0
  41. data/config/routes.rb +14 -0
  42. data/db/migrate/20160929214715_create_prototypes.rb +34 -0
  43. data/lib/decorators/spree/admin/products_decorator.rb +1 -0
  44. data/lib/decorators/spree/option_type_decorator.rb +1 -0
  45. data/lib/decorators/spree/permission_sets_product_display_decorator.rb +1 -0
  46. data/lib/decorators/spree/permission_sets_product_management_decorator.rb +1 -0
  47. data/lib/decorators/spree/permitted_attributes_prototype_decorator.rb +1 -0
  48. data/lib/decorators/spree/products_decorator.rb +1 -0
  49. data/lib/decorators/spree/property_decorator.rb +1 -0
  50. data/lib/decorators/spree/taxon_decorator.rb +1 -0
  51. data/lib/generators/solidus_prototypes/install/install_generator.rb +30 -0
  52. data/lib/solidus_prototypes.rb +2 -0
  53. data/lib/solidus_prototypes/engine.rb +21 -0
  54. data/lib/solidus_prototypes/factories.rb +8 -0
  55. data/lib/solidus_prototypes/spree/permission_sets/prototype_product_display.rb +21 -0
  56. data/lib/solidus_prototypes/spree/permission_sets/prototype_product_management.rb +19 -0
  57. data/lib/solidus_prototypes/version.rb +3 -0
  58. metadata +273 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 27bd4972091c50809a66138bc3359737f7655608
4
+ data.tar.gz: e6462efcfca8de3a2e8faced03a39bfe94f079b8
5
+ SHA512:
6
+ metadata.gz: e773af5016181c26cc002b6b822faf445d7837a23d20b13e3e562eeae58328ca0b7df8158d5fe035bb4799d19d17caf82693d3518b1a37f062e641a1a1d4cfc2
7
+ data.tar.gz: 9ab9e8db2329d1332b5f44595c0e5cb5822dbc25319b41c11ce67ebb9760274a54622454295eab0c9b277c5583ae0372bd0fe2f1bfe8251a55dbc2720d792c7d
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2016 [name of plugin creator]
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,39 @@
1
+ SolidusPrototypes
2
+ ================
3
+
4
+ Prototype extension for Solidus.
5
+
6
+ Installation
7
+ ------------
8
+
9
+ Add solidus_prototypes to your Gemfile:
10
+
11
+ ```ruby
12
+ gem 'solidus_prototypes'
13
+ ```
14
+
15
+ Bundle your dependencies and run the installation generator:
16
+
17
+ ```shell
18
+ bundle
19
+ bundle exec rails g solidus_prototypes:install
20
+ ```
21
+
22
+ Testing
23
+ -------
24
+
25
+ First bundle your dependencies, then run `rake`. `rake` will default to building the dummy app if it does not exist, then it will run specs, and [Rubocop](https://github.com/bbatsov/rubocop) static code analysis. The dummy app can be regenerated by using `rake test_app`.
26
+
27
+ ```shell
28
+ bundle
29
+ bundle exec rake
30
+ ```
31
+
32
+ When testing your applications integration with this extension you may use it's factories.
33
+ Simply add this require statement to your spec_helper:
34
+
35
+ ```ruby
36
+ require 'solidus_prototypes/factories'
37
+ ```
38
+
39
+ Copyright (c) 2016 Solidus, released under the New BSD License
@@ -0,0 +1,30 @@
1
+ require 'bundler'
2
+
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ begin
6
+ require 'spree/testing_support/extension_rake'
7
+ require 'rubocop/rake_task'
8
+ require 'rspec/core/rake_task'
9
+
10
+ RSpec::Core::RakeTask.new(:spec)
11
+
12
+ RuboCop::RakeTask.new
13
+
14
+ task default: %i(first_run rubocop spec)
15
+ rescue LoadError
16
+ # no rspec available
17
+ end
18
+
19
+ task :first_run do
20
+ if Dir['spec/dummy'].empty?
21
+ Rake::Task[:test_app].invoke
22
+ Dir.chdir('../../')
23
+ end
24
+ end
25
+
26
+ desc 'Generates a dummy app for testing'
27
+ task :test_app do
28
+ ENV['LIB_NAME'] = 'solidus_prototypes'
29
+ Rake::Task['extension:test_app'].invoke
30
+ end
@@ -0,0 +1,11 @@
1
+ $(document).on('change', '#product_prototype_id', function() {
2
+ var solidus_prototypes_select = $('#product_prototype_id');
3
+ var id = solidus_prototypes_select.val();
4
+ if (id.length) {
5
+ var url = new Uri('prototypes');
6
+ url.setPath(url.path() + '/' + id);
7
+ $('#product-from-prototype').load(url.toString());
8
+ } else {
9
+ $('#product-from-prototype').empty();
10
+ }
11
+ });
@@ -0,0 +1,4 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/backend/all.js'
3
+
4
+ //= require spree/backend/select_prototype_ajax
@@ -0,0 +1,2 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/frontend/all.js'
@@ -0,0 +1,4 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/backend/all.css'
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/frontend/all.css'
4
+ */
@@ -0,0 +1,10 @@
1
+ module SolidusPrototypes
2
+ module OptionTypePrototypeConcern
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ has_many :option_type_prototypes
7
+ has_many :prototypes, through: :option_type_prototypes
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ module SolidusPrototypes
2
+ module PermittedAttributesConcern
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ product_attributes << :prototype_id
7
+ end
8
+
9
+ module ClassMethods
10
+ def product_attributes
11
+ @@product_attributes
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,34 @@
1
+ module SolidusPrototypes
2
+ module ProductPrototypeConcern
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ after_create :add_associations_from_prototype
7
+ after_create :build_variants_from_option_values_hash, if: :option_values_hash
8
+
9
+ # Overrides the prototype_id setter in order to ensure it is cast to an
10
+ # integer.
11
+ #
12
+ # @param value [#to_i] the intended new value
13
+ # @!attribute [rw] prototype_id
14
+ # @return [Fixnum]
15
+ attr_reader :prototype_id
16
+ end
17
+
18
+ def prototype_id=(value)
19
+ @prototype_id = value.to_i
20
+ end
21
+
22
+ private
23
+
24
+ def add_associations_from_prototype
25
+ if prototype_id && prototype = Spree::Prototype.find_by(id: prototype_id)
26
+ prototype.properties.each do |property|
27
+ product_properties.create(property: property)
28
+ end
29
+ self.option_types = prototype.option_types
30
+ self.taxons = prototype.taxons
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ module SolidusPrototypes
2
+ module ProductsLoaderConcern
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ create.before :load_prototype
7
+ end
8
+
9
+ def load_prototype
10
+ resource = :product
11
+ return if params[resource][:prototype_id].blank?
12
+ @prototype = Spree::Prototype.find(params[resource][:prototype_id])
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ module SolidusPrototypes
2
+ module PropertyPrototypeConcern
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ has_many :property_prototypes
7
+ has_many :prototypes, through: :property_prototypes
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ module SolidusPrototypes
2
+ module PrototypeProductDisplayPermissionConcern
3
+ def activate!
4
+ super
5
+ can [:display, :admin], Spree::Prototype
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module SolidusPrototypes
2
+ module PrototypeProductManagementPermissionConcern
3
+ def activate!
4
+ can :manage, Spree::Prototype
5
+ super
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ module SolidusPrototypes
2
+ module TaxonPrototypeConcern
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ has_many :prototype_taxons, dependent: :destroy
7
+ has_many :prototypes, through: :prototype_taxons
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,26 @@
1
+ module Spree
2
+ module Admin
3
+ class PrototypesController < ResourceController
4
+ def show
5
+ if request.xhr?
6
+ render layout: false
7
+ else
8
+ redirect_to admin_prototypes_path
9
+ end
10
+ end
11
+
12
+ def available
13
+ @prototypes = Prototype.order('name asc')
14
+ respond_with(@prototypes) do |format|
15
+ format.html { render layout: !request.xhr? }
16
+ format.js
17
+ end
18
+ end
19
+
20
+ def select
21
+ @prototype ||= Prototype.find(params[:id])
22
+ @prototype_properties = @prototype.properties
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,6 @@
1
+ module Spree
2
+ class OptionTypePrototype < Spree::Base
3
+ belongs_to :option_type
4
+ belongs_to :prototype
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Spree
2
+ class PropertyPrototype < Spree::Base
3
+ belongs_to :prototype
4
+ belongs_to :property
5
+ end
6
+ end
@@ -0,0 +1,14 @@
1
+ module Spree
2
+ class Prototype < Spree::Base
3
+ has_many :property_prototypes
4
+ has_many :properties, through: :property_prototypes
5
+
6
+ has_many :option_type_prototypes
7
+ has_many :option_types, through: :option_type_prototypes
8
+
9
+ has_many :prototype_taxons, dependent: :destroy
10
+ has_many :taxons, through: :prototype_taxons
11
+
12
+ validates :name, presence: true
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ module Spree
2
+ class PrototypeTaxon < Spree::Base
3
+ belongs_to :prototype
4
+ belongs_to :taxon
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ Deface::Override.new(
2
+ virtual_path: "spree/admin/shared/_product_sub_menu",
3
+ name: "prototypes_product_tabs",
4
+ insert_bottom: "[data-hook='admin_product_sub_tabs']",
5
+ disabled: false,
6
+ partial: "spree/shared/prototypes_products_sub_menu_tab"
7
+ )
@@ -0,0 +1,15 @@
1
+ Deface::Override.new(
2
+ virtual_path: "spree/admin/products/new",
3
+ name: "prototypes_admin_products_new",
4
+ insert_before: "[data-hook='new_product_price']",
5
+ disabled: false,
6
+ partial: "spree/admin/prototypes/products_new"
7
+ )
8
+
9
+ Deface::Override.new(
10
+ virtual_path: "spree/admin/products/new",
11
+ name: "prototypes_admin_products_new_clearfix",
12
+ insert_after: "[data-hook='new_product_tax_category']",
13
+ disabled: false,
14
+ partial: "spree/admin/prototypes/products_new_clearfix"
15
+ )
@@ -0,0 +1,7 @@
1
+ Deface::Override.new(
2
+ virtual_path: "spree/admin/product_properties/index",
3
+ name: "prototype_product_properties_form",
4
+ insert_after: "[data-hook='add_product_properties']",
5
+ disabled: false,
6
+ text: "<div id='prototypes' data-hook></div>"
7
+ )
@@ -0,0 +1,7 @@
1
+ Deface::Override.new(
2
+ virtual_path: "spree/admin/product_properties/index",
3
+ name: "prototypes_product_properties_toolbar",
4
+ insert_bottom: "ul.tollbar",
5
+ disabled: false,
6
+ partial: "spree/shared/prototypes_product_properties_toolbar"
7
+ )
@@ -0,0 +1,36 @@
1
+ <div data-hook="admin_prototype_form_fields" class="row">
2
+ <div class="alpha four columns">
3
+ <%= f.field_container :name do %>
4
+ <%= f.label :name, class: 'required' %><br />
5
+ <%= f.text_field :name, class: 'fullwidth' %>
6
+ <%= f.error_message_on :name %>
7
+ <% end %>
8
+ </div>
9
+
10
+ <div class="four columns">
11
+ <div id='properties' data-hook>
12
+ <%= f.field_container :property_ids do %>
13
+ <%= f.label :property_ids, plural_resource_name(Spree::Property) %><br>
14
+ <%= f.select :property_ids, Spree::Property.all.map { |p| ["#{p.presentation} (#{p.name})", p.id] }, {}, { multiple: true, class: "select2 fullwidth" } %>
15
+ <% end %>
16
+ </div>
17
+ </div>
18
+
19
+ <div class="four columns">
20
+ <div id="option_types" data-hook>
21
+ <%= f.field_container :option_type_ids do %>
22
+ <%= f.label :option_type_ids, plural_resource_name(Spree::OptionType) %><br>
23
+ <%= f.select :option_type_ids, Spree::OptionType.all.map { |ot| ["#{ot.presentation} (#{ot.name})", ot.id] }, {}, { multiple: true, class: "select2 fullwidth" } %>
24
+ <% end %>
25
+ </div>
26
+ </div>
27
+
28
+ <div class="four columns omega">
29
+ <div id='taxons' data-hook>
30
+ <%= f.field_container :taxon_ids do %>
31
+ <%= f.label :taxon_ids, plural_resource_name(Spree::Taxon) %><br>
32
+ <%= f.select :taxon_ids, Spree::Taxon.all.map { |t| [t.name, t.id] }, {}, { multiple: true, class: "select2 fullwidth" } %>
33
+ <% end %>
34
+ </div>
35
+ </div>
36
+ </div>
@@ -0,0 +1,6 @@
1
+ <div data-hook="new_product_prototype" class="four columns">
2
+ <%= f.field_container :prototype do %>
3
+ <%= f.label :prototype_id, Spree::Prototype.model_name.human %><br />
4
+ <%= f.collection_select :prototype_id, Spree::Prototype.all, :id, :name, {:include_blank => true}, {:class => 'select2 fullwidth'} %>
5
+ <% end %>
6
+ </div>
@@ -0,0 +1,3 @@
1
+ <div class="clearfix" data-hook="product-from-prototype" id="product-from-prototype">
2
+ <%= render :file => 'spree/admin/prototypes/show' if @prototype %>
3
+ </div>
@@ -0,0 +1,25 @@
1
+ <table class="index">
2
+ <colgroup>
3
+ <col style="width: 80%" />
4
+ <col style="width: 20%" />
5
+ </colgroup>
6
+ <thead>
7
+ <tr data-hook="available_header">
8
+ <th><%= Spree::Prototype.human_attribute_name(:name) %></th>
9
+ <th class="actions"></th>
10
+ </tr>
11
+ </thead>
12
+ <tbody>
13
+ <% @prototypes.each do |prototype| %>
14
+ <tr id="row_<%= prototype.id %>" data-hook="available_row" class="<%= cycle('odd', 'even')%>">
15
+ <td><%= prototype.name %></td>
16
+ <td class="actions">
17
+ <%= link_to Spree.t(:select), select_admin_prototype_url(prototype), class: 'ajax button select_properties_from_prototype', data: { remote: true } %>
18
+ </td>
19
+ </tr>
20
+ <% end %>
21
+ <% if @prototypes.empty? %>
22
+ <tr data-hook="available_none"><td colspan="2"><% Spree.t(:none) %>.</td></tr>
23
+ <% end %>
24
+ </tbody>
25
+ </table>
@@ -0,0 +1,2 @@
1
+ $("#prototypes").html('<%= escape_javascript(render :partial => "spree/admin/prototypes/prototypes") %>');
2
+ $("#new_ptype_link").hide();
@@ -0,0 +1,15 @@
1
+ <% admin_breadcrumb(link_to plural_resource_name(Spree::Product), spree.admin_products_path) %>
2
+ <% admin_breadcrumb(link_to plural_resource_name(Spree::Prototype), spree.admin_prototypes_path) %>
3
+ <% admin_breadcrumb(@prototype.name) %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <% end %>
7
+
8
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @prototype } %>
9
+
10
+ <%= form_for [:admin, @prototype] do |f| %>
11
+ <fieldset class="no-border-top">
12
+ <%= render :partial => 'form', :locals => { :f => f } %>
13
+ <%= render :partial => 'spree/admin/shared/edit_resource_links' %>
14
+ </fieldset>
15
+ <% end %>
@@ -0,0 +1,50 @@
1
+ <% admin_breadcrumb(link_to plural_resource_name(Spree::Product), spree.admin_products_path) %>
2
+ <% admin_breadcrumb(plural_resource_name(Spree::Prototype)) %>
3
+
4
+
5
+ <% content_for :page_actions do %>
6
+ <% if can?(:create, Spree::Prototype) %>
7
+ <li id="new_prototype_link">
8
+ <%= button_link_to Spree.t(:new_prototype), new_admin_prototype_url, {:remote => true, :id => 'new_prototype_link'} %>
9
+ </li>
10
+ <% end %>
11
+ <% end %>
12
+
13
+ <%# Placeholder for new prototype form %>
14
+ <div id="new_prototype_container"></div>
15
+
16
+ <% if @prototypes.any? %>
17
+ <table class="index" id='listing_prototypes' data-hook>
18
+ <colgroup>
19
+ <col style="width: 90%">
20
+ <col style="width: 10%">
21
+ </colgroup>
22
+ <thead>
23
+ <tr data-hook="prototypes_header">
24
+ <th><%= Spree::Prototype.human_attribute_name(:name) %></th>
25
+ <th class="actions"></th>
26
+ </tr>
27
+ </thead>
28
+ <tbody>
29
+ <% @prototypes.each do |prototype| %>
30
+ <tr id="<%= spree_dom_id prototype %>" data-hook="prototypes_row" class="<%= cycle('odd', 'even')%>">
31
+ <td style="padding-left:1em"><%= prototype.name %></td>
32
+ <td class="actions">
33
+ <% if can?(:update, prototype) %>
34
+ <%= link_to_edit(prototype, :no_text => true, :class => 'admin_edit_prototype') %>
35
+ <% end %>
36
+ <% if can?(:destroy, prototype) %>
37
+ <%= link_to_delete(prototype, :no_text => true) %>
38
+ <% end %>
39
+ </td>
40
+ </tr>
41
+ <% end %>
42
+ </tbody>
43
+ </table>
44
+ <% else %>
45
+ <div class="alpha twelve columns no-objects-found">
46
+ <%= render 'spree/admin/shared/no_objects_found',
47
+ resource: Spree::Prototype,
48
+ new_resource_url: new_object_url %>
49
+ </div>
50
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @prototype } %>
2
+
3
+ <%= form_for [:admin, @prototype] do |f| %>
4
+ <fieldset data-hook="new_prototype">
5
+ <legend align="center"><%= Spree.t(:new_prototype) %></legend>
6
+ <%= render :partial => 'form', :locals => { :f => f } %>
7
+ <%= render :partial => 'spree/admin/shared/new_resource_links' %>
8
+ </fieldset>
9
+ <% end %>
@@ -0,0 +1,5 @@
1
+ $("#new_prototype_container").html('<%= escape_javascript(render :template => "spree/admin/prototypes/new", :formats=>[:html], :handlers=>[:erb]) %>');
2
+ <% unless Rails.env.test? %>
3
+ $('.select2').select2();
4
+ <% end %>
5
+ $("#new_prototype_link").parent().hide();
@@ -0,0 +1,4 @@
1
+ <% @prototype_properties.sort_by{ |prop| -prop[:id] }.each do |prop| %>
2
+ $("a.spree_add_fields").click();
3
+ $(".product_property.fields:first input[type=text]:first").val("<%= prop.name %>");
4
+ <% end %>
@@ -0,0 +1,42 @@
1
+ <% if @prototype.option_types.present? %>
2
+ <h2><%= plural_resource_name(Spree::Variant) %></h2>
3
+
4
+ <ul class="product-prototype-options">
5
+ <% @prototype.option_types.each do |ot| %>
6
+ <li class="option-type-field">
7
+ <b>
8
+ <%= check_box_tag "option_types[]", ot.id, (params[:option_types] || []).include?(ot.id.to_s), :id => "option_type_#{ot.id}", :class => "option-type" %>
9
+ <%= label_tag "option_type_#{ot.id}", ot.presentation %>
10
+ </b>
11
+ <ul class="option-type-values">
12
+ <% ot.option_values.each do |ov| %>
13
+ <li>
14
+ <%= check_box_tag "product[option_values_hash[#{ot.id}]][]", ov.id, params[:product] && (params[:product][:option_values_hash] || {}).values.flatten.include?(ov.id.to_s), :id => "option_value_#{ov.id}", :class => "option-value" %>
15
+ <%= label_tag "option_value_#{ov.id}", ov.presentation %>
16
+ </li>
17
+ <% end %>
18
+ </ul>
19
+ </li>
20
+ <% end %>
21
+ </ul>
22
+
23
+ <script type="text/javascript">
24
+ //<![CDATA[
25
+ (function($){
26
+
27
+ $("input.option-type").change(function() {
28
+ $(this).parents("li").find("input.option-value").prop("checked", this.checked);
29
+ });
30
+
31
+ $("input.option-value").change(function() {
32
+ var any_checked = false;
33
+ $(this).parents(".option-type-values").find("input.option-value").each(function(i, el) {
34
+ any_checked = any_checked || el.checked;
35
+ });
36
+ $(this).parents(".option-type-field").find("input.option-type").prop("checked", any_checked);
37
+ });
38
+
39
+ })(jQuery);
40
+ //]]>
41
+ </script>
42
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <li>
2
+ <span id="new_ptype_link">
3
+ <%= link_to Spree.t(:select_from_prototype), available_admin_prototypes_url, :remote => true, :class => 'button fa fa-copy' %>
4
+ </span>
5
+ </li>
@@ -0,0 +1,3 @@
1
+ <% if can? :admin, Spree::Prototype %>
2
+ <%= tab :prototypes %>
3
+ <% end %>
@@ -0,0 +1,21 @@
1
+ en:
2
+ activerecord:
3
+ attributes:
4
+ spree/prototype:
5
+ name: Name
6
+ models:
7
+ # LegacyUser maps to this model_name so we want to provide translations for it
8
+ spree/prototype:
9
+ one: Prototype
10
+ other: Prototypes
11
+
12
+ spree:
13
+ admin:
14
+ tab:
15
+ prototypes: Prototypes
16
+ back_to_prototypes_list: Back To Prototypes List
17
+ editing_prototype: Editing Prototype
18
+ new_prototype: New Prototype
19
+ prototype: Prototype
20
+ prototypes: Prototypes
21
+ select_from_prototype: Select From Prototype
@@ -0,0 +1,14 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ # Add your extension routes here
3
+ namespace :admin do
4
+ resources :prototypes do
5
+ member do
6
+ get :select
7
+ end
8
+
9
+ collection do
10
+ get :available
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,34 @@
1
+ class CreatePrototypes < ActiveRecord::Migration[5.0]
2
+ def change
3
+ unless data_source_exists?("spree_prototypes")
4
+ create_table :spree_prototypes do |t|
5
+ t.string :name
6
+ t.timestamps null: true
7
+ end
8
+ end
9
+
10
+ unless data_source_exists?("spree_property_prototypes")
11
+ create_table :spree_property_prototypes, id: false do |t|
12
+ t.references :prototype
13
+ t.references :property
14
+ t.timestamps null: true
15
+ end
16
+ end
17
+
18
+ unless data_source_exists?("spree_prototype_taxons")
19
+ create_table :spree_prototype_taxons do |t|
20
+ t.integer :taxon_id, index: true
21
+ t.integer :prototype_id, index: true
22
+ t.timestamps null: true
23
+ end
24
+ end
25
+
26
+ unless data_source_exists?("spree_option_type_prototypes")
27
+ create_table :spree_option_type_prototypes, id: false do |t|
28
+ t.references :prototype
29
+ t.references :option_type
30
+ t.timestamps null: true
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1 @@
1
+ Spree::Admin::ProductsController.include SolidusPrototypes::ProductsLoaderConcern
@@ -0,0 +1 @@
1
+ Spree::OptionType.include SolidusPrototypes::OptionTypePrototypeConcern
@@ -0,0 +1 @@
1
+ Spree::PermissionSets::ProductDisplay.prepend SolidusPrototypes::PrototypeProductDisplayPermissionConcern
@@ -0,0 +1 @@
1
+ Spree::PermissionSets::ProductManagement.prepend SolidusPrototypes::PrototypeProductManagementPermissionConcern
@@ -0,0 +1 @@
1
+ Spree::PermittedAttributes.include SolidusPrototypes::PermittedAttributesConcern
@@ -0,0 +1 @@
1
+ Spree::Product.include SolidusPrototypes::ProductPrototypeConcern
@@ -0,0 +1 @@
1
+ Spree::Property.include SolidusPrototypes::PropertyPrototypeConcern
@@ -0,0 +1 @@
1
+ Spree::Taxon.include SolidusPrototypes::TaxonPrototypeConcern
@@ -0,0 +1,30 @@
1
+ module SolidusPrototypes
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ class_option :auto_run_migrations, type: :boolean, default: false
5
+
6
+ def add_javascripts
7
+ append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/solidus_prototypes\n"
8
+ append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/solidus_prototypes\n"
9
+ end
10
+
11
+ def add_stylesheets
12
+ inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/solidus_prototypes\n", before: /\*\//, verbose: true
13
+ inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/solidus_prototypes\n", before: /\*\//, verbose: true
14
+ end
15
+
16
+ def add_migrations
17
+ run 'bundle exec rake railties:install:migrations FROM=solidus_prototypes'
18
+ end
19
+
20
+ def run_migrations
21
+ run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]'))
22
+ if run_migrations
23
+ run 'bundle exec rake db:migrate'
24
+ else
25
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,2 @@
1
+ require 'solidus_core'
2
+ require 'solidus_prototypes/engine'
@@ -0,0 +1,21 @@
1
+ module SolidusPrototypes
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'solidus_prototypes'
6
+
7
+ config.autoload_paths += %W(#{config.root}/lib/concerns)
8
+ # use rspec for tests
9
+ config.generators do |g|
10
+ g.test_framework :rspec
11
+ end
12
+
13
+ def self.activate
14
+ Dir.glob(File.join(File.dirname(__FILE__), '../../lib/decorators/**/*_decorator*.rb')) do |c|
15
+ Rails.configuration.cache_classes ? require(c) : load(c)
16
+ end
17
+ end
18
+
19
+ config.to_prepare(&method(:activate).to_proc)
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ require 'spree/testing_support/factories/property_factory'
2
+
3
+ FactoryGirl.define do
4
+ factory :prototype, class: Spree::Prototype do
5
+ name 'Baseball Cap'
6
+ properties { [create(:property)] }
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ module Spree
2
+ module PermissionSets
3
+ # Adds all product display permissions, with addition
4
+ # permissions for Spree::Prototype
5
+ #
6
+ # @example Adding order, user, and product (with prototype) display to customer service users.
7
+ # Spree::RoleConfiguration.configure do |config|
8
+ # config.assign_permissions :customer_service, [
9
+ # Spree::PermissionSets::OrderDisplay,
10
+ # Spree::PermissionSets::UserDisplay,
11
+ # Spree::PermissionSets::PrototypeProductDisplay
12
+ # ]
13
+ # end
14
+ class PrototypeProductDisplay < PermissionSets::ProductDisplay
15
+ def activate!
16
+ can [:display, :admin], Spree::Prototype
17
+ super
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ module Spree
2
+ module PermissionSets
3
+ # Adds all product display permissions, with addition
4
+ # permissions for Spree::Prototype
5
+ #
6
+ # @example Adding product (with prototype) management to customer service users.
7
+ # Spree::RoleConfiguration.configure do |config|
8
+ # config.assign_permissions :customer_service, [
9
+ # Spree::PermissionSets::PrototypeProductManagement
10
+ # ]
11
+ # end
12
+ class PrototypeProductManagement < PermissionSets::ProductManagement
13
+ def activate!
14
+ can :manage, Spree::Prototype
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module SolidusPrototypes
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,273 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: solidus_prototypes
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Graeme Nathan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: solidus_core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.0.alpha
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 2.1.0.alpha
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
33
+ - !ruby/object:Gem::Dependency
34
+ name: capybara
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: poltergeist
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: coffee-rails
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: sass-rails
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: database_cleaner
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: factory_girl
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rspec-rails
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: rubocop
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - '='
136
+ - !ruby/object:Gem::Version
137
+ version: 0.46.0
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - '='
143
+ - !ruby/object:Gem::Version
144
+ version: 0.46.0
145
+ - !ruby/object:Gem::Dependency
146
+ name: rubocop-rspec
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '1.8'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '1.8'
159
+ - !ruby/object:Gem::Dependency
160
+ name: simplecov
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: sqlite3
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ description: Breaking out prototypes from solidus
188
+ email: graeme@stembolt.com
189
+ executables: []
190
+ extensions: []
191
+ extra_rdoc_files: []
192
+ files:
193
+ - LICENSE
194
+ - README.md
195
+ - Rakefile
196
+ - app/assets/javascripts/spree/backend/select_prototype_ajax.js
197
+ - app/assets/javascripts/spree/backend/solidus_prototypes.js
198
+ - app/assets/javascripts/spree/frontend/solidus_prototypes.js
199
+ - app/assets/stylesheets/spree/backend/solidus_prototypes.css
200
+ - app/assets/stylesheets/spree/frontend/solidus_prototypes.css
201
+ - app/concerns/solidus_prototypes/option_type_prototype_concern.rb
202
+ - app/concerns/solidus_prototypes/permitted_attributes_concern.rb
203
+ - app/concerns/solidus_prototypes/product_prototype_concern.rb
204
+ - app/concerns/solidus_prototypes/products_loader_concern.rb
205
+ - app/concerns/solidus_prototypes/property_prototype_concern.rb
206
+ - app/concerns/solidus_prototypes/prototype_product_display_permission_concern.rb
207
+ - app/concerns/solidus_prototypes/prototype_product_management_permission_concern.rb
208
+ - app/concerns/solidus_prototypes/taxon_prototype_concern.rb
209
+ - app/controllers/spree/admin/prototypes_controller.rb
210
+ - app/models/spree/option_type_prototype.rb
211
+ - app/models/spree/property_prototype.rb
212
+ - app/models/spree/prototype.rb
213
+ - app/models/spree/prototype_taxon.rb
214
+ - app/overrides/decorate_admin_product_tabs.rb
215
+ - app/overrides/decorate_admin_products_new.rb
216
+ - app/overrides/decorate_product_properties_form.rb
217
+ - app/overrides/decorate_product_properties_index.rb
218
+ - app/views/spree/admin/prototypes/_form.html.erb
219
+ - app/views/spree/admin/prototypes/_products_new.html.erb
220
+ - app/views/spree/admin/prototypes/_products_new_clearfix.html.erb
221
+ - app/views/spree/admin/prototypes/_prototypes.html.erb
222
+ - app/views/spree/admin/prototypes/available.js.erb
223
+ - app/views/spree/admin/prototypes/edit.html.erb
224
+ - app/views/spree/admin/prototypes/index.html.erb
225
+ - app/views/spree/admin/prototypes/new.html.erb
226
+ - app/views/spree/admin/prototypes/new.js.erb
227
+ - app/views/spree/admin/prototypes/select.js.erb
228
+ - app/views/spree/admin/prototypes/show.html.erb
229
+ - app/views/spree/shared/_prototypes_product_properties_toolbar.html.erb
230
+ - app/views/spree/shared/_prototypes_products_sub_menu_tab.html.erb
231
+ - config/locales/en.yml
232
+ - config/routes.rb
233
+ - db/migrate/20160929214715_create_prototypes.rb
234
+ - lib/decorators/spree/admin/products_decorator.rb
235
+ - lib/decorators/spree/option_type_decorator.rb
236
+ - lib/decorators/spree/permission_sets_product_display_decorator.rb
237
+ - lib/decorators/spree/permission_sets_product_management_decorator.rb
238
+ - lib/decorators/spree/permitted_attributes_prototype_decorator.rb
239
+ - lib/decorators/spree/products_decorator.rb
240
+ - lib/decorators/spree/property_decorator.rb
241
+ - lib/decorators/spree/taxon_decorator.rb
242
+ - lib/generators/solidus_prototypes/install/install_generator.rb
243
+ - lib/solidus_prototypes.rb
244
+ - lib/solidus_prototypes/engine.rb
245
+ - lib/solidus_prototypes/factories.rb
246
+ - lib/solidus_prototypes/spree/permission_sets/prototype_product_display.rb
247
+ - lib/solidus_prototypes/spree/permission_sets/prototype_product_management.rb
248
+ - lib/solidus_prototypes/version.rb
249
+ homepage: https://github.com/gevann
250
+ licenses:
251
+ - BSD-3-Clause
252
+ metadata: {}
253
+ post_install_message:
254
+ rdoc_options: []
255
+ require_paths:
256
+ - lib
257
+ required_ruby_version: !ruby/object:Gem::Requirement
258
+ requirements:
259
+ - - ">="
260
+ - !ruby/object:Gem::Version
261
+ version: '0'
262
+ required_rubygems_version: !ruby/object:Gem::Requirement
263
+ requirements:
264
+ - - ">="
265
+ - !ruby/object:Gem::Version
266
+ version: '0'
267
+ requirements: []
268
+ rubyforge_project:
269
+ rubygems_version: 2.6.10
270
+ signing_key:
271
+ specification_version: 4
272
+ summary: Adds prototypes for solidus
273
+ test_files: []