workarea-product_additional_details 0.0.0 → 2.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be13c908ad82859fbb0828351fab50a8dd2c9b224837696c340a17785a2caa74
4
- data.tar.gz: 5c6eb0fb3ac0baaf6da83afbb790437684616038f606a9fd2fae276e19260ec3
3
+ metadata.gz: 4d24293b5ecd598ce1e4f81865b0e2a5939f5bf47a9eac646edcbf6c4566c811
4
+ data.tar.gz: 1205a137f548433a39144e38d687b31fdcd736beaf969b410112f4631b28a05d
5
5
  SHA512:
6
- metadata.gz: a2ad0cf2c1e7ea9ea5af7efd362dcc0d116704a994e19d8b85f77141d53c4c1e3c3c8d8132b2c626ebb7475b33ff1c4664d377590f5bbac77318ed2a5dd2d8c5
7
- data.tar.gz: 2a220464e42c9137035ca1a29feab91f2e4aca932951cc2e0a98641a348f0662a855ac0f6a8958aca63abacd02ebf7a7bd0a9f74f5483235efa8a84a6b11edd5
6
+ metadata.gz: 21774ab5b8904169c5cd6d8647ad0e30ff81f450812f08fd74cc089597eda3db214255a185af211600051fb28b56d7c661ef130083bb5a1dad3f1b441243197d
7
+ data.tar.gz: 822bb52bb0bc63d8abf23065c71aaac1f60e761d6f6207784cd9d112838ed2f1205e019c424846bd88ee760fb33171455f692465e4fd2c29356197e8c07373b5
@@ -0,0 +1,54 @@
1
+ /*------------------------------------*\
2
+ #TABLES
3
+ \*------------------------------------*/
4
+
5
+ $table-border-color: $border-color !default;
6
+
7
+ $table-header-color: $dark-gray !default;
8
+ $table-cell-color: $font-color !default;
9
+
10
+ $table-row-hover-bg-color: $light-gray !default;
11
+
12
+
13
+ /**
14
+ * 1. various types of content will be found wrapped in paragraph tags within
15
+ * tables
16
+ */
17
+ table {
18
+ margin-bottom: $vertical-margin;
19
+ width: 100%;
20
+ border-collapse: collapse;
21
+
22
+ p { /* [1] */
23
+ margin: 0;
24
+ }
25
+
26
+ p + p { /* [1] */
27
+ margin-top: $spacing-unit;
28
+ }
29
+ }
30
+
31
+
32
+ tr {
33
+ tbody &:hover {
34
+ background: $table-row-hover-bg-color;
35
+ }
36
+ }
37
+
38
+ th, td {
39
+ padding: $spacing-unit;
40
+ text-align: left;
41
+ border-bottom: 1px solid $table-border-color;
42
+ vertical-align: baseline;
43
+ .bottom-align & {
44
+ vertical-align: top;
45
+ }
46
+ }
47
+
48
+ th {
49
+ color: $table-header-color;
50
+ }
51
+
52
+ td {
53
+ color: $table-cell-color;
54
+ }
@@ -0,0 +1,33 @@
1
+ module Workarea
2
+ decorate Admin::CatalogProductsController, with: :product_additional_details do
3
+ decorated do
4
+ # Place code to decorate here that would normally go on the class
5
+ # level, e.g.:
6
+ #
7
+ # field :name, type: String
8
+ end
9
+
10
+ class_methods do
11
+ # Place methods to define on the class level here. These methods
12
+ # will be available by calling Admin::CatalogProductsController.your_method. Do
13
+ # not prefix these methods with `self.`
14
+ end
15
+
16
+ def update
17
+ set_additional_details
18
+ super
19
+ end
20
+
21
+ def set_additional_details
22
+ @product.additional_details = HashUpdate.new(
23
+ original: @product.additional_details,
24
+ adds: params[:new_additional_details],
25
+ updates: params[:additional_details],
26
+ removes: params[:additional_details_to_remove]
27
+ ).result_grouped
28
+ end
29
+ # Instance methods can go right in the main definition of the
30
+ # decorator, as it is a module that gets prepended into the class of
31
+ # your choice.
32
+ end
33
+ end
@@ -0,0 +1,27 @@
1
+ module Workarea
2
+ decorate Admin::CatalogVariantsController, with: :product_additional_details do
3
+
4
+ def update
5
+ @variant = @product.variants.find(params[:id])
6
+ set_details
7
+ set_additional_details
8
+
9
+ if @variant.update_attributes(params[:variant])
10
+ flash[:success] = t('workarea.admin.catalog_variants.flash_messages.saved')
11
+ redirect_to catalog_product_variants_path(@product)
12
+ else
13
+ flash[:error] = t('workarea.admin.catalog_variants.flash_messages.changes_error')
14
+ render :edit
15
+ end
16
+ end
17
+
18
+ def set_additional_details
19
+ @variant.additional_details = HashUpdate.new(
20
+ original: @product.additional_details,
21
+ adds: params[:new_additional_details],
22
+ updates: params[:additional_details],
23
+ removes: params[:additional_details_to_remove]
24
+ ).result_grouped
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ module Workarea
2
+ decorate Admin::CreateCatalogProductsController, with: :product_additional_details do
3
+ def save_details
4
+ @product.additional_details = HashUpdate
5
+ .new(original: @product.additional_details, updates: params[:additional_details])
6
+ .result_grouped
7
+ super
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ module Workarea
2
+ decorate Catalog::Product, with: :product_additional_details do
3
+ decorated do
4
+ field :additional_details, type: Hash, default: {}, localize: true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Workarea
2
+ decorate Catalog::Variant, with: :product_additional_details do
3
+ decorated do
4
+ field :additional_details, type: Hash, default: {}, localize: true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,93 @@
1
+ module Workarea
2
+ module Search
3
+ class Storefront
4
+ class Product
5
+ module Text
6
+ def catalog_content
7
+ [model.browser_title, model.meta_description, model.description]
8
+ .reject(&:blank?)
9
+ .join(' ')
10
+ end
11
+
12
+ # A list of category names to which this product belongs,
13
+ # allows finding products by category names in search.
14
+ #
15
+ # @return [String]
16
+ #
17
+ def category_names
18
+ categorization.to_models.map(&:name).join(', ')
19
+ end
20
+
21
+ # A textual version of the product's filters hash that
22
+ # will be stored and analyzed in the search index.
23
+ #
24
+ # @return [String]
25
+ #
26
+ def facets_content
27
+ HashText.new(model.filters).text
28
+ end
29
+
30
+ # A textual version of the product's filters hash that
31
+ # will be stored and analyzed in the search index.
32
+ #
33
+ # @return [String]
34
+ #
35
+ def details_content
36
+ "#{HashText.new(model.details).text} #{variant_details_text} #{additional_details_content}"
37
+ end
38
+
39
+ # Text from the product's details hash and it's variants' details
40
+ # hash. Allows finding a product by one of these values.
41
+ #
42
+ # @return [String]
43
+ #
44
+ def details
45
+ "#{HashText.new(model.details).text} #{variant_details_text} #{additional_details_content}"
46
+ end
47
+
48
+ # Text from additional details hash
49
+ def additional_details_content
50
+ if model.additional_details.present? && model.additional_details.any?
51
+ parse_addtional_details(model.additional_details)
52
+ end
53
+ end
54
+
55
+ # Content to put in the index for making search query suggestions.
56
+ # Includes all content for the product.
57
+ #
58
+ # @return [String]
59
+ #
60
+ def suggestion_content
61
+ [
62
+ model.name,
63
+ category_names,
64
+ facets_content,
65
+ details_content
66
+ ].join(' ')
67
+ end
68
+
69
+ def variant_details_text
70
+ @variant_details_text ||= model.variants.active.map do |variant|
71
+ "#{variant.name} #{HashText.new(variant.details).text}"
72
+ end.join(' ')
73
+ end
74
+
75
+ private
76
+ # extract text content from html content
77
+ def parse_addtional_details(details)
78
+ parsed_data = []
79
+ details.each do |key, value|
80
+ data = Nokogiri::HTML.parse(value) if value.is_a?(String)
81
+ if data.present?
82
+ data.traverse do |node|
83
+ parsed_data.push(node.text)
84
+ end
85
+ end
86
+ end
87
+ parsed_data.flatten.compact.uniq.join(" ")
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,43 @@
1
+ module Workarea
2
+ decorate HashUpdate, with: :product_additional_details do
3
+ decorated do
4
+ # Place code to decorate here that would normally go on the class
5
+ # level, e.g.:
6
+ #
7
+ # field :name, type: String
8
+ end
9
+
10
+ class_methods do
11
+ # Place methods to define on the class level here. These methods
12
+ # will be available by calling HashUpdate.your_method. Do
13
+ # not prefix these methods with `self.`
14
+ end
15
+
16
+ def result_grouped
17
+ apply_to_grouped(@original.deep_dup)
18
+ end
19
+
20
+ private
21
+
22
+ def apply_to_grouped(hash)
23
+ @adds.each do |tuple|
24
+ key, value = *tuple
25
+ hash[key] = value
26
+ end
27
+
28
+ @updates.each do |tuple|
29
+ key, value = *tuple
30
+ hash[key] = value
31
+ end
32
+
33
+ @removes.each do |key|
34
+ hash.delete(key)
35
+ end
36
+
37
+ hash.delete_if { |k, v| k.blank? || v.blank? }
38
+ end
39
+ # Instance methods can go right in the main definition of the
40
+ # decorator, as it is a module that gets prepended into the class of
41
+ # your choice.
42
+ end
43
+ end
@@ -0,0 +1,31 @@
1
+ .section.section--additional-details
2
+ %h2= "Additional Details"
3
+
4
+ %table
5
+ %thead
6
+ %tr
7
+ %th= t('workarea.admin.catalog_products.edit.details.name')
8
+ %th= "Content"
9
+ %th.align-center= t('workarea.admin.actions.delete')
10
+ %tbody.bottom-align
11
+ - product.additional_details.each do |name, value|
12
+ %tr
13
+ %td
14
+ .property
15
+ = label_tag "details_#{name}" do
16
+ #{name}
17
+ %td
18
+ .property
19
+ = hidden_field_tag 'additional_details[]', name, id: nil
20
+ = text_area_tag 'additional_details[]', value, class: 'text-box text-box--i18n', id: nil
21
+ %td.align-center= check_box_tag 'additional_details_to_remove[]', name, false, id: nil, title: "#{t('workarea.admin.actions.delete')}: #{name} #{value}"
22
+ %tr{ data: { cloneable_row: '' } }
23
+ %td
24
+ .property
25
+ = text_field_tag 'new_additional_details[]', nil, id: nil, class: 'text-box text-box--i18n', title: t('workarea.admin.catalog_products.edit.details.new_attribute_name'), placeholder: t('workarea.admin.catalog_products.edit.details.new_attribute_name_placeholder')
26
+ %span.property__note= "Example: User Manual"
27
+ %td
28
+ .property
29
+ = text_area_tag 'new_additional_details[]', nil, id: nil, class: 'text-box text-box--i18n', title: t('workarea.admin.catalog_products.edit.details.new_attribute_value'), placeholder: t('workarea.admin.catalog_products.edit.details.new_attribute_value_placeholder')
30
+ %span.property__note= "Example: <a href='/manuals'>Download Manuals</a>"
31
+ %td.align-center -
@@ -0,0 +1,31 @@
1
+ .section.section--additional-details
2
+ %h2= "Additional Details"
3
+
4
+ %table
5
+ %thead
6
+ %tr
7
+ %th= t('workarea.admin.catalog_products.edit.details.name')
8
+ %th= "Content"
9
+ %th.align-center= t('workarea.admin.actions.delete')
10
+ %tbody.bottom-align
11
+ - variant.additional_details.each do |name, value|
12
+ %tr
13
+ %td
14
+ .property
15
+ = label_tag "details_#{name}" do
16
+ #{name}
17
+ %td
18
+ .property
19
+ = hidden_field_tag 'additional_details[]', name, id: nil
20
+ = text_area_tag 'additional_details[]', value, class: 'text-box text-box--i18n', id: nil
21
+ %td.align-center= check_box_tag 'additional_details_to_remove[]', name, false, id: nil, title: "#{t('workarea.admin.actions.delete')}: #{name} #{value}"
22
+ %tr{ data: { cloneable_row: '' } }
23
+ %td
24
+ .property
25
+ = text_field_tag 'new_additional_details[]', nil, id: nil, class: 'text-box text-box--i18n', title: t('workarea.admin.catalog_products.edit.details.new_attribute_name'), placeholder: t('workarea.admin.catalog_products.edit.details.new_attribute_name_placeholder')
26
+ %span.property__note= "Example: User Manual"
27
+ %td
28
+ .property
29
+ = text_area_tag 'new_additional_details[]', nil, id: nil, class: 'text-box text-box--i18n', title: t('workarea.admin.catalog_products.edit.details.new_attribute_value'), placeholder: t('workarea.admin.catalog_products.edit.details.new_attribute_value_placeholder')
30
+ %span.property__note= "Example: <a href='/manuals'>Download Manuals</a>"
31
+ %td.align-center -
@@ -0,0 +1,114 @@
1
+ - @page_title = t('workarea.admin.create_catalog_products.details.page_title', product_name: @product.name)
2
+
3
+ .view
4
+ .view__header
5
+ .grid.grid--right
6
+ .grid__cell.grid__cell--50
7
+ .view__heading
8
+ %h1.heading.heading--no-margin= t('workarea.admin.create_catalog_products.details.add_details', product_name: @product.name)
9
+ %p= link_to t('workarea.admin.create_catalog_products.details.or_skip_this'), content_create_catalog_product_path(@product)
10
+ .grid__cell.grid__cell--25
11
+ = render_aux_navigation_for(@product, html_options: { target: @product.id })
12
+
13
+ .view__container.view__container--narrow
14
+ = form_tag save_details_create_catalog_product_path(@product), method: 'post' do
15
+ .grid.grid--huge
16
+ .grid__cell.grid__cell--50-at-medium
17
+ .section
18
+ %h2= t('workarea.admin.create_catalog_products.details.filters')
19
+
20
+ %table
21
+ %tbody
22
+ - @filters.each do |name, value|
23
+ %tr
24
+ %td
25
+ .property
26
+ = text_field_tag 'filters[]', name, class: 'text-box text-box--i18n', title: 'New Filter Name', placeholder: 'Name', pattern: Workarea.config.product_filter_input_validation_pattern, id: nil
27
+ %td
28
+ .property
29
+ = text_field_tag 'filters[]', hash_editing_value(value), class: 'text-box text-box--i18n', title: 'New Filter Value', placeholder: 'Value', id: nil
30
+
31
+ %tr{ data: { cloneable_row: '' } }
32
+ %td
33
+ .property
34
+ = text_field_tag 'filters[]', nil, class: 'text-box text-box--i18n', title: 'New Filter Name', placeholder: 'Name', pattern: Workarea.config.product_filter_input_validation_pattern, id: nil
35
+ %span.property__note= t('workarea.admin.create_catalog_products.details.example_color')
36
+ %td
37
+ .property
38
+ = text_field_tag 'filters[]', nil, class: 'text-box text-box--i18n', title: 'New Filter Value', placeholder: 'Value', id: nil
39
+ %span.property__note= t('workarea.admin.create_catalog_products.details.comma_separated_red_green')
40
+
41
+ .grid__cell.grid__cell--50-at-medium
42
+ .section
43
+ %h2= t('workarea.admin.create_catalog_products.details.details')
44
+
45
+ %table
46
+ %tbody
47
+ - @product.details.each do |name, value|
48
+ %tr
49
+ %td
50
+ .property
51
+ = text_field_tag 'details[]', name, class: 'text-box text-box--i18n', title: 'Name', placeholder: 'Name', id: nil
52
+ %td
53
+ .property
54
+ = text_field_tag 'details[]', hash_editing_value(value), class: 'text-box text-box--i18n', title: 'Value', placeholder: 'Value', id: nil
55
+ %tr{ data: { cloneable_row: '' } }
56
+ %td
57
+ .property
58
+ = text_field_tag 'details[]', nil, class: 'text-box text-box--i18n', title: 'Name', placeholder: 'Name', id: nil
59
+ %span.property__note= t('workarea.admin.create_catalog_products.details.example_manufactured')
60
+ %td
61
+ .property
62
+ = text_field_tag 'details[]', nil, class: 'text-box text-box--i18n', title: 'Value', placeholder: 'Value', id: nil
63
+ %span.property__note= t('workarea.admin.create_catalog_products.details.example_usa')
64
+
65
+ .grid__cell
66
+ .section
67
+ %h2= "Additional Details"
68
+
69
+ %table
70
+ %tbody.bottom-align
71
+ - @product.additional_details.each do |name, value|
72
+ %tr
73
+ %td
74
+ .property
75
+ = text_field_tag 'additional_details[]', name, class: 'text-box text-box--i18n', title: 'Name', placeholder: 'Name', id: nil
76
+ %td
77
+ .property
78
+ = text_area_tag 'additional_details[]', hash_editing_value(value), class: 'text-box text-box--i18n', title: 'Value', placeholder: 'Value', id: nil
79
+ %tr{ data: { cloneable_row: '' } }
80
+ %td
81
+ .property
82
+ = text_field_tag 'additional_details[]', nil, class: 'text-box text-box--i18n', title: 'Name', placeholder: 'Name', id: nil
83
+ %span.property__note= "Example: User Manual"
84
+ %td
85
+ .property
86
+ = text_area_tag 'additional_details[]', nil, class: 'text-box text-box--i18n', title: 'Value', placeholder: 'Value', id: nil
87
+ %span.property__note= "Example: <a href='/manuals'>Download Manuals</a>"
88
+
89
+ .workflow-bar
90
+ .grid.grid--middle
91
+ .grid__cell.grid__cell--20
92
+ = link_to t('workarea.admin.create_catalog_products.details.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') }
93
+
94
+ .grid__cell.grid__cell--60
95
+
96
+ %ol.workflow-bar__steps
97
+ %li.workflow-bar__step
98
+ 1) #{link_to t('workarea.admin.create_catalog_products.steps.setup'), edit_create_catalog_product_path(@product)}
99
+ %li.workflow-bar__step
100
+ 2) #{link_to t('workarea.admin.create_catalog_products.steps.variants'), variants_create_catalog_product_path(@product)}
101
+ %li.workflow-bar__step
102
+ 2) #{link_to t('workarea.admin.create_catalog_products.steps.images'), images_create_catalog_product_path(@product)}
103
+ %li.workflow-bar__step
104
+ %strong 4) #{t('workarea.admin.create_catalog_products.steps.details')}
105
+ %li.workflow-bar__step
106
+ 5) #{t('workarea.admin.create_catalog_products.steps.content')}
107
+ %li.workflow-bar__step
108
+ 6) #{t('workarea.admin.create_catalog_products.steps.categorization')}
109
+ %li.workflow-bar__step
110
+ 7) #{t('workarea.admin.create_catalog_products.steps.publish')}
111
+
112
+ .grid__cell.grid__cell--20
113
+ .grid.grid--auto.grid--right.grid--middle
114
+ = button_tag t('workarea.admin.create_catalog_products.details.save_details_and_continue'), value: 'save_details', class: 'workflow-bar__button workflow-bar__button--create'
@@ -0,0 +1,8 @@
1
+ Workarea.append_partials(
2
+ 'admin.additional_product_details_information',
3
+ 'workarea/admin/catalog_products/additional_details'
4
+ )
5
+ Workarea.append_partials(
6
+ 'admin.additional_variant_information_fields',
7
+ 'workarea/admin/catalog_variants/additional_details'
8
+ )
@@ -1,5 +1,5 @@
1
1
  module Workarea
2
2
  module ProductAdditionalDetails
3
- VERSION = "0.0.0".freeze
3
+ VERSION = "2.0.3".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ decorate Catalog::ProductTest, with: :product_additional_details do
5
+ # Define additional tests based on new functionality or
6
+ # override tests originally defined in the decorated class for
7
+ # changes that alter default behavior.
8
+ #
9
+ # While calling super to extend a test case is possible, it is
10
+ # recommended that you add a new test or completely override an
11
+ # existing test to avoid ambiguity in your test suite.
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ decorate UserTest, with: :product_additional_details do
5
+ # Define additional tests based on new functionality or
6
+ # override tests originally defined in the decorated class for
7
+ # changes that alter default behavior.
8
+ #
9
+ # While calling super to extend a test case is possible, it is
10
+ # recommended that you add a new test or completely override an
11
+ # existing test to avoid ambiguity in your test suite.
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ decorate HashUpdateTest, with: :product_additional_details do
5
+ # Define additional tests based on new functionality or
6
+ # override tests originally defined in the decorated class for
7
+ # changes that alter default behavior.
8
+ #
9
+ # While calling super to extend a test case is possible, it is
10
+ # recommended that you add a new test or completely override an
11
+ # existing test to avoid ambiguity in your test suite.
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: workarea-product_additional_details
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gunasekaran Raja
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-24 00:00:00.000000000 Z
11
+ date: 2020-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: workarea
@@ -41,14 +41,26 @@ files:
41
41
  - app/assets/images/workarea/storefront/product_additional_details/.keep
42
42
  - app/assets/javascripts/workarea/admin/product_additional_details/.keep
43
43
  - app/assets/javascripts/workarea/storefront/product_additional_details/.keep
44
+ - app/assets/stylesheets/workarea/admin/base/_tables.scss
44
45
  - app/assets/stylesheets/workarea/admin/product_additional_details/.keep
45
46
  - app/assets/stylesheets/workarea/storefront/product_additional_details/.keep
46
47
  - app/controllers/.keep
48
+ - app/controllers/workarea/admin/catalog_products_controller.decorator
49
+ - app/controllers/workarea/admin/catalog_variants_controller.decorator
50
+ - app/controllers/workarea/admin/create_catalog_products_controller.decorator
47
51
  - app/helpers/.keep
48
52
  - app/mailers/.keep
49
53
  - app/models/.keep
54
+ - app/models/workarea/catalog/product.decorator
55
+ - app/models/workarea/catalog/variant.decorator
56
+ - app/models/workarea/search/storefront/product/text.rb
57
+ - app/services/workarea/hash_update.decorator
50
58
  - app/views/.keep
59
+ - app/views/workarea/admin/catalog_products/_additional_details.html.haml
60
+ - app/views/workarea/admin/catalog_variants/_additional_details.html.haml
61
+ - app/views/workarea/admin/create_catalog_products/details.html.haml
51
62
  - bin/rails
63
+ - config/initializers/appends.rb
52
64
  - config/initializers/workarea.rb
53
65
  - config/routes.rb
54
66
  - lib/workarea/product_additional_details.rb
@@ -96,8 +108,11 @@ files:
96
108
  - test/dummy/db/seeds.rb
97
109
  - test/dummy/lib/assets/.keep
98
110
  - test/dummy/log/.keep
111
+ - test/models/workarea/catalog/product_test.decorator
112
+ - test/models/workarea/user_test.decorator
99
113
  - test/teaspoon_env.rb
100
114
  - test/test_helper.rb
115
+ - test/workarea/hash_update_test.decorator
101
116
  - workarea-product_additional_details.gemspec
102
117
  homepage: https://github.com/trikatechnologies/workarea-product_additional_details
103
118
  licenses: