workarea-swatches 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +20 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.gitignore +21 -0
- data/CHANGELOG.md +121 -0
- data/CODE_OF_CONDUCT.md +3 -0
- data/CONTRIBUTING.md +3 -0
- data/Gemfile +17 -0
- data/LICENSE +52 -0
- data/README.md +40 -0
- data/Rakefile +60 -0
- data/app/assets/javascripts/workarea/storefront/swatches/modules/product_summary_swatches.js +63 -0
- data/app/assets/stylesheets/workarea/storefront/swatches/components/_option_button.scss +17 -0
- data/app/assets/stylesheets/workarea/storefront/swatches/components/_swatch_facet.scss +25 -0
- data/app/assets/stylesheets/workarea/storefront/swatches/components/_swatch_options.scss +54 -0
- data/app/controllers/workarea/admin/catalog_product_swatches_controller.rb +47 -0
- data/app/controllers/workarea/admin/catalog_swatches_controller.rb +48 -0
- data/app/controllers/workarea/storefront/products_controller.decorator +12 -0
- data/app/helpers/workarea/storefront/swatches_helper.rb +84 -0
- data/app/models/workarea/catalog/product.decorator +7 -0
- data/app/models/workarea/catalog/product_swatch.rb +10 -0
- data/app/models/workarea/catalog/swatch.rb +37 -0
- data/app/models/workarea/search/settings.decorator +8 -0
- data/app/queries/workarea/search/category_browse.decorator +7 -0
- data/app/queries/workarea/search/product_search.decorator +7 -0
- data/app/queries/workarea/search/swatched_facets.rb +19 -0
- data/app/queries/workarea/search/swatches_facet.rb +13 -0
- data/app/seeds/workarea/swatches_seeds.rb +37 -0
- data/app/view_models/workarea/storefront/product_templates/swatches_view_model.rb +57 -0
- data/app/views/workarea/admin/activities/_catalog_product_swatch_create.html.haml +10 -0
- data/app/views/workarea/admin/activities/_catalog_product_swatch_destroy.html.haml +10 -0
- data/app/views/workarea/admin/activities/_catalog_swatch_create.html.haml +12 -0
- data/app/views/workarea/admin/activities/_catalog_swatch_destroy.html.haml +10 -0
- data/app/views/workarea/admin/catalog_product_swatches/edit.html.haml +52 -0
- data/app/views/workarea/admin/catalog_product_swatches/index.html.haml +65 -0
- data/app/views/workarea/admin/catalog_products/_swatches_card.html.haml +27 -0
- data/app/views/workarea/admin/catalog_swatches/_primary_navigation.html.haml +1 -0
- data/app/views/workarea/admin/catalog_swatches/index.html.haml +78 -0
- data/app/views/workarea/api/storefront/facets/_swatches.json.jbuilder +17 -0
- data/app/views/workarea/storefront/facets/_swatches.html.haml +14 -0
- data/app/views/workarea/storefront/products/_swatch_summary.html.haml +17 -0
- data/app/views/workarea/storefront/products/templates/_swatches.html.haml +79 -0
- data/bin/rails +19 -0
- data/config/initializers/dragonfly.rb +11 -0
- data/config/initializers/workarea.rb +40 -0
- data/config/locales/en.yml +52 -0
- data/config/routes.rb +15 -0
- data/lib/tasks/swatches_tasks.rake +4 -0
- data/lib/workarea/swatches.rb +11 -0
- data/lib/workarea/swatches/engine.rb +12 -0
- data/lib/workarea/swatches/version.rb +5 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/config/manifest.js +4 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/application_job.rb +2 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +30 -0
- data/test/dummy/bin/update +26 -0
- data/test/dummy/bin/yarn +11 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/config/application.rb +30 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/cable.yml +10 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +51 -0
- data/test/dummy/config/environments/production.rb +88 -0
- data/test/dummy/config/environments/test.rb +44 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/test/dummy/config/initializers/assets.rb +14 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/workarea.rb +5 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
- data/test/dummy/config/locales/en.yml +33 -0
- data/test/dummy/config/puma.rb +56 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/config/secrets.yml +32 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/db/seeds.rb +2 -0
- data/test/dummy/log/.keep +0 -0
- data/test/factories/workarea/swatches.rb +14 -0
- data/test/integration/workarea/admin/product_swatches_integration_test.rb +43 -0
- data/test/integration/workarea/admin/swatches_integration_test.rb +37 -0
- data/test/integration/workarea/storefront/swatches_integration_test.rb +72 -0
- data/test/system/workarea/admin/swatches_system_test.rb +58 -0
- data/test/system/workarea/storefront/browse_swatches_system_test.rb +50 -0
- data/test/system/workarea/storefront/swatches_system_test.rb +101 -0
- data/test/teaspoon_env.rb +6 -0
- data/test/test_helper.rb +10 -0
- data/test/view_models/workarea/storefront/product_templates/swatches_view_model_test.rb +74 -0
- data/workarea-swatches.gemspec +19 -0
- metadata +147 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Storefront
|
3
|
+
class ProductTemplates::SwatchesViewModel < ProductViewModel
|
4
|
+
include OptionSetViewModel
|
5
|
+
|
6
|
+
def images_by_option
|
7
|
+
@images_by_option ||= model
|
8
|
+
.images
|
9
|
+
.reject { |i| i.option.blank? }
|
10
|
+
.group_by { |i| i.option.optionize }
|
11
|
+
.with_indifferent_access
|
12
|
+
.transform_keys(&:optionize)
|
13
|
+
end
|
14
|
+
|
15
|
+
def swatches_by_option
|
16
|
+
@swatches_by_option ||= Hash[swatches_with_overrides.map { |s| [s.id, s] }]
|
17
|
+
end
|
18
|
+
|
19
|
+
def browse_link_options
|
20
|
+
return super unless current_browse_selection.present?
|
21
|
+
super.merge(browse_swatch_option.slug => current_browse_selection)
|
22
|
+
end
|
23
|
+
|
24
|
+
def browse_swatch_option
|
25
|
+
@browse_swatch_option ||=
|
26
|
+
Workarea.config.browse_swatch_option.call(self, options_for_selection)
|
27
|
+
end
|
28
|
+
|
29
|
+
def display_browse_swatches?
|
30
|
+
return false if model.try(:browse_option).present?
|
31
|
+
browse_swatch_option.present?
|
32
|
+
end
|
33
|
+
|
34
|
+
def current_browse_selection
|
35
|
+
return if browse_swatch_option.blank?
|
36
|
+
options[browse_swatch_option.slug]
|
37
|
+
end
|
38
|
+
|
39
|
+
def current_browse_selection?(selection)
|
40
|
+
current_browse_selection == selection
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def swatches_with_overrides
|
46
|
+
(global_swatches + model.swatches).map do |swatch|
|
47
|
+
override_swatch = model.swatches.detect { |s| s.id == swatch.id }
|
48
|
+
override_swatch || swatch
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def global_swatches
|
53
|
+
@global_swatches ||= Catalog::Swatch.all.to_a
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
.activity
|
2
|
+
.activity__header
|
3
|
+
.activity__avatar
|
4
|
+
= link_to_modifier(entry) do
|
5
|
+
= avatar_for entry.modifier
|
6
|
+
%h3.activity__name= link_to_modifier(entry)
|
7
|
+
%p.activity__time= activity_time(entry.created_at)
|
8
|
+
.activity__message
|
9
|
+
- name = entry.root.blank? ? t('workarea.admin.activities.a_product') : link_to(entry.root.name, catalog_product_path(entry.root))
|
10
|
+
= t('workarea.admin.activities.catalog_product_swatch_create_html', name: name)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
.activity
|
2
|
+
.activity__header
|
3
|
+
.activity__avatar
|
4
|
+
= link_to_modifier(entry) do
|
5
|
+
= avatar_for entry.modifier
|
6
|
+
%h3.activity__name= link_to_modifier(entry)
|
7
|
+
%p.activity__time= activity_time(entry.created_at)
|
8
|
+
.activity__message
|
9
|
+
- name = entry.root.blank? ? t('workarea.admin.activities.a_product') : link_to(entry.root.name, catalog_product_path(entry.root))
|
10
|
+
= t('workarea.admin.activities.catalog_product_swatch_destroy_html', name: name)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
.activity
|
2
|
+
.activity__header
|
3
|
+
.activity__avatar
|
4
|
+
= link_to_modifier(entry) do
|
5
|
+
= avatar_for entry.modifier
|
6
|
+
%h3.activity__name= link_to_modifier(entry)
|
7
|
+
%p.activity__time= activity_time(entry.created_at)
|
8
|
+
.activity__message
|
9
|
+
- if entry.audited.present?
|
10
|
+
= t('workarea.admin.activities.catalog_swatch_create_html', name: link_to(entry.audited.name, catalog_swatch_path(entry.audited)))
|
11
|
+
- else
|
12
|
+
= t('workarea.admin.activities.catalog_swatch_create_html', name: entry.model_name)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
.activity
|
2
|
+
.activity__header
|
3
|
+
.activity__avatar
|
4
|
+
= link_to_modifier(entry) do
|
5
|
+
= avatar_for entry.modifier
|
6
|
+
%h3.activity__name= link_to_modifier(entry)
|
7
|
+
%p.activity__time= activity_time(entry.created_at)
|
8
|
+
.activity__message
|
9
|
+
= t('workarea.admin.activities.catalog_swatch_destroy_html', name: entry.model_name)
|
10
|
+
= link_to_restore_for(entry)
|
@@ -0,0 +1,52 @@
|
|
1
|
+
- @page_title = t('workarea.admin.catalog_product_swatches.edit.edit_swatch_for', product: @product.name)
|
2
|
+
|
3
|
+
.product-images.view
|
4
|
+
.view__header
|
5
|
+
.grid.grid--middle
|
6
|
+
.grid__cell.grid__cell--25
|
7
|
+
= render 'workarea/admin/releases/select'
|
8
|
+
.grid__cell.grid__cell--50
|
9
|
+
.view__heading
|
10
|
+
= link_to_index_for(@product)
|
11
|
+
%h1= link_to @product.name, url_for(@product)
|
12
|
+
.grid__cell.grid__cell--25
|
13
|
+
= render_aux_navigation_for(@product)
|
14
|
+
|
15
|
+
.view__container
|
16
|
+
= render_cards_for(@product, :swatches)
|
17
|
+
|
18
|
+
.view__container.view__container--narrow
|
19
|
+
.section
|
20
|
+
.product-images__option-group
|
21
|
+
.product-images__option
|
22
|
+
.product-images__option-header
|
23
|
+
.product-images__option-title= @swatch.option.present? ? "#{@swatch.option.titleize} #{t('workarea.admin.catalog_product_swatches.edit.swatch')}" : t('workarea.admin.catalog_product_swatches.edit.without_options')
|
24
|
+
|
25
|
+
.product-images__image-group
|
26
|
+
.product-images__image
|
27
|
+
.product-images__image-summary
|
28
|
+
.product-images__image-summary-container= image_tag @swatch.image.process(:swatch).url, alt: "#{@swatch.option} #{t('workarea.admin.catalog_product_swatches.edit.swatch')}", id: @swatch.option.parameterize, class: 'product-images__image-summary-image'
|
29
|
+
|
30
|
+
.section
|
31
|
+
%h2= t('workarea.admin.catalog_product_swatches.edit.edit_swatch')
|
32
|
+
|
33
|
+
= form_tag catalog_product_swatch_path(@product, @swatch), method: :patch, multipart: true do
|
34
|
+
.property
|
35
|
+
= label_tag 'swatch_image', t('workarea.admin.fields.image'), class: 'property__name'
|
36
|
+
= file_field_tag 'swatch[image]', value: @swatch.url
|
37
|
+
|
38
|
+
.property
|
39
|
+
= label_tag 'swatch_option', t('workarea.admin.fields.option'), class: 'property__name'
|
40
|
+
= text_field_tag 'swatch[option]', @swatch.option, class: 'text-box text-box--medium', data: { autocomplete_field: options_catalog_product_images_path(@product) }
|
41
|
+
|
42
|
+
= append_partials('admin.product_swatch_fields')
|
43
|
+
|
44
|
+
= append_partials('admin.product_swatches', product: @product)
|
45
|
+
|
46
|
+
.workflow-bar
|
47
|
+
.grid.grid--right.grid--middle
|
48
|
+
.grid__cell.grid__cell--20
|
49
|
+
= link_to t('workarea.admin.form.cancel'), catalog_product_swatches_path(@product), class: 'workflow-bar__button workflow-bar__button--delete'
|
50
|
+
.grid__cell.grid__cell--80
|
51
|
+
.grid.grid--auto.grid--right.grid--middle
|
52
|
+
.grid__cell= button_tag t('workarea.admin.form.save_changes'), value: 'save_product_image', class: 'workflow-bar__button workflow-bar__button--update'
|
@@ -0,0 +1,65 @@
|
|
1
|
+
- @page_title = t('workarea.admin.catalog_product_swatches.index.swatches_for', product: @product.name)
|
2
|
+
.product-images.view
|
3
|
+
.view__header
|
4
|
+
.grid.grid--middle
|
5
|
+
.grid__cell.grid__cell--25
|
6
|
+
= render 'workarea/admin/releases/select'
|
7
|
+
.grid__cell.grid__cell--50
|
8
|
+
.view__heading
|
9
|
+
= link_to_index_for(@product)
|
10
|
+
%h1= link_to @product.name, url_for(@product)
|
11
|
+
.grid__cell.grid__cell--25
|
12
|
+
= render_aux_navigation_for(@product)
|
13
|
+
|
14
|
+
.view__container
|
15
|
+
= render_cards_for(@product, :swatches)
|
16
|
+
|
17
|
+
.view__container.view__container--narrow
|
18
|
+
.section
|
19
|
+
- if @product.swatches.blank?
|
20
|
+
%h2.align-center= t('workarea.admin.catalog_swatches.index.no_swatches')
|
21
|
+
- else
|
22
|
+
%table.index-table
|
23
|
+
%thead
|
24
|
+
%tr
|
25
|
+
%th= t('workarea.admin.fields.name')
|
26
|
+
%th= t('workarea.admin.fields.color')
|
27
|
+
%th= t('workarea.admin.fields.image')
|
28
|
+
%th= t('workarea.admin.actions.remove')
|
29
|
+
%tbody
|
30
|
+
- @product.swatches.each do |swatch|
|
31
|
+
%tr.index-table__row
|
32
|
+
%td= swatch.name
|
33
|
+
%td
|
34
|
+
= form_tag catalog_product_swatch_path(@product, swatch), method: 'patch' do
|
35
|
+
= color_field_tag 'swatch[hex]', swatch.hex, class: 'color-picker__input', data: { form_submitting_control: '' }, id: nil
|
36
|
+
%td
|
37
|
+
= form_tag catalog_product_swatch_path(@product, swatch), method: 'patch', multipart: true do
|
38
|
+
= image_tag swatch.image.process(:small).url if swatch.image.present?
|
39
|
+
= file_field_tag 'swatch[image]', class: 'text-box', data: { form_submitting_control: '' }, id: nil
|
40
|
+
%td
|
41
|
+
= form_tag catalog_product_swatch_path(@product, swatch), method: 'delete', class: 'text-button text-button--destroy' do
|
42
|
+
= button_tag value: 'remove_swatch', class: 'text-button text-button--destroy' do
|
43
|
+
= inline_svg('workarea/admin/icons/delete.svg', class: 'text-button__icon', title: t('workarea.admin.actions.delete'))
|
44
|
+
|
45
|
+
.section
|
46
|
+
.grid.grid--center
|
47
|
+
.grid__cell.grid__cell--50
|
48
|
+
%h2.align-center= t('workarea.admin.catalog_swatches.index.add_new')
|
49
|
+
|
50
|
+
= form_tag catalog_product_swatches_path(@product), method: 'post', multipart: true do
|
51
|
+
.grid.grid--auto
|
52
|
+
.grid__cell
|
53
|
+
.property.property--required
|
54
|
+
= label_tag 'swatch_name', t('workarea.admin.fields.name'), class: 'property__name'
|
55
|
+
= text_field_tag 'swatch[name]', params.dig(:swatch, :name), class: 'text-box text-box--medium', required: true, id: nil
|
56
|
+
.grid__cell
|
57
|
+
.property
|
58
|
+
= label_tag 'swatch_hex', t('workarea.admin.fields.color'), class: 'property__name'
|
59
|
+
= color_field_tag 'swatch[hex]', params.dig(:swatch, :hex), class: 'color-picker__input', id: nil
|
60
|
+
.grid__cell
|
61
|
+
.property
|
62
|
+
= label_tag 'swatch_image', t('workarea.admin.fields.image'), class: 'property__name'
|
63
|
+
= file_field_tag 'swatch[image]', class: 'text-box text-box--large', id: nil
|
64
|
+
|
65
|
+
= button_tag t('workarea.admin.actions.save'), value: 'save_new_swatch', class: 'button'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
.grid__cell
|
2
|
+
.card{ class: card_classes(:swatches, local_assigns[:active]) }
|
3
|
+
= link_to catalog_product_swatches_path(model), class: 'card__header' do
|
4
|
+
%span.card__header-text= t('workarea.admin.catalog_products.cards.swatches.title')
|
5
|
+
= inline_svg 'workarea/admin/icons/images.svg', class: 'card__icon'
|
6
|
+
|
7
|
+
- if local_assigns[:active].blank?
|
8
|
+
.card__body
|
9
|
+
- if model.swatches.empty?
|
10
|
+
%p= t('workarea.admin.catalog_products.cards.swatches.description')
|
11
|
+
= link_to catalog_product_swatches_path(model), class: 'card__button' do
|
12
|
+
%span.button.button--small= t('workarea.admin.catalog_products.cards.swatches.add_swatches')
|
13
|
+
- else
|
14
|
+
%ul.grid
|
15
|
+
- model.swatches.take(4).each_with_index do |swatch, i|
|
16
|
+
%li.grid__cell.grid__cell--50
|
17
|
+
- if i == 3 && model.swatches.size > 4
|
18
|
+
.card__photo-box
|
19
|
+
%span.card__photo +#{model.swatches.size - i}
|
20
|
+
- elsif swatch.image.present?
|
21
|
+
.card__photo-box
|
22
|
+
= image_tag swatch.image.process(:small_thumb).url, alt: swatch.name, class: 'card__photo'
|
23
|
+
- else
|
24
|
+
.card__photo-box{ style: "background-color: #{swatch.hex};" }
|
25
|
+
|
26
|
+
= link_to catalog_product_swatches_path(model), class: 'card__button' do
|
27
|
+
%span.button.button--small= t('workarea.admin.catalog_products.cards.swatches.manage_swatches')
|
@@ -0,0 +1 @@
|
|
1
|
+
%li{ class: "primary-nav__item" }= link_to t('workarea.admin.catalog_swatches.primary_navigation.swatches'), catalog_swatches_path, class: navigation_link_classes(catalog_swatches_path)
|
@@ -0,0 +1,78 @@
|
|
1
|
+
- @page_title= t('workarea.admin.catalog_swatches.index.page_title')
|
2
|
+
|
3
|
+
.view
|
4
|
+
.view__header
|
5
|
+
.grid.grid--center
|
6
|
+
.grid__cell.grid__cell--50
|
7
|
+
.view__heading
|
8
|
+
= link_to "↑ #{t('workarea.admin.catalog.dashboard_link')}", catalog_dashboards_path, class: 'view__dashboard-button'
|
9
|
+
%h1.heading--no-margin= t('workarea.admin.catalog_swatches.index.page_title')
|
10
|
+
%p= t('workarea.admin.catalog_swatches.index.description')
|
11
|
+
|
12
|
+
.view__container.view__container--narrow
|
13
|
+
.section
|
14
|
+
- if @swatches.blank?
|
15
|
+
%h2= t('workarea.admin.catalog_swatches.index.no_swatches')
|
16
|
+
- else
|
17
|
+
%table.index-table
|
18
|
+
%thead
|
19
|
+
%tr
|
20
|
+
%th= t('workarea.admin.fields.name')
|
21
|
+
%th= t('workarea.admin.fields.color')
|
22
|
+
%th= t('workarea.admin.fields.image')
|
23
|
+
%th= t('workarea.admin.actions.remove')
|
24
|
+
%tbody
|
25
|
+
- @swatches.each do |swatch|
|
26
|
+
%tr.index-table__row
|
27
|
+
%td= swatch.name
|
28
|
+
%td
|
29
|
+
= form_tag catalog_swatch_path(swatch), method: 'patch' do
|
30
|
+
= color_field_tag 'swatch[hex]', swatch.hex, class: 'color-picker__input', data: { form_submitting_control: '' }, id: nil
|
31
|
+
%td
|
32
|
+
= form_tag catalog_swatch_path(swatch), method: 'patch', multipart: true do
|
33
|
+
= image_tag swatch.image.process(:small).url if swatch.image.present?
|
34
|
+
= file_field_tag 'swatch[image]', class: 'text-box', data: { form_submitting_control: '' }, id: nil
|
35
|
+
%td
|
36
|
+
= form_tag catalog_swatch_path(swatch), method: 'delete', class: 'text-button text-button--destroy' do
|
37
|
+
= button_tag value: 'remove_swatch', class: 'text-button text-button--destroy' do
|
38
|
+
= inline_svg('workarea/admin/icons/delete.svg', class: 'text-button__icon', title: t('workarea.admin.actions.delete'))
|
39
|
+
|
40
|
+
.section
|
41
|
+
.grid
|
42
|
+
.grid__cell.grid__cell--50
|
43
|
+
%h2= t('workarea.admin.catalog_swatches.index.add_new')
|
44
|
+
|
45
|
+
= form_tag catalog_swatches_path, method: 'post', multipart: true do
|
46
|
+
.grid.grid--auto
|
47
|
+
.grid__cell
|
48
|
+
.property.property--required
|
49
|
+
= label_tag 'swatch_name', t('workarea.admin.fields.name'), class: 'property__name'
|
50
|
+
= text_field_tag 'swatch[name]', params.dig(:swatch, :name), class: 'text-box text-box--medium', required: true, id: nil
|
51
|
+
.grid__cell
|
52
|
+
.property
|
53
|
+
= label_tag 'swatch_hex', t('workarea.admin.fields.color'), class: 'property__name'
|
54
|
+
= color_field_tag 'swatch[hex]', params.dig(:swatch, :hex), class: 'color-picker__input', id: nil
|
55
|
+
.grid__cell
|
56
|
+
.property
|
57
|
+
= label_tag 'swatch_image', t('workarea.admin.fields.image'), class: 'property__name'
|
58
|
+
= file_field_tag 'swatch[image]', class: 'text-box text-box--large', id: nil
|
59
|
+
|
60
|
+
= button_tag t('workarea.admin.actions.save'), value: 'save_new_swatch', class: 'button'
|
61
|
+
|
62
|
+
.grid__cell.grid__cell--50
|
63
|
+
%h2= t('workarea.admin.catalog_swatches.index.manage_filters')
|
64
|
+
|
65
|
+
= form_tag search_settings_path, method: 'patch', data: { unsaved_changes: '' } do
|
66
|
+
= hidden_field_tag :return_to, catalog_swatches_path
|
67
|
+
.property
|
68
|
+
= label_tag 'swatch_facets_list', class: 'property__name' do
|
69
|
+
= t('workarea.admin.catalog_swatches.index.swatch_filters')
|
70
|
+
= link_to '#swatch-facets-info', data: { tooltip: '' } do
|
71
|
+
= inline_svg('workarea/admin/icons/help.svg', class: 'svg-icon svg-icon--small svg-icon--blue', title: t('workarea.admin.catalog_swatches.index.swatch_filters'))
|
72
|
+
|
73
|
+
= text_field_tag 'settings[swatch_facets_list]', @search_settings.swatch_facets_list, class: 'text-box'
|
74
|
+
%span.property__note= t('workarea.admin.form.csv_field_note')
|
75
|
+
#swatch-facets-info.tooltip-content
|
76
|
+
%p= t('workarea.admin.catalog_swatches.index.swatch_facets_info')
|
77
|
+
|
78
|
+
= button_tag t('workarea.admin.actions.save'), value: 'save_settings', class: 'button'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
json.type facet.type
|
2
|
+
json.name facet.name
|
3
|
+
json.display_name facet.display_name
|
4
|
+
|
5
|
+
json.results facet.results do |name, count|
|
6
|
+
json.name name
|
7
|
+
json.count count
|
8
|
+
|
9
|
+
@swatches_cache ||= Workarea::Catalog::Swatch.all.to_a
|
10
|
+
swatch = @swatches_cache.detect { |s| s.id == name.systemize }
|
11
|
+
|
12
|
+
if swatch&.image?
|
13
|
+
json.swatch_image swatch.image.process(:facet_swatch).url
|
14
|
+
elsif swatch&.hex?
|
15
|
+
json.swatch_hex swatch.hex
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
%div{ class: "result-filters__section result-filters__section--#{facet.system_name}" }
|
2
|
+
%h2= t('workarea.storefront.products.filter_title', name: facet.display_name)
|
3
|
+
%ul.result-filters__group
|
4
|
+
- facet.results.each do |value_name, count|
|
5
|
+
%li.result-filters__filter{ class: facet.selected?(value_name) ? 'result-filters__filter--selected' : nil }
|
6
|
+
= link_to render_swatch_facet(value_name), facet_path(facet, value_name), rel: 'nofollow', class: 'results-filters__swatch-link'
|
7
|
+
|
8
|
+
= link_to facet_path(facet, value_name), rel: 'nofollow', class: 'result-filters__link' do
|
9
|
+
= value_name.titleize
|
10
|
+
|
11
|
+
- if facet.selected?(value_name)
|
12
|
+
%strong.result-filters__remove= t('workarea.storefront.products.remove_filter')
|
13
|
+
-else
|
14
|
+
%span.result-filters__count (#{count})
|
@@ -0,0 +1,17 @@
|
|
1
|
+
- if product.try(:display_browse_swatches?)
|
2
|
+
.swatch-options.swatch-options--small
|
3
|
+
%ul.swatch-options__group
|
4
|
+
- product.browse_swatch_option.selections.each do |selection|
|
5
|
+
- swatch = product.swatches_by_option[selection.optionize]
|
6
|
+
- swatch_content = render_browse_swatch(selection, swatch)
|
7
|
+
|
8
|
+
- if product.current_browse_selection?(selection)
|
9
|
+
%li.swatch-options__swatch.swatch-options__swatch--selected>
|
10
|
+
= swatch_content
|
11
|
+
- else
|
12
|
+
%li.swatch-options__swatch>
|
13
|
+
- selection_options = option_selection_url_for(product, product.browse_swatch_option, selection)
|
14
|
+
- product_path = product_path(product, product.browse_link_options.merge(selection_options))
|
15
|
+
|
16
|
+
= link_to product_path, title: selection, class: 'swatch-options__swatch-button', data: { product_summary_swatch: { url: summary_product_path(product, selection_options) }.to_json } do
|
17
|
+
= swatch_content
|
@@ -0,0 +1,79 @@
|
|
1
|
+
.grid.grid--rev
|
2
|
+
.grid__cell.grid__cell--60-at-medium
|
3
|
+
|
4
|
+
.product-details__name
|
5
|
+
%h1.product-details__heading{ itemprop: 'name' }= product.name
|
6
|
+
|
7
|
+
%p.product-details__id
|
8
|
+
%span{ itemprop: 'productID' }= product.id
|
9
|
+
|
10
|
+
.product-prices.product-prices--details{ itemprop: 'offers', itemscope: true, itemtype: 'http://schema.org/Offer' }
|
11
|
+
= render 'workarea/storefront/products/pricing', product: product
|
12
|
+
|
13
|
+
= append_partials('storefront.product_pricing_details', product: product)
|
14
|
+
|
15
|
+
- if product.description.present?
|
16
|
+
.product-details__description
|
17
|
+
%p= truncated_product_description(product, t('workarea.storefront.products.read_more'))
|
18
|
+
|
19
|
+
= form_tag cart_items_path, method: 'post', class: 'product-details__add-to-cart-form', data: { dialog_form: { dialogOptions: { closeAll: true, initModules: true } }, analytics: add_to_cart_analytics_data(product).to_json } do
|
20
|
+
= hidden_field_tag :product_id, product.id, id: dom_id(product, 'product_id')
|
21
|
+
= hidden_field_tag :sku, product.current_sku
|
22
|
+
= hidden_field_tag :via, params[:via], id: dom_id(product, 'via')
|
23
|
+
|
24
|
+
- product.options_for_selection.each do |option|
|
25
|
+
.property
|
26
|
+
= label_tag option.slug, nil, class: 'property__name', for: "#{option.slug}_#{dom_id(product)}" do
|
27
|
+
%span.property__text= option_label(option)
|
28
|
+
.value
|
29
|
+
- option.selections.each do |selection|
|
30
|
+
= radio_button_tag option.slug, selection, option.current == selection, required: true, title: selection, class: 'visually-hidden', id: nil
|
31
|
+
= link_to option_selection_url_for(product, option, selection), title: selection, class: "option-button option-button--#{selection.downcase.dasherize}#{' option-button--active' if option.current == selection}", data: { option_button: '' } do
|
32
|
+
- swatch_content = render_swatch_option(selection, product.swatches_by_option[selection.optionize])
|
33
|
+
|
34
|
+
- if swatch_content.present?
|
35
|
+
= swatch_content
|
36
|
+
- elsif product.images_by_option[selection.optionize].present?
|
37
|
+
= image_tag(product_image_url(product.images_by_option[selection.optionize].first, :small_thumb), alt: selection, class: 'option-button__image')
|
38
|
+
- else
|
39
|
+
%span.option-button__text= selection
|
40
|
+
|
41
|
+
- unless product.currently_selected_options.blank?
|
42
|
+
= link_to t('workarea.storefront.products.clear_selections'), product_path(product), data: { option_button: '' }
|
43
|
+
|
44
|
+
= append_partials('storefront.add_to_cart_form', product: product)
|
45
|
+
|
46
|
+
- if product.purchasable?
|
47
|
+
.product-details__quantity
|
48
|
+
.property
|
49
|
+
= label_tag :quantity, nil, class: 'property__name', for: "quantity#{dom_id(product)}" do
|
50
|
+
%span.property__text= t('workarea.storefront.products.quantity')
|
51
|
+
.value
|
52
|
+
= number_field_tag :quantity, params[:quantity] || 1, class: 'text-box text-box--x-small', required: true, min: 1, id: "quantity#{dom_id(product)}"
|
53
|
+
- if product.current_sku.present?
|
54
|
+
.value__note= product.inventory_status
|
55
|
+
|
56
|
+
%p.product-details__add-to-cart-action= button_tag t('workarea.storefront.products.add_to_cart'), value: 'add_to_cart', class: 'button button--large'
|
57
|
+
|
58
|
+
- else
|
59
|
+
= hidden_field_tag :quantity, params[:quantity] || 1, id: "quantity#{dom_id(product)}"
|
60
|
+
%p.product-details__unavailable= t('workarea.storefront.products.unavailable')
|
61
|
+
|
62
|
+
= append_partials('storefront.product_details', product: product)
|
63
|
+
|
64
|
+
%p.product-details__full-details=link_to t('workarea.storefront.products.view_full_details'), product_path(product, color: params[:color]), class: 'text-button', itemprop: 'url'
|
65
|
+
|
66
|
+
.grid__cell.grid__cell--40-at-medium
|
67
|
+
|
68
|
+
.product-details__primary-image
|
69
|
+
= link_to(product_image_url(product.primary_image, :zoom), target: '_blank', rel: 'noopener', class: 'product-details__primary-image-link', data: { dialog_button: '' }) do
|
70
|
+
= image_tag product_image_url(product.primary_image, :detail), alt: t('workarea.storefront.products.image_alt_attribute', name: product.name), itemprop: 'image', class: 'product-details__primary-image-link-image'
|
71
|
+
|
72
|
+
- if product.images.length > 1
|
73
|
+
.product-details__alt-images
|
74
|
+
.grid.grid--auto
|
75
|
+
- product.images.each_with_index do |image, index|
|
76
|
+
.grid__cell
|
77
|
+
.product-details__alt-image
|
78
|
+
- button_class = index == 0 ? 'product-details__alt-image-link product-details__alt-image-link--selected' : 'product-details__alt-image-link'
|
79
|
+
= link_to(image_tag(product_image_url(image, :small_thumb), alt: t('workarea.storefront.products.zoom')), product_image_url(image, :zoom), class: button_class, target: '_blank', rel: 'noopener', data: { alternate_image_button: { src: product_image_url(image, :detail) }.to_json })
|