From 12e685bd923daf20709e59d8e3c8788875ca6a92 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 27 May 2016 16:22:11 +1000 Subject: [PATCH] Restricting number of tags for tag rules to one --- .../tags_with_translation.js.coffee | 7 ++++ .../filter_order_cycles_input.html.haml | 14 +++++-- .../filter_payment_methods_input.html.haml | 14 +++++-- .../tag_rules/filter_products_input.html.haml | 14 +++++-- .../filter_shipping_methods_input.html.haml | 14 +++++-- .../admin/tag_rules/tag_rule.html.haml | 2 +- .../templates/admin/tags_input.html.haml | 4 +- .../stylesheets/admin/tag_rules.css.scss | 8 ++++ .../enterprises/form/_tag_rules.html.haml | 4 +- spec/features/admin/tag_rules_spec.rb | 38 ++++++++++--------- 10 files changed, 80 insertions(+), 39 deletions(-) diff --git a/app/assets/javascripts/admin/utils/directives/tags_with_translation.js.coffee b/app/assets/javascripts/admin/utils/directives/tags_with_translation.js.coffee index a79bc8f87e..9722ab26af 100644 --- a/app/assets/javascripts/admin/utils/directives/tags_with_translation.js.coffee +++ b/app/assets/javascripts/admin/utils/directives/tags_with_translation.js.coffee @@ -7,10 +7,15 @@ angular.module("admin.utils").directive "tagsWithTranslation", ($timeout) -> tagListAttr: "@?" findTags: "&" form: '=?' + onTagAdded: "&" + onTagRemoved: "&" + max: "=" link: (scope, element, attrs) -> scope.findTags = undefined unless attrs.hasOwnProperty("findTags") + scope.limitReached = false compileTagList = -> + scope.limitReached = scope.object[scope.tagsAttr].length >= scope.max if scope.max != undefined scope.object[scope.tagListAttr] = (tag.text for tag in scope.object[scope.tagsAttr]).join(",") $timeout -> @@ -21,10 +26,12 @@ angular.module("admin.utils").directive "tagsWithTranslation", ($timeout) -> compileTagList() scope.tagAdded = -> + scope.onTagAdded() compileTagList() scope.tagRemoved = -> # For some reason the tags input doesn't mark the form # as dirty when a tag is removed, which breaks the save bar scope.form.$setDirty(true) if typeof scope.form isnt 'undefined' + scope.onTagRemoved() compileTagList() diff --git a/app/assets/javascripts/templates/admin/tag_rules/filter_order_cycles_input.html.haml b/app/assets/javascripts/templates/admin/tag_rules/filter_order_cycles_input.html.haml index 5cd8a4400d..fd8dac63c7 100644 --- a/app/assets/javascripts/templates/admin/tag_rules/filter_order_cycles_input.html.haml +++ b/app/assets/javascripts/templates/admin/tag_rules/filter_order_cycles_input.html.haml @@ -1,4 +1,10 @@ -%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_order_cycles_visibility", - name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_order_cycles_visibility]", - ng: { model: "rule.preferred_matched_order_cycles_visibility"}, - data: 'visibilityOptions', "min-search" => 5 } +%div + %input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_order_cycles_visibility", + name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_order_cycles_visibility]", + ng: { model: "rule.preferred_matched_order_cycles_visibility", if: "!rule.is_default" }, + data: 'visibilityOptions', "min-search" => 5 } + %input{ type: "hidden", + id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_order_cycles_visibility", + name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_order_cycles_visibility]", + ng: { value: "'hidden'", if: "rule.is_default" } } + %span.text-normal{ ng: { if: "rule.is_default" } } not visible diff --git a/app/assets/javascripts/templates/admin/tag_rules/filter_payment_methods_input.html.haml b/app/assets/javascripts/templates/admin/tag_rules/filter_payment_methods_input.html.haml index 1446c6bcff..0dd533235d 100644 --- a/app/assets/javascripts/templates/admin/tag_rules/filter_payment_methods_input.html.haml +++ b/app/assets/javascripts/templates/admin/tag_rules/filter_payment_methods_input.html.haml @@ -1,4 +1,10 @@ -%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_payment_methods_visibility", - name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_payment_methods_visibility]", - ng: { model: "rule.preferred_matched_payment_methods_visibility"}, - data: 'visibilityOptions', "min-search" => 5 } +%div + %input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_payment_methods_visibility", + name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_payment_methods_visibility]", + ng: { model: "rule.preferred_matched_payment_methods_visibility", if: "!rule.is_default" }, + data: 'visibilityOptions', "min-search" => 5 } + %input{ type: "hidden", + id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_payment_methods_visibility", + name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_payment_methods_visibility]", + ng: { value: "'hidden'", if: "rule.is_default" } } + %span.text-normal{ ng: { if: "rule.is_default" } } not visible diff --git a/app/assets/javascripts/templates/admin/tag_rules/filter_products_input.html.haml b/app/assets/javascripts/templates/admin/tag_rules/filter_products_input.html.haml index 9326af7d5a..da112c9db2 100644 --- a/app/assets/javascripts/templates/admin/tag_rules/filter_products_input.html.haml +++ b/app/assets/javascripts/templates/admin/tag_rules/filter_products_input.html.haml @@ -1,4 +1,10 @@ -%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_variants_visibility", - name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_variants_visibility]", - ng: { model: "rule.preferred_matched_variants_visibility"}, - data: 'visibilityOptions', "min-search" => 5 } +%div + %input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_variants_visibility", + name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_variants_visibility]", + ng: { model: "rule.preferred_matched_variants_visibility", if: "!rule.is_default" }, + data: 'visibilityOptions', "min-search" => 5 } + %input{ type: "hidden", + id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_variants_visibility", + name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_variants_visibility]", + ng: { value: "'hidden'", if: "rule.is_default" } } + %span.text-normal{ ng: { if: "rule.is_default" } } not visible diff --git a/app/assets/javascripts/templates/admin/tag_rules/filter_shipping_methods_input.html.haml b/app/assets/javascripts/templates/admin/tag_rules/filter_shipping_methods_input.html.haml index af31e93cfa..a46b9abd14 100644 --- a/app/assets/javascripts/templates/admin/tag_rules/filter_shipping_methods_input.html.haml +++ b/app/assets/javascripts/templates/admin/tag_rules/filter_shipping_methods_input.html.haml @@ -1,4 +1,10 @@ -%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_shipping_methods_visibility", - name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_shipping_methods_visibility]", - ng: { model: "rule.preferred_matched_shipping_methods_visibility"}, - data: 'visibilityOptions', "min-search" => 5 } +%div + %input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_shipping_methods_visibility", + name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_shipping_methods_visibility]", + ng: { model: "rule.preferred_matched_shipping_methods_visibility", if: "!rule.is_default" }, + data: 'visibilityOptions', "min-search" => 5 } + %input{ type: "hidden", + id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_shipping_methods_visibility", + name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_shipping_methods_visibility]", + ng: { value: "'hidden'", if: "rule.is_default" } } + %span.text-normal{ ng: { if: "rule.is_default" } } not visible diff --git a/app/assets/javascripts/templates/admin/tag_rules/tag_rule.html.haml b/app/assets/javascripts/templates/admin/tag_rules/tag_rule.html.haml index f3018927c4..4427d284fd 100644 --- a/app/assets/javascripts/templates/admin/tag_rules/tag_rule.html.haml +++ b/app/assets/javascripts/templates/admin/tag_rules/tag_rule.html.haml @@ -38,7 +38,7 @@ %span.text-normal {{ opt[rule.type].textTop }} %td - %tags-with-translation{ object: "rule", "tags-attr" => "{{opt[rule.type].tagsAttr}}", "tag-list-attr" => "{{opt[rule.type].tagListAttr}}" } + %tags-with-translation{ object: "rule", max: 1, "tags-attr" => "{{opt[rule.type].tagsAttr}}", "tag-list-attr" => "{{opt[rule.type].tagListAttr}}" } %td.actions{ rowspan: 2 } %a{ ng: { click: "deleteTagRule(tagGroup, rule)" }, :class => "delete-tag-rule icon-trash no-text" } %tr diff --git a/app/assets/javascripts/templates/admin/tags_input.html.haml b/app/assets/javascripts/templates/admin/tags_input.html.haml index 15a69b650c..3c604b4b15 100644 --- a/app/assets/javascripts/templates/admin/tags_input.html.haml +++ b/app/assets/javascripts/templates/admin/tags_input.html.haml @@ -1,4 +1,6 @@ -%tags-input{ template: 'admin/tag.html', ng: { model: 'object[tagsAttr]' }, on: { tag: { added: 'tagAdded()', removed:'tagRemoved()' } } } +%tags-input{ template: 'admin/tag.html', + ng: { model: 'object[tagsAttr]', class: "{'limit-reached': limitReached}"}, + on: { tag: { added: 'tagAdded()', removed:'tagRemoved()' } } } %auto-complete{ ng: { if: "findTags" }, source: "findTags({query: $query})", template: "admin/tag_autocomplete.html", "min-length" => "0", diff --git a/app/assets/stylesheets/admin/tag_rules.css.scss b/app/assets/stylesheets/admin/tag_rules.css.scss index 7feedb7c50..a4bf6b7b2c 100644 --- a/app/assets/stylesheets/admin/tag_rules.css.scss +++ b/app/assets/stylesheets/admin/tag_rules.css.scss @@ -1,3 +1,11 @@ +tags-input { + &.limit-reached { + input, span.input { + display: none; + } + } +} + .no_tags { margin-bottom: 40px; color: #aeaeae; diff --git a/app/views/admin/enterprises/form/_tag_rules.html.haml b/app/views/admin/enterprises/form/_tag_rules.html.haml index fd34477c6c..e58f7c5a62 100644 --- a/app/views/admin/enterprises/form/_tag_rules.html.haml +++ b/app/views/admin/enterprises/form/_tag_rules.html.haml @@ -16,9 +16,7 @@ %h5 For customers tagged: %td - %tags-input{ ng: { model: 'tagGroup.tags'}, - min: { tags: "1" }, - on: { tag: { added: "updateTagsRulesFor(tagGroup)", removed: "updateTagsRulesFor(tagGroup)" } } } + %tags-with-translation{ object: "tagGroup", max: 1, on: { tag: { added: "updateTagsRulesFor(tagGroup)", removed: "updateTagsRulesFor(tagGroup)" } } } .no_rules{ ng: { show: "tagGroup.rules.length == 0" } } No rules apply to this tag yet diff --git a/spec/features/admin/tag_rules_spec.rb b/spec/features/admin/tag_rules_spec.rb index 7c1aa55f9e..63955de1f8 100644 --- a/spec/features/admin/tag_rules_spec.rb +++ b/spec/features/admin/tag_rules_spec.rb @@ -64,7 +64,7 @@ feature 'Tag Rules', js: true do click_button "Add Rule" within(".default_rules #tr_0") do find(:css, "tags-input .tags input").set "wholesale\n" - select2_select "NOT VISIBLE", from: "enterprise_tag_rules_attributes_0_preferred_matched_order_cycles_visibility" + expect(page).to have_content "not visible" end # New DiscountOrder Rule @@ -128,19 +128,21 @@ feature 'Tag Rules', js: true do expect(page).to have_selector '.customer_tag .header tags-input .tag-list ti-tag-item', text: "local", count: 1 expect(page).to have_selector '.customer_tag .header tags-input .tag-list ti-tag-item', text: "wholesale", count: 1 expect(page).to have_selector '.customer_tag .header tags-input .tag-list ti-tag-item', text: "trusted", count: 1 - all(:css, ".customer_tag .header tags-input .tags input").each { |node| node.set "volunteer\n" } + all(:css, ".customer_tag .header tags-input").each do |node| + node.find("li.tag-item a.remove-button").trigger('click') + node.find(".tags input").set "volunteer\n" + end # DEFAULT FilterShippingMethods rule within ".default_rules #tr_0" do - expect(first('tags-input .tag-list ti-tag-item')).to have_content "local" + within "li.tag-item", text: "local ✖" do find("a.remove-button").trigger('click') end find(:css, "tags-input .tags input").set "volunteers-only\n" - expect(page).to have_select2 "enterprise_tag_rules_attributes_0_preferred_matched_shipping_methods_visibility", selected: 'VISIBLE' - select2_select 'NOT VISIBLE', from: "enterprise_tag_rules_attributes_0_preferred_matched_shipping_methods_visibility" + expect(page).to have_content "not visible" end # FilterProducts rule within ".customer_tag #tr_1" do - expect(first('tags-input .tag-list ti-tag-item')).to have_content "member" + within "li.tag-item", text: "member ✖" do find("a.remove-button").trigger('click') end find(:css, "tags-input .tags input").set "volunteers-only1\n" expect(page).to have_select2 "enterprise_tag_rules_attributes_1_preferred_matched_variants_visibility", selected: 'VISIBLE' select2_select 'NOT VISIBLE', from: "enterprise_tag_rules_attributes_1_preferred_matched_variants_visibility" @@ -148,7 +150,7 @@ feature 'Tag Rules', js: true do # FilterPaymentMethods rule within ".customer_tag #tr_2" do - expect(first('tags-input .tag-list ti-tag-item')).to have_content "trusted" + within "li.tag-item", text: "trusted ✖" do find("a.remove-button").trigger('click') end find(:css, "tags-input .tags input").set "volunteers-only2\n" expect(page).to have_select2 "enterprise_tag_rules_attributes_2_preferred_matched_payment_methods_visibility", selected: 'NOT VISIBLE' select2_select 'VISIBLE', from: "enterprise_tag_rules_attributes_2_preferred_matched_payment_methods_visibility" @@ -156,7 +158,7 @@ feature 'Tag Rules', js: true do # FilterOrderCycles rule within ".customer_tag #tr_3" do - expect(first('tags-input .tag-list ti-tag-item')).to have_content "wholesale" + within "li.tag-item", text: "wholesale ✖" do find("a.remove-button").trigger('click') end find(:css, "tags-input .tags input").set "volunteers-only3\n" expect(page).to have_select2 "enterprise_tag_rules_attributes_3_preferred_matched_order_cycles_visibility", selected: 'VISIBLE' select2_select 'NOT VISIBLE', from: "enterprise_tag_rules_attributes_3_preferred_matched_order_cycles_visibility" @@ -164,7 +166,7 @@ feature 'Tag Rules', js: true do # FilterShippingMethods rule within ".customer_tag #tr_4" do - expect(first('tags-input .tag-list ti-tag-item')).to have_content "local" + within "li.tag-item", text: "local ✖" do find("a.remove-button").trigger('click') end find(:css, "tags-input .tags input").set "volunteers-only4\n" expect(page).to have_select2 "enterprise_tag_rules_attributes_4_preferred_matched_shipping_methods_visibility", selected: 'NOT VISIBLE' select2_select 'VISIBLE', from: "enterprise_tag_rules_attributes_4_preferred_matched_shipping_methods_visibility" @@ -183,31 +185,31 @@ feature 'Tag Rules', js: true do # DEFAULT FilterShippingMethods rule expect(default_fsm_tag_rule.reload.preferred_customer_tags).to eq "" - expect(default_fsm_tag_rule.preferred_shipping_method_tags).to eq "local,volunteers-only" + expect(default_fsm_tag_rule.preferred_shipping_method_tags).to eq "volunteers-only" expect(default_fsm_tag_rule.preferred_matched_shipping_methods_visibility).to eq "hidden" # FilterShippingMethods rule expect(fsm_tag_rule.reload.priority).to eq 1 - expect(fsm_tag_rule.preferred_customer_tags).to eq "local,volunteer" - expect(fsm_tag_rule.preferred_shipping_method_tags).to eq "local,volunteers-only4" + expect(fsm_tag_rule.preferred_customer_tags).to eq "volunteer" + expect(fsm_tag_rule.preferred_shipping_method_tags).to eq "volunteers-only4" expect(fsm_tag_rule.preferred_matched_shipping_methods_visibility).to eq "visible" # FilterProducts rule expect(fp_tag_rule.reload.priority).to eq 2 - expect(fp_tag_rule.preferred_customer_tags).to eq "member,volunteer" - expect(fp_tag_rule.preferred_variant_tags).to eq "member,volunteers-only1" + expect(fp_tag_rule.preferred_customer_tags).to eq "volunteer" + expect(fp_tag_rule.preferred_variant_tags).to eq "volunteers-only1" expect(fp_tag_rule.preferred_matched_variants_visibility).to eq "hidden" # FilterPaymentMethods rule expect(fpm_tag_rule.reload.priority).to eq 3 - expect(fpm_tag_rule.preferred_customer_tags).to eq "trusted,volunteer" - expect(fpm_tag_rule.preferred_payment_method_tags).to eq "trusted,volunteers-only2" + expect(fpm_tag_rule.preferred_customer_tags).to eq "volunteer" + expect(fpm_tag_rule.preferred_payment_method_tags).to eq "volunteers-only2" expect(fpm_tag_rule.preferred_matched_payment_methods_visibility).to eq "visible" # FilterOrderCycles rule expect(foc_tag_rule.reload.priority).to eq 4 - expect(foc_tag_rule.preferred_customer_tags).to eq "wholesale,volunteer" - expect(foc_tag_rule.preferred_exchange_tags).to eq "wholesale,volunteers-only3" + expect(foc_tag_rule.preferred_customer_tags).to eq "volunteer" + expect(foc_tag_rule.preferred_exchange_tags).to eq "volunteers-only3" expect(foc_tag_rule.preferred_matched_order_cycles_visibility).to eq "hidden" # DiscountOrder rule