workarea-package_products 3.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +20 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  4. data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  6. data/.gitignore +15 -0
  7. data/CHANGELOG.md +343 -0
  8. data/CODE_OF_CONDUCT.md +3 -0
  9. data/CONTRIBUTING.md +3 -0
  10. data/Gemfile +16 -0
  11. data/LICENSE +52 -0
  12. data/README.md +40 -0
  13. data/Rakefile +52 -0
  14. data/app/assets/javascripts/workarea/storefront/package_products/modules/family_product_add_to_cart.js +83 -0
  15. data/app/assets/javascripts/workarea/storefront/package_products/templates/family_add_to_cart_checkbox.jst.ejs +1 -0
  16. data/app/assets/stylesheets/workarea/admin/package_products/components/_product_cards.scss +7 -0
  17. data/app/assets/stylesheets/workarea/storefront/package_products/components/_product_detail_packaged_products.scss +11 -0
  18. data/app/controllers/workarea/admin/create_catalog_package_products_controller.rb +150 -0
  19. data/app/controllers/workarea/admin/create_catalog_products_controller.decorator +25 -0
  20. data/app/controllers/workarea/storefront/cart_items_controller.decorator +29 -0
  21. data/app/controllers/workarea/storefront/products_controller.decorator +8 -0
  22. data/app/models/workarea/catalog/product.decorator +44 -0
  23. data/app/models/workarea/search/admin/catalog_product.decorator +20 -0
  24. data/app/models/workarea/search/storefront/package_product.rb +40 -0
  25. data/app/queries/workarea/search/product_entries.decorator +8 -0
  26. data/app/seeds/workarea/package_product_seeds.rb +41 -0
  27. data/app/services/workarea/add_package_to_cart.rb +79 -0
  28. data/app/view_models/workarea/admin/product_view_model.decorator +35 -0
  29. data/app/view_models/workarea/storefront/product_templates/family_view_model.rb +6 -0
  30. data/app/view_models/workarea/storefront/product_templates/package_view_model.rb +33 -0
  31. data/app/view_models/workarea/storefront/product_view_model.decorator +13 -0
  32. data/app/views/workarea/admin/catalog_products/_create_package_button.html.haml +1 -0
  33. data/app/views/workarea/admin/catalog_products/_packaged_products_card.html.haml +26 -0
  34. data/app/views/workarea/admin/create_catalog_package_products/categorization.html.haml +64 -0
  35. data/app/views/workarea/admin/create_catalog_package_products/content.html.haml +54 -0
  36. data/app/views/workarea/admin/create_catalog_package_products/details.html.haml +87 -0
  37. data/app/views/workarea/admin/create_catalog_package_products/images.html.haml +57 -0
  38. data/app/views/workarea/admin/create_catalog_package_products/packaged_products.html.haml +79 -0
  39. data/app/views/workarea/admin/create_catalog_package_products/publish.html.haml +61 -0
  40. data/app/views/workarea/admin/create_catalog_package_products/setup.html.haml +68 -0
  41. data/app/views/workarea/admin/create_catalog_products/select.html.haml +34 -0
  42. data/app/views/workarea/storefront/cart_items/package.html.haml +59 -0
  43. data/app/views/workarea/storefront/products/package_show.html.haml +49 -0
  44. data/app/views/workarea/storefront/products/templates/_family.html.haml +42 -0
  45. data/app/views/workarea/storefront/products/templates/_package.html.haml +36 -0
  46. data/app/workers/workarea/update_package_products.rb +21 -0
  47. data/bin/rails +16 -0
  48. data/config/initializers/appends.rb +31 -0
  49. data/config/initializers/configuration.rb +6 -0
  50. data/config/initializers/seeds.rb +1 -0
  51. data/config/locales/en.yml +45 -0
  52. data/config/routes.rb +30 -0
  53. data/lib/tasks/sample_data.rake +16 -0
  54. data/lib/workarea/package_products.rb +10 -0
  55. data/lib/workarea/package_products/engine.rb +8 -0
  56. data/lib/workarea/package_products/version.rb +5 -0
  57. data/test/dummy/Rakefile +6 -0
  58. data/test/dummy/app/assets/config/manifest.js +4 -0
  59. data/test/dummy/app/assets/images/.keep +0 -0
  60. data/test/dummy/app/assets/javascripts/application.js +13 -0
  61. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  62. data/test/dummy/app/controllers/application_controller.rb +3 -0
  63. data/test/dummy/app/controllers/concerns/.keep +0 -0
  64. data/test/dummy/app/helpers/application_helper.rb +2 -0
  65. data/test/dummy/app/jobs/application_job.rb +2 -0
  66. data/test/dummy/app/mailers/application_mailer.rb +4 -0
  67. data/test/dummy/app/models/concerns/.keep +0 -0
  68. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  69. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  70. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  71. data/test/dummy/bin/bundle +3 -0
  72. data/test/dummy/bin/rails +4 -0
  73. data/test/dummy/bin/rake +4 -0
  74. data/test/dummy/bin/setup +34 -0
  75. data/test/dummy/bin/update +29 -0
  76. data/test/dummy/config.ru +5 -0
  77. data/test/dummy/config/application.rb +18 -0
  78. data/test/dummy/config/boot.rb +5 -0
  79. data/test/dummy/config/cable.yml +9 -0
  80. data/test/dummy/config/environment.rb +5 -0
  81. data/test/dummy/config/environments/development.rb +54 -0
  82. data/test/dummy/config/environments/production.rb +83 -0
  83. data/test/dummy/config/environments/test.rb +43 -0
  84. data/test/dummy/config/initializers/application_controller_renderer.rb +6 -0
  85. data/test/dummy/config/initializers/assets.rb +11 -0
  86. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  87. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  88. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  89. data/test/dummy/config/initializers/inflections.rb +16 -0
  90. data/test/dummy/config/initializers/mime_types.rb +4 -0
  91. data/test/dummy/config/initializers/session_store.rb +3 -0
  92. data/test/dummy/config/initializers/workarea.rb +5 -0
  93. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  94. data/test/dummy/config/locales/en.yml +23 -0
  95. data/test/dummy/config/puma.rb +47 -0
  96. data/test/dummy/config/routes.rb +5 -0
  97. data/test/dummy/config/secrets.yml +22 -0
  98. data/test/dummy/db/seeds.rb +2 -0
  99. data/test/dummy/lib/assets/.keep +0 -0
  100. data/test/dummy/log/.keep +0 -0
  101. data/test/dummy/public/404.html +67 -0
  102. data/test/dummy/public/422.html +67 -0
  103. data/test/dummy/public/500.html +66 -0
  104. data/test/dummy/public/apple-touch-icon-precomposed.png +0 -0
  105. data/test/dummy/public/apple-touch-icon.png +0 -0
  106. data/test/dummy/public/favicon.ico +1 -0
  107. data/test/integration/workarea/admin/create_catalog_package_products_integration_test.rb +139 -0
  108. data/test/integration/workarea/storefront/package_cart_items_integration_test.rb +47 -0
  109. data/test/integration/workarea/storefront/products_integration_test.decorator +19 -0
  110. data/test/models/workarea/catalog/package_product_test.rb +68 -0
  111. data/test/models/workarea/search/storefront/package_product_test.rb +44 -0
  112. data/test/queries/workarea/search/product_entries_test.decorator +15 -0
  113. data/test/services/workarea/add_package_to_cart_test.rb +46 -0
  114. data/test/system/workarea/admin/activity_system_test.decorator +53 -0
  115. data/test/system/workarea/admin/package_product_copy_system_test.rb +27 -0
  116. data/test/system/workarea/admin/package_products_system_test.rb +101 -0
  117. data/test/system/workarea/admin/product_copy_system_test.decorator +28 -0
  118. data/test/system/workarea/admin/products_system_test.decorator +69 -0
  119. data/test/system/workarea/storefront/categories_with_packages_system_test.rb +172 -0
  120. data/test/system/workarea/storefront/family_product_system_test.rb +58 -0
  121. data/test/system/workarea/storefront/package_product_system_test.rb +42 -0
  122. data/test/test_helper.rb +10 -0
  123. data/test/view_models/workarea/admin/package_product_view_model_test.rb +41 -0
  124. data/test/view_models/workarea/storefront/package_product_view_model_test.rb +27 -0
  125. data/test/view_models/workarea/storefront/package_templates/package_view_model_test.rb +34 -0
  126. data/test/workers/workarea/update_package_products_test.rb +27 -0
  127. data/workarea-package_products.gemspec +24 -0
  128. metadata +189 -0
@@ -0,0 +1,29 @@
1
+ module Workarea
2
+ decorate Storefront::CartItemsController, with: :package_products do
3
+
4
+ decorated do
5
+ skip_before_action :verify_authenticity_token, only: [:create, :package]
6
+ after_action :check_inventory, except: [:create, :package]
7
+ end
8
+
9
+ def package
10
+ add_to_cart = AddPackageToCart.new(current_order, params)
11
+
12
+ if add_to_cart.save
13
+ check_inventory
14
+ Pricing.perform(current_order, current_shipping)
15
+
16
+ order_items = add_to_cart.items.map do |item|
17
+ current_order.items.find_existing(
18
+ item.item_params[:sku],
19
+ item.item_params[:customizations]
20
+ )
21
+ end.compact
22
+
23
+ @items = order_items.map do |item|
24
+ Storefront::OrderItemViewModel.wrap(item, view_model_options)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,8 @@
1
+ module Workarea
2
+ decorate Storefront::ProductsController, with: :package_products do
3
+ def show
4
+ super
5
+ render 'package_show' and return if @product.package? && !request.xhr?
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,44 @@
1
+ module Workarea
2
+ decorate Catalog::Product, with: :package_products do
3
+ decorated do
4
+ include FeaturedProducts
5
+
6
+ scope :packages_containing, ->(id) { where('product_ids' => id) }
7
+
8
+ # For all products that have the given SKU return an Array containing:
9
+ # * the matching product
10
+ # * the package products that contain the matching product
11
+ #
12
+ # @param sku [String]
13
+ # @return [Array<Catalog::Product>]
14
+ #
15
+ def self.find_for_update_by_sku(sku)
16
+ where('variants.sku' => sku).flat_map do |product|
17
+ [product] + packages_containing(product.id)
18
+ end
19
+ end
20
+ end
21
+
22
+ def package?
23
+ template == 'package' || product_ids.present?
24
+ end
25
+
26
+ def family?
27
+ template == 'family'
28
+ end
29
+
30
+ def active?
31
+ attribute = if Workarea.config.localized_active_fields
32
+ read_attribute(:active)[I18n.locale.to_s]
33
+ else
34
+ read_attribute(:active)
35
+ end
36
+
37
+ attribute && (variants.active.any? || product_ids.present?)
38
+ end
39
+
40
+ def purchasable?
41
+ super && !package?
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ module Workarea
2
+ decorate Search::Admin::CatalogProduct, with: :package_products do
3
+ def search_text
4
+ super.tap do |text|
5
+ text << 'package' if model.package?
6
+ text << 'family' if model.family?
7
+ end
8
+ end
9
+
10
+ def issues
11
+ super.tap do |issues|
12
+ if model.package?
13
+ # issues << 'No Packaged Products' if model.product_ids.blank?
14
+ issues.delete('No Variants')
15
+ issues.delete('SKU missing price')
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,40 @@
1
+ module Workarea
2
+ module Search
3
+ class Storefront
4
+ class PackageProduct < Product
5
+ def skus
6
+ packaged_products.flat_map(&:skus)
7
+ end
8
+
9
+ def variant_count
10
+ packaged_products.sum(&:variant_count)
11
+ end
12
+
13
+ def orders_score
14
+ return 0 unless packaged_products.present?
15
+ packaged_products.sum(&:orders_score) / packaged_products.size
16
+ end
17
+
18
+ def variant_details_text
19
+ @variant_details_text ||= packaged_products_variants.map do |variant|
20
+ "#{variant.name} #{HashText.new(variant.details).text}"
21
+ end.join(' ')
22
+ end
23
+
24
+ private
25
+
26
+ def packaged_products
27
+ return @packaged_products if defined?(@packaged_products)
28
+
29
+ products = Catalog::Product.find_ordered(model.product_ids)
30
+ @packaged_products ||= products.map { |p| Product.new(p) }
31
+ end
32
+
33
+ def packaged_products_variants
34
+ @package_products_variants ||=
35
+ packaged_products.map(&:model).flat_map { |p| p.variants.active }
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,8 @@
1
+ module Workarea
2
+ decorate Search::ProductEntries, with: :package_products do
3
+ def index_entries_for(product)
4
+ return Search::Storefront::PackageProduct.new(product) if product.package?
5
+ super
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,41 @@
1
+ module Workarea
2
+ class PackageProductSeeds
3
+ def perform
4
+ puts 'Adding package products...'
5
+
6
+ 10.times do
7
+ package = create_product
8
+
9
+ category = Workarea::Catalog::Category.sample
10
+ category.product_ids.push(package.id)
11
+ category.save!
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def create_product
18
+ Sidekiq::Callbacks.disable do
19
+ model = Workarea::Catalog::Product.new
20
+ packaged_products =
21
+ Workarea::Catalog::Product.sample(4).reject(&:package?)
22
+
23
+ model.id = rand(1_000_000)
24
+ model.name = "Package Product #{rand(100_000)}"
25
+ model.template = Workarea.config.package_product_templates.sample
26
+ model.product_ids = packaged_products.map(&:id)
27
+
28
+ model.filters = packaged_products.each_with_object({}) do |product, package_filters|
29
+ product.filters.each do |filter_name, values|
30
+ package_filters[filter_name] ||= []
31
+ package_filters[filter_name].concat(Array(values)).uniq!
32
+ end
33
+ end
34
+
35
+ model.description = Faker::Lorem.paragraph
36
+ model.save!
37
+ model
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,79 @@
1
+ module Workarea
2
+ class AddPackageToCart
3
+ attr_reader :items
4
+
5
+ def initialize(order, params)
6
+ @items = []
7
+
8
+ # ActionController::Parameters has no #map
9
+ params[:items].each do |_, item|
10
+ @items << Item.new(order, item)
11
+ end
12
+ end
13
+
14
+ def save
15
+ items.all?(&:save)
16
+ end
17
+
18
+ def errors
19
+ items.flat_map(&:errors)
20
+ end
21
+
22
+ class Item
23
+ attr_reader :order, :params
24
+
25
+ def initialize(order, params)
26
+ @order = order
27
+ @params = params
28
+ end
29
+
30
+ def errors
31
+ @errors ||= []
32
+ end
33
+
34
+ def valid?
35
+ (!customizations.present? || customizations.valid?).tap do |valid|
36
+ customizations.errors.full_messages unless valid
37
+ end
38
+ end
39
+
40
+ def save
41
+ return false unless valid?
42
+ order.add_item(item_params)
43
+ end
44
+
45
+ def item_params
46
+ params
47
+ .permit(:product_id, :sku, :quantity)
48
+ .merge(customizations: customizations)
49
+ .merge(item_details)
50
+ end
51
+
52
+ private
53
+
54
+ def product_id
55
+ @product_id ||= if params[:product_id].present?
56
+ params[:product_id]
57
+ elsif params[:sku].present?
58
+ Catalog::Product.find_by_sku(params[:sku]).id
59
+ end
60
+ end
61
+
62
+ def customizations
63
+ @customizations ||= Catalog::Customizations.find(product_id, params)
64
+ end
65
+
66
+ def customization_params
67
+ ActionController::Parameters.new(
68
+ customizations.try(:to_h) || {}
69
+ )
70
+ end
71
+
72
+ def item_details
73
+ ActionController::Parameters.new(
74
+ OrderItemDetails.find!(params[:sku]).to_h
75
+ ).permit!
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,35 @@
1
+ module Workarea
2
+ decorate Admin::ProductViewModel, with: :package_products do
3
+ decorated do
4
+ include Admin::FeaturedProductsViewModel
5
+ end
6
+
7
+ def packaged_products
8
+ @packaged_products ||=
9
+ begin
10
+ models = Catalog::Product.find_ordered_for_display(
11
+ model.product_ids
12
+ )
13
+ Admin::ProductViewModel.wrap(models)
14
+ end
15
+ end
16
+
17
+ def package_templates
18
+ Workarea.config.package_product_templates
19
+ .map(&:to_s)
20
+ .map do |template_name|
21
+ [template_name.titleize, template_name.optionize]
22
+ end
23
+ end
24
+
25
+ def templates
26
+ return super unless model.present?
27
+
28
+ if package?
29
+ package_templates
30
+ else
31
+ super.reject { |o| o.in?(package_templates) }
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,6 @@
1
+ module Workarea
2
+ module Storefront
3
+ class ProductTemplates::FamilyViewModel < ProductTemplates::PackageViewModel
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,33 @@
1
+ module Workarea
2
+ module Storefront
3
+ class ProductTemplates::PackageViewModel < ProductViewModel
4
+ delegate :has_price_range?, :price, :display_min_price,
5
+ :display_max_price, :display_price, :has_msrp_range?,
6
+ :msrp?, :msrp, :msrp_min, :msrp_max, :sale_starts_at,
7
+ :sale_ends_at, to: :pricing
8
+
9
+ def primary_image
10
+ product_image = super
11
+ return product_image unless product_image.placeholder?
12
+
13
+ @primary_image ||=
14
+ packaged_products
15
+ .map(&:images)
16
+ .flatten
17
+ .reject(&:placeholder?)
18
+ .first ||
19
+ Catalog::ProductPlaceholderImage.cached
20
+ end
21
+
22
+ def show_panel?
23
+ false
24
+ end
25
+
26
+ def pricing
27
+ @pricing ||=
28
+ options[:pricing] ||
29
+ Pricing::Collection.new(packaged_products.map(&:skus).flatten)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ module Workarea
2
+ decorate Storefront::ProductViewModel, with: :package_products do
3
+ def packaged_products
4
+ @packaged_products ||= begin
5
+ return [] if product_ids.blank?
6
+
7
+ models = Catalog::Product.find_ordered_for_display(product_ids)
8
+ models.map { |p| Storefront::ProductViewModel.wrap(p, options) }
9
+ .select { |p| p.variants.any? }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1 @@
1
+ .grid__cell= link_to t('workarea.admin.catalog_products.index.add_new_package_product'), create_catalog_package_products_path, id: 'add_product', class: 'workflow-bar__button workflow-bar__button--create'
@@ -0,0 +1,26 @@
1
+ - if model.package? || model.family?
2
+ .grid__cell
3
+ .card{ class: card_classes(:featured_products, local_assigns[:active]) }
4
+ = link_to select_featured_product_path(model.to_global_id), class: 'card__header' do
5
+ %span.card__header-text= t('workarea.admin.catalog_products.cards.packaged_products.title')
6
+ = inline_svg 'workarea/admin/icons/featured_products.svg', class: 'card__icon'
7
+
8
+ - if local_assigns[:active].blank?
9
+ .card__body
10
+ - if model.packaged_products.empty?
11
+ .card__empty-note
12
+ %p= t('workarea.admin.catalog_products.cards.packaged_products.empty')
13
+ %p= t('workarea.admin.catalog_products.cards.packaged_products.description')
14
+ = link_to select_featured_product_path(model.to_global_id), class: 'card__button' do
15
+ %span.button.button--small= t('workarea.admin.catalog_products.cards.packaged_products.empty_button')
16
+ - else
17
+ %ol.grid
18
+ - model.packaged_products.take(4).each_with_index do |product, i|
19
+ %li.grid__cell.grid__cell--50
20
+ .card__photo-box
21
+ - if i == 3 && model.packaged_products.size > 4
22
+ %span.card__photo +#{model.packaged_products.size - i}
23
+ - else
24
+ = image_tag product_image_url(product.primary_image, :medium), alt: product.name, class: 'card__photo'
25
+ = link_to edit_featured_product_path(model.to_global_id), class: 'card__button' do
26
+ %span.button.button--small= t('workarea.admin.catalog_products.cards.packaged_products.button')
@@ -0,0 +1,64 @@
1
+ - @page_title = t('workarea.admin.create_catalog_products.categorization.page_title', product_name: @product.name)
2
+
3
+ .view
4
+ .view__header
5
+ .view__heading
6
+ %h1.heading.heading--no-margin= t('workarea.admin.create_catalog_products.categorization.categorize', product_name: @product.name)
7
+ %p= link_to t('workarea.admin.create_catalog_products.categorization.or_skip_this'), publish_create_catalog_package_product_path(@product)
8
+
9
+ .view__container.view__container--narrow
10
+ .grid.grid--center.grid--huge
11
+ .grid__cell.grid__cell--50-at-medium
12
+ %h2.align-center= t('workarea.admin.create_catalog_products.categorization.by_matching_category_rules')
13
+
14
+ - if @product.rules_categories.blank?
15
+ %p.align-center= t('workarea.admin.create_catalog_products.categorization.doesnt_match_any_categorys_rules')
16
+ - else
17
+ %ul.list-reset.align-center
18
+ - @product.rules_categories.each do |category|
19
+ %li
20
+ %strong= link_to category.name, catalog_category_path(category)
21
+
22
+ .grid__cell.grid__cell--50-at-medium
23
+ %h2.align-center= t('workarea.admin.create_catalog_products.categorization.by_being_featured')
24
+
25
+ - if @product.featured_categories.blank?
26
+ %p.align-center= t('workarea.admin.create_catalog_products.categorization.not_featured_in_any_categories_yet')
27
+ - else
28
+ %ul.list-reset.align-center
29
+ - @product.featured_categories.each do |category|
30
+ %li
31
+ %strong= link_to category.name, catalog_category_path(category)
32
+ = link_to catalog_product_categorization_path(@product, category), data: { remote: true, method: 'delete', dom_remove: 'li' } do
33
+ = inline_svg('workarea/admin/icons/delete.svg', class: 'svg-icon svg-icon--small svg-icon--red', title: t('workarea.admin.actions.remove'))
34
+
35
+ .section
36
+ = form_tag save_categorization_create_catalog_package_product_path(@product), method: 'post', class: 'align-center' do
37
+ = select_tag 'category_ids[]', nil, multiple: true, data: { remote_select: { source: catalog_categories_path, options: { placeholder: 'Feature in categories...' } }.to_json }
38
+ = button_tag t('workarea.admin.create_catalog_products.categorization.save'), value: 'add_categories', class: 'button button--small'
39
+
40
+ .workflow-bar
41
+ .grid.grid--middle
42
+ .grid__cell.grid__cell--20
43
+ = link_to t('workarea.admin.create_catalog_products.categorization.cancel'), catalog_product_path(@product), class: 'workflow-bar__button workflow-bar__button--delete', data: { method: 'delete', confirm: t('workarea.admin.create_catalog_products.are_you_sure_all_work_on_this_product_will_be_lost') }
44
+
45
+ .grid__cell.grid__cell--60
46
+ %ol.workflow-bar__steps
47
+ %li.workflow-bar__step
48
+ 1) #{link_to t('workarea.admin.create_catalog_products.steps.setup'), edit_create_catalog_package_product_path(@product)}
49
+ %li.workflow-bar__step
50
+ 2) #{link_to t('workarea.admin.create_catalog_package_products.steps.packaged_products'), packaged_products_create_catalog_package_product_path(@product)}
51
+ %li.workflow-bar__step
52
+ 3) #{link_to t('workarea.admin.create_catalog_products.steps.images'), images_create_catalog_package_product_path(@product)}
53
+ %li.workflow-bar__step
54
+ 4) #{link_to t('workarea.admin.create_catalog_products.steps.details'), details_create_catalog_package_product_path(@product)}
55
+ %li.workflow-bar__step
56
+ 5) #{link_to t('workarea.admin.create_catalog_products.steps.content'), content_create_catalog_package_product_path(@product)}
57
+ %li.workflow-bar__step
58
+ %strong 6) #{t('workarea.admin.create_catalog_products.steps.categorization')}
59
+ %li.workflow-bar__step
60
+ 7) #{t('workarea.admin.create_catalog_products.steps.publish')}
61
+
62
+ .grid__cell.grid__cell--20
63
+ .grid.grid--auto.grid--right.grid--middle
64
+ .grid__cell= link_to "#{t('workarea.admin.create_catalog_products.categorization.continue_to_publish')} →", publish_create_catalog_package_product_path(@product), class: 'workflow-bar__button'