From e18a242b903068121d8bf6fa2d93165ff112f3b2 Mon Sep 17 00:00:00 2001 From: binarygit Date: Tue, 9 Aug 2022 12:58:24 +0545 Subject: [PATCH] Render admin/enterprises//edit page using stimulus --- app/helpers/admin/enterprises_helper.rb | 29 +++++++ app/views/admin/enterprises/_form.html.haml | 78 +++++-------------- .../admin/enterprises/_ng_form.html.haml | 3 +- app/views/admin/shared/_side_menu.html.haml | 14 ++-- .../controllers/tabs_and_panels_controller.js | 40 ++++++++++ .../tabs_and_panels_controller_test.js | 48 ++++++++++++ spec/system/admin/enterprises_spec.rb | 6 +- 7 files changed, 146 insertions(+), 72 deletions(-) create mode 100644 app/webpacker/controllers/tabs_and_panels_controller.js create mode 100644 spec/javascripts/stimulus/tabs_and_panels_controller_test.js diff --git a/app/helpers/admin/enterprises_helper.rb b/app/helpers/admin/enterprises_helper.rb index 59945d274c..e95f4589ed 100644 --- a/app/helpers/admin/enterprises_helper.rb +++ b/app/helpers/admin/enterprises_helper.rb @@ -13,5 +13,34 @@ module Admin def select_only_item(producers) producers.size == 1 ? producers.first.id : nil end + + def enterprise_side_menu_items(enterprise) + is_shop = enterprise.sells != "none" + show_properties = !!enterprise.is_primary_producer + show_shipping_methods = can?(:manage_shipping_methods, enterprise) && is_shop + show_payment_methods = can?(:manage_payment_methods, enterprise) && is_shop + show_enterprise_fees = can?(:manage_enterprise_fees, + enterprise) && (is_shop || enterprise.is_primary_producer) + + [ + { name: 'primary_details', icon_class: "icon-home", show: true, selected: 'selected' }, + { name: 'address', icon_class: "icon-map-marker", show: true }, + { name: 'contact', icon_class: "icon-phone", show: true }, + { name: 'social', icon_class: "icon-twitter", show: true }, + { name: 'about', icon_class: "icon-pencil", show: true, form_name: "about_us" }, + { name: 'business_details', icon_class: "icon-briefcase", show: true }, + { name: 'images', icon_class: "icon-picture", show: true }, + { name: 'properties', icon_class: "icon-tags", show: show_properties }, + { name: 'shipping_methods', icon_class: "icon-truck", show: show_shipping_methods }, + { name: 'payment_methods', icon_class: "icon-money", show: show_payment_methods }, + { name: 'enterprise_fees', icon_class: "icon-tasks", show: show_enterprise_fees }, + { name: 'enterprise_permissions', icon_class: "icon-plug", show: true, + href: admin_enterprise_relationships_path }, + { name: 'inventory_settings', icon_class: "icon-list-ol", show: is_shop }, + { name: 'tag_rules', icon_class: "icon-random", show: is_shop }, + { name: 'shop_preferences', icon_class: "icon-shopping-cart", show: is_shop }, + { name: 'users', icon_class: "icon-user", show: true } + ] + end end end diff --git a/app/views/admin/enterprises/_form.html.haml b/app/views/admin/enterprises/_form.html.haml index 3fc9e9ebaa..75b9109e07 100644 --- a/app/views/admin/enterprises/_form.html.haml +++ b/app/views/admin/enterprises/_form.html.haml @@ -1,63 +1,21 @@ -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='primary_details'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/primary_details', f: f +- enterprise_side_menu_items(@enterprise).each do |item| + - case item[:name] + - when 'primary_details' + %fieldset.alpha.no-border-bottom{ id: "#{item[:name]}_panel", data: { "tabs-and-panels-target": "panel default" }} + %legend= t("#{ item[:name] }") + = render "admin/enterprises/form/#{ item[:form_name] || item[:name] }", f: f -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='users'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/users', f: f + - when 'address' + = f.fields_for :address do |af| + %fieldset.alpha.no-border-bottom{ id: "#{item[:name]}_panel", data: { "tabs-and-panels-target": "panel" }} + %legend= t("#{ item[:name] }") + = render 'admin/enterprises/form/address', af: af -= f.fields_for :address do |af| - %fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='address'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/address', af: af + - when 'enterprise_permissions' + %fieldset.alpha.no-border-bottom{ id: "#{item[:name]}_panel", data: { "tabs-and-panels-target": "panel" }} + %legend= t("#{ item[:name] }") -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='contact'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/contact', f: f - -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='social'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/social', f: f - -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='business_details'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/business_details', f: f - -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='about'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/about_us', f: f - -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='images'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/images', f: f - -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='properties'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/properties', f: f - -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='shipping_methods'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/shipping_methods', f: f - -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='payment_methods'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/payment_methods', f: f - -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='enterprise_fees'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/enterprise_fees', f: f - -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='enterprise_permissions'" } } - %legend {{menu.selected.label}} - -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='inventory_settings'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/inventory_settings', f: f - -%fieldset.alpha.no-border-bottom{ ng: { show: "menu.selected.name=='shop_preferences'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/shop_preferences', f: f - -%fieldset.alpha.no-border-bottom{ ng: { if: "menu.selected.name=='tag_rules'" } } - %legend {{menu.selected.label}} - = render 'admin/enterprises/form/tag_rules', f: f + - else + %fieldset.alpha.no-border-bottom{ id: "#{item[:name]}_panel", data: { "tabs-and-panels-target": "panel" }} + %legend= t("#{ item[:name] }") + = render "admin/enterprises/form/#{ item[:form_name] || item[:name] }", f: f diff --git a/app/views/admin/enterprises/_ng_form.html.haml b/app/views/admin/enterprises/_ng_form.html.haml index 44511d35ec..9dd03271ea 100644 --- a/app/views/admin/enterprises/_ng_form.html.haml +++ b/app/views/admin/enterprises/_ng_form.html.haml @@ -10,7 +10,8 @@ %input.red{ type: "button", value: t(:update), ng: { click: "submit()", disabled: "!enterprise_form.$dirty" } } %input{ type: "button", ng: { value: "enterprise_form.$dirty ? '#{t(:cancel)}' : '#{t(:close)}'", click: "cancel('#{main_app.admin_enterprises_path}')" } } - .row + .row{ data: { + controller: "tabs-and-panels", "tabs-and-panels-class-name-value": "selected" }} .sixteen.columns.alpha .four.columns.alpha = render 'admin/shared/side_menu' diff --git a/app/views/admin/shared/_side_menu.html.haml b/app/views/admin/shared/_side_menu.html.haml index 267a341991..9618e52c45 100644 --- a/app/views/admin/shared/_side_menu.html.haml +++ b/app/views/admin/shared/_side_menu.html.haml @@ -1,8 +1,6 @@ -.side_menu{ ng: { controller: 'sideMenuCtrl' } } - %a.menu_item{ href: "", id: "{{ item.name.toLowerCase().replace(' ', '_') }}", - ng: { repeat: '(index,item) in menu.items | filter:{visible:true}', - click: 'select(index)', - show: '!showItem || showItem(item)', - class: '{ selected: item.selected }' } } - %i{ class: "{{item.icon_class}}" } - %span {{ item.label }} +.side_menu + - enterprise_side_menu_items(@enterprise).each do |item| + - next unless item[:show] + %a.menu_item{ href: item[:href] || "##{item[:name]}_panel", id: item[:name], data: { action: "tabs-and-panels#changeActivePanel tabs-and-panels#changeActiveTab", "tabs-and-panels-target": "tab" }, class: item[:selected] } + %i{ class: item[:icon_class] } + %span= t("#{item[:name] }") diff --git a/app/webpacker/controllers/tabs_and_panels_controller.js b/app/webpacker/controllers/tabs_and_panels_controller.js new file mode 100644 index 0000000000..0a1762cedb --- /dev/null +++ b/app/webpacker/controllers/tabs_and_panels_controller.js @@ -0,0 +1,40 @@ +import { Controller } from "stimulus"; + +export default class extends Controller { + static targets = ["tab", "panel", "default"]; + static values = { className: String }; + + connect() { + // hide all active panel + this.panelTargets.forEach((panel) => { + panel.style.display = "none"; + }); + + // only display the default panel + this.defaultTarget.style.display = "block"; + } + + changeActivePanel(event) { + const newActivePanel = this.panelTargets.find( + (panel) => panel.id == `${event.currentTarget.id}_panel` + ); + + this.currentActivePanel.style.display = "none"; + newActivePanel.style.display = "block"; + } + + changeActiveTab(event) { + this.currentActiveTab.classList.remove(`${this.classNameValue}`); + event.currentTarget.classList.add(`${this.classNameValue}`); + } + + get currentActiveTab() { + return this.tabTargets.find((tab) => tab.classList.contains("selected")); + } + + get currentActivePanel() { + return this.panelTargets.find( + (panel) => panel.id == `${this.currentActiveTab.id}_panel` + ); + } +} diff --git a/spec/javascripts/stimulus/tabs_and_panels_controller_test.js b/spec/javascripts/stimulus/tabs_and_panels_controller_test.js new file mode 100644 index 0000000000..8fdfedd117 --- /dev/null +++ b/spec/javascripts/stimulus/tabs_and_panels_controller_test.js @@ -0,0 +1,48 @@ +/** + * @jest-environment jsdom + */ + +import { Application } from "stimulus"; +import tabs_and_panels_controller from "../../../app/webpacker/controllers/tabs_and_panels_controller"; + +describe("EnterprisePanelController", () => { + beforeAll(() => { + const application = Application.start(); + application.register("tabs-and-panels", tabs_and_panels_controller); + }); + + describe("#tabs-and-panels", () => { + beforeEach(() => { + document.body.innerHTML = ` +
+ Peek + Ka + Boo + + +
Peek me
+
Ka you
+
Boo three
+
`; + }); + + it("displays only the default panel", () => { + const peekPanel = document.getElementById("peek_panel"); + const kaPanel = document.getElementById("ka_panel"); + const booPanel = document.getElementById("boo_panel"); + + expect(peekPanel.style.display).toBe("block"); + expect(kaPanel.style.display).toBe("none"); + expect(booPanel.style.display).toBe("none"); + }); + + it("displays appropriate panel when associated tab is clicked", () => { + const kaPanel = document.getElementById("ka_panel"); + const ka = document.getElementById("ka"); + + expect(kaPanel.style.display).toBe("none"); + ka.click(); + expect(kaPanel.style.display).toBe("block"); + }); + }); +}); diff --git a/spec/system/admin/enterprises_spec.rb b/spec/system/admin/enterprises_spec.rb index 00c244e7b2..9a892505b5 100644 --- a/spec/system/admin/enterprises_spec.rb +++ b/spec/system/admin/enterprises_spec.rb @@ -108,7 +108,7 @@ describe ' description_input = page.find("text-angular#enterprise_long_description div[id^='taTextElement']") description_input.native.send_keys('This is an interesting long description') - # Check Angularjs switching of sidebar elements + # Check StimulusJs switching of sidebar elements accept_alert do click_link "Primary Details" end @@ -485,7 +485,7 @@ describe ' end choose "enterprise_preferred_shopfront_product_sorting_method_by_category" - find("#s2id_autogen7").click + find("#s2id_enterprise_preferred_shopfront_taxon_order").click find(".select2-result-label", text: "Tricky Taxon").click click_button 'Update' expect(flash_message).to eq('Enterprise "First Distributor" has been successfully updated!') @@ -506,7 +506,7 @@ describe ' end choose "enterprise_preferred_shopfront_product_sorting_method_by_producer" - find("#s2id_autogen8").click + find("#s2id_enterprise_preferred_shopfront_producer_order").click find(".select2-result-label", text: "First Supplier").click click_button 'Update' expect(flash_message).to eq('Enterprise "First Distributor" has been successfully updated!')