diff --git a/app/controllers/ops_controller/settings/common.rb b/app/controllers/ops_controller/settings/common.rb index aa16dd8857b..e659bc9c930 100644 --- a/app/controllers/ops_controller/settings/common.rb +++ b/app/controllers/ops_controller/settings/common.rb @@ -859,20 +859,26 @@ def settings_get_info(nodetype = x_node) nodes = nodetype.downcase.split("-") case nodes[0] when "root" + @subtab = -1 @right_cell_text = _("%{product} Region \"%{name}\"") % {:name => "#{MiqRegion.my_region.description} [#{MiqRegion.my_region.region}]", :product => Vmdb::Appliance.PRODUCT_NAME} case @sb[:active_tab] when "settings_details" + @settings_tab = 0 settings_set_view_vars when "settings_cu_collection" # C&U collection settings + @settings_tab = 1 cu_build_edit_screen @in_a_form = true when "settings_tags" + @settings_tab = 2 case @sb[:active_subtab] - when "settings_co_categories" + when "settings_my_company_categories" + @subtab = 0 category_get_all - when "settings_co_tags" + when "settings_my_company_tags" + @subtab = 1 # dont hide the disabled categories, so user can remove tags from the disabled ones cats = Classification.categories.sort_by(&:description) # Get the categories, sort by name @cats = {} # Classifications array for first chooser @@ -882,12 +888,14 @@ def settings_get_info(nodetype = x_node) @cat = cats.first ce_build_screen # Build the Classification Edit screen when "settings_import_tags" + @subtab = 2 @edit = {} @edit[:new] = {} @edit[:key] = "#{@sb[:active_tab]}_edit__#{@sb[:selected_server_id]}" add_flash(_("Locate and upload a file to start the import process"), :info) @in_a_form = true - when "settings_import" # Import tab + when "settings_import_variables" # Import tab + @subtab = 3 @edit = {} @edit[:new] = {} @edit[:key] = "#{@sb[:active_tab]}_edit__#{@sb[:selected_server_id]}" @@ -895,10 +903,14 @@ def settings_get_info(nodetype = x_node) @sb[:good] = nil unless @sb[:show_button] add_flash(_("Choose the type of custom variables to be imported"), :info) @in_a_form = true - when "settings_label_tag_mapping" + when "settings_map_tags" + @subtab = 4 label_tag_mapping_get_all end + when "settings_replication" + @settings_tab = 3 when "settings_help_menu" + @settings_tab = 4 @in_a_form = true @edit = {:new => {}, :key => 'customize_help_menu'} @edit[:new] = Settings.help_menu.to_h @@ -910,6 +922,7 @@ def settings_get_info(nodetype = x_node) session[:edit] = @edit session[:changed] = false when "settings_advanced" + @settings_tab = 5 fetch_advanced_settings(MiqRegion.my_region) end when "xx" diff --git a/app/helpers/ops_helper.rb b/app/helpers/ops_helper.rb index af32760c3da..5c74dca1778 100644 --- a/app/helpers/ops_helper.rb +++ b/app/helpers/ops_helper.rb @@ -9,6 +9,8 @@ module OpsHelper include SettingsLabelTagMappingHelper include SettingsScheduleHelper include SettingsServerDescHelper + include SettingsTabsHelper + include SettingsTagsHelper include SettingsUsersHelper include SettingsZoneHelper include SettingsRbacTagHelper diff --git a/app/helpers/settings_tabs_helper.rb b/app/helpers/settings_tabs_helper.rb new file mode 100644 index 00000000000..411566809d9 --- /dev/null +++ b/app/helpers/settings_tabs_helper.rb @@ -0,0 +1,24 @@ +module SettingsTabsHelper + def settings_tab_configuration + [:details, :cu_collection, :tags, :replication, :help_menu, :advanced] + end + + def settings_tab_content(key_name, &block) + if settings_tabs_types[key_name] + tag.div(:id => "settings_#{key_name}", :class => 'tab_content', &block) + end + end + + private + + def settings_tabs_types + { + :details => _('Details'), + :cu_collection => _('C & U Collection'), + :tags => _('Tags'), + :replication => _('Replication'), + :help_menu => _('Help Menu'), + :advanced => _('Advanced'), + } + end +end diff --git a/app/helpers/settings_tags_helper.rb b/app/helpers/settings_tags_helper.rb new file mode 100644 index 00000000000..639c3f559f2 --- /dev/null +++ b/app/helpers/settings_tags_helper.rb @@ -0,0 +1,23 @@ +module SettingsTagsHelper + def settings_tags_configuration + [:my_company_categories, :my_company_tags, :import_tags, :import_variables, :map_tags] + end + + def settings_tags_content(key_name, &block) + if settings_tags_types[key_name] + tag.div(:id => key_name, :class => 'tab_content', &block) + end + end + + private + + def settings_tags_types + { + :my_company_categories => _('My Company Categories'), + :my_company_tags => _('My Company Tags'), + :import_tags => _('Import Tags'), + :import_variables => _('Import Variables'), + :map_tags => _('Map Tags'), + } + end +end diff --git a/app/javascript/components/miq-custom-tab/helper.js b/app/javascript/components/miq-custom-tab/helper.js index 46bd411bec0..e2e5b99e6ad 100644 --- a/app/javascript/components/miq-custom-tab/helper.js +++ b/app/javascript/components/miq-custom-tab/helper.js @@ -28,6 +28,24 @@ const requestInfo = { network: __('Network'), }; +/** Tab labels used for settings in application settings page. */ +const settings = { + details: __('Details'), + cu_collection: __('C & U Collection'), + tags: __('Tags'), + replication: __('Replication'), + help_menu: __('Help'), + advanced: __('Advanced'), +}; + +const settingsTags = { + my_company_categories: __('My Company Categories'), + my_company_tags: __('My Company Tags'), + import_tags: ('Import Tags'), + import_variables: __('Import Variables'), + map_tags: __('Map Tags'), +} + /** Function to select the tab labels. */ export const labelConfig = (type) => { const configMap = { @@ -35,6 +53,8 @@ export const labelConfig = (type) => { CATALOG_EDIT: catalog, UTILIZATION: utilization, CATALOG_REQUEST_INFO: requestInfo, + SETTINGS: settings, + SETTINGS_TAGS: settingsTags, }; return configMap[type]; diff --git a/app/javascript/components/miq-custom-tab/index.jsx b/app/javascript/components/miq-custom-tab/index.jsx index 54f826ccbd2..e1e180e3a6d 100644 --- a/app/javascript/components/miq-custom-tab/index.jsx +++ b/app/javascript/components/miq-custom-tab/index.jsx @@ -1,13 +1,18 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import { Tabs, Tab } from 'carbon-components-react'; import { useDispatch } from 'react-redux'; import { miqCustomTabActions } from '../../miq-redux/actions/miq-custom-tab-actions'; import { labelConfig, tabText } from './helper'; -const MiqCustomTab = ({ containerId, tabLabels, type }) => { +const MiqCustomTab = ({ + containerId, tabLabels, type, activeTab, subtab +}) => { const dispatch = useDispatch(); const [data, setData] = useState({ loading: false }); + const [currentTab, setCurrentTab] = useState(activeTab); + const activeTabClassName = 'bx--tabs--scrollable__nav-item--selected'; + const selectedClassName = 'bx--tabs__nav-item--selected'; /** Labels used for a Tab found from the 'type'. */ const selectedLabels = labelConfig(type); @@ -23,6 +28,13 @@ const MiqCustomTab = ({ containerId, tabLabels, type }) => { { type: 'CATALOG_EDIT', js: () => name === 'detail' && dispatch(miqCustomTabActions.incrementClickCount()) }, { type: 'CATALOG_REQUEST_INFO', url: `/miq_request/prov_field_changed?tab_id=${name}&edit_mode=true` }, { type: 'UTILIZATION' }, + { + type: 'SETTINGS', + url: name === 'tags' + ? `/ops/change_tab?tab_id=settings_my_company_categories&parent_tab_id=settings_${name}` + : `/ops/change_tab?tab_id=settings_${name}`, + }, + { type: 'SETTINGS_TAGS', url: `/ops/change_tab?parent_tab_id=settings_tags&tab_id=settings_${name}` }, ]; const configuration = (name) => tabConfigurations(name).find((item) => item.type === type); @@ -78,6 +90,10 @@ const MiqCustomTab = ({ containerId, tabLabels, type }) => { /** Function to handle tab click events. */ const onTabSelect = (name) => { + if (name === 'advanced') { + setCurrentTab(5); + } + setData(true); if (!data.loading) { miqSparkleOn(); const config = configuration(name); @@ -91,6 +107,23 @@ const MiqCustomTab = ({ containerId, tabLabels, type }) => { onTabSelect(label)} /> )); + useEffect(() => { + if (activeTab) { + let elements = document.getElementsByClassName('bx--tabs--scrollable__nav-item'); + elements.forEach((element) => { + element.classList.remove(activeTabClassName); + element.classList.remove(selectedClassName); + }); + if (elements.length > 6) { + elements[6].classList.remove(activeTabClassName); + elements[subtab + 6].classList.add(activeTabClassName); + } + elements[currentTab].classList.add(activeTabClassName); + + elements = document.getElementsByClassName('bx--tabs--scrollable__nav-item'); + } + }, [data.loading]); + return ( {renderTabs()} @@ -104,4 +137,11 @@ MiqCustomTab.propTypes = { containerId: PropTypes.string.isRequired, tabLabels: PropTypes.arrayOf(PropTypes.string).isRequired, type: PropTypes.string.isRequired, + activeTab: PropTypes.number, + subtab: PropTypes.number, +}; + +MiqCustomTab.defaultProps = { + activeTab: undefined, + subtab: undefined, }; diff --git a/app/views/ops/_all_tabs.html.haml b/app/views/ops/_all_tabs.html.haml index 27e51d3b70b..8945058c9b7 100644 --- a/app/views/ops/_all_tabs.html.haml +++ b/app/views/ops/_all_tabs.html.haml @@ -52,58 +52,44 @@ = render :partial => "settings_list_tab" - else = render(:partial => "layouts/flash_msg") - %ul.nav.nav-tabs{'role' => 'tablist'} - = miq_tab_header("settings_details", @sb[:active_tab]) do - = _("Details") - = miq_tab_header("settings_cu_collection", @sb[:active_tab]) do - = _("C & U Collection") - = miq_tab_header("settings_tags", @sb[:active_tab]) do - = _("Tags") - = miq_tab_header("settings_replication", @sb[:active_tab]) do - = _("Replication") - = miq_tab_header("settings_help_menu", @sb[:active_tab]) do - = _("Help Menu") - = miq_tab_header("settings_advanced", @sb[:active_tab]) do - = _("Advanced") - .tab-content - = miq_tab_content("settings_details", @sb[:active_tab]) do - = render :partial => "settings_details_tab" - = miq_tab_content("settings_cu_collection", @sb[:active_tab]) do - = render :partial => "settings_cu_collection_tab" - = miq_tab_content("settings_tags", @sb[:active_tab]) do - #ops_tags_subtabs - %ul.nav.nav-tabs.nav-tabs-pf{:style => 'font-size: 12px'} - = miq_tab_header("settings_co_categories", @sb[:active_subtab]) do - = escape_javascript(current_tenant.name) - = _("Categories") - = miq_tab_header("settings_co_tags", @sb[:active_subtab]) do - = escape_javascript(current_tenant.name) - = _("Tags") - = miq_tab_header("settings_import_tags", @sb[:active_subtab]) do - = _("Import Tags") - = miq_tab_header("settings_import", @sb[:active_subtab]) do - = _("Import Variables") - = miq_tab_header("settings_label_tag_mapping", @sb[:active_subtab]) do - = _("Map Tags") - .tab-content - = miq_tab_content("settings_co_categories", @sb[:active_subtab]) do - = render :partial => "settings_co_categories_tab" - = miq_tab_content("settings_co_tags", @sb[:active_subtab]) do - = render :partial => "settings_co_tags_tab" - = miq_tab_content("settings_import_tags", @sb[:active_subtab]) do - = render :partial => "settings_import_tags_tab" - = miq_tab_content("settings_import", @sb[:active_subtab]) do - = render :partial => "settings_import_tab" - = miq_tab_content("settings_label_tag_mapping", @sb[:active_subtab]) do - = render :partial => "settings_label_tag_mapping_tab" - :javascript - miq_tabs_init("#ops_tags_subtabs", "/ops/change_tab", {parent_tab_id: 'settings_tags'}); - = miq_tab_content("settings_replication", @sb[:active_tab]) do - = render :partial => "settings_replication_tab" - = miq_tab_content("settings_help_menu", @sb[:active_tab]) do - = render :partial => "settings_help_menu_tab" - = miq_tab_content("settings_advanced", @sb[:active_tab]) do - = render :partial => "settings_advanced_tab" + #utilization-tabs-wrapper + = react('MiqCustomTab', {:containerId => 'settings-tabs', + :tabLabels => settings_tab_configuration, + :type => 'SETTINGS', + :activeTab => @settings_tab, + }) + #settings-tabs + = settings_tab_content(:details) do + = render :partial => "settings_details_tab" + = settings_tab_content(:cu_collection) do + = render :partial => "settings_cu_collection_tab" + = settings_tab_content(:tags) do + - if @sb[:active_tab] == 'settings_tags' + #ops_tags_subtabs + %ul.nav.nav-tabs.nav-tabs-pf{:style => 'font-size: 12px'} + = react('MiqCustomTab', {:containerId => 'ops_tags_subtabs', + :tabLabels => settings_tags_configuration, + :type => 'SETTINGS_TAGS', + :activeTab => @settings_tab, + :subtab => @subtab, + }) + .tab-content + = settings_tags_content(:my_company_categories) do + = render :partial => "settings_co_categories_tab" + = settings_tags_content(:my_company_tags) do + = render :partial => "settings_co_tags_tab" + = settings_tags_content(:import_tags) do + = render :partial => "settings_import_tags_tab" + = settings_tags_content(:import_variables) do + = render :partial => "settings_import_tab" + = settings_tags_content(:map_tags) do + = render :partial => "settings_label_tag_mapping_tab" + = settings_tab_content(:replication) do + = render :partial => "settings_replication_tab" + = settings_tab_content(:help_menu) do + = render :partial => "settings_help_menu_tab" + = settings_tab_content(:advanced) do + = render :partial => "settings_advanced_tab" -# Diagnostics - when :diagnostics_tree - if x_node.split("-")[0] == "z" diff --git a/app/views/ops/_settings_co_categories_tab.html.haml b/app/views/ops/_settings_co_categories_tab.html.haml index 1f17df6cad8..ba009a7305d 100644 --- a/app/views/ops/_settings_co_categories_tab.html.haml +++ b/app/views/ops/_settings_co_categories_tab.html.haml @@ -1,2 +1,2 @@ -- if @sb[:active_tab] == "settings_tags" && @sb[:active_subtab] == "settings_co_categories" +- if @sb[:active_tab] == "settings_tags" && @sb[:active_subtab] == "settings_my_company_categories" = react('SettingsCompanyCategories', {:initialData => settings_company_categories_list(@categories)}) diff --git a/app/views/ops/_settings_co_tags_tab.html.haml b/app/views/ops/_settings_co_tags_tab.html.haml index 2292457ab76..1e6e1ee048c 100644 --- a/app/views/ops/_settings_co_tags_tab.html.haml +++ b/app/views/ops/_settings_co_tags_tab.html.haml @@ -1,3 +1,3 @@ -- if @sb[:active_tab] == "settings_tags" && @sb[:active_subtab] == "settings_co_tags" +- if @sb[:active_tab] == "settings_tags" && @sb[:active_subtab] == "settings_my_company_tags" #tab_div = react('SettingsCompanyTags', {:pageTitle => "#{current_tenant.name} #{_('Tags')}", :categoryId => @cat.id}) diff --git a/app/views/ops/_settings_import_tab.html.haml b/app/views/ops/_settings_import_tab.html.haml index 6fc33afb2d4..361151cf16f 100644 --- a/app/views/ops/_settings_import_tab.html.haml +++ b/app/views/ops/_settings_import_tab.html.haml @@ -1,4 +1,4 @@ -- if @sb[:active_tab] == "settings_tags" && @sb[:active_subtab] == "settings_import" +- if @sb[:active_tab] == "settings_tags" && @sb[:active_subtab] == "settings_import_variables" - url = url_for_only_path(:action => 'upload_form_field_changed', :id => @sb[:active_tab].split('_').last) %h3= _("Messages") %hr diff --git a/app/views/ops/_settings_label_tag_mapping_tab.html.haml b/app/views/ops/_settings_label_tag_mapping_tab.html.haml index baecaf2e854..e9998c4f324 100644 --- a/app/views/ops/_settings_label_tag_mapping_tab.html.haml +++ b/app/views/ops/_settings_label_tag_mapping_tab.html.haml @@ -1,2 +1,2 @@ -- if @sb[:active_tab] == "settings_tags" && @sb[:active_subtab] == "settings_label_tag_mapping" +- if @sb[:active_tab] == "settings_tags" && @sb[:active_subtab] == "settings_map_tags" = react('SettingsLabelTagMapping', {:initialData => settings_label_tab_mapping_list(@any_mapping_is_all_entities, @lt_mapping)}) diff --git a/spec/controllers/ops_controller_spec.rb b/spec/controllers/ops_controller_spec.rb index 2473853fe92..3d6fc9a77d1 100644 --- a/spec/controllers/ops_controller_spec.rb +++ b/spec/controllers/ops_controller_spec.rb @@ -320,7 +320,6 @@ allow(controller).to receive(:check_privileges).and_return(true) allow(controller).to receive(:assert_privileges).and_return(true) seed_session_trees('ops', :settings_tree, 'root') - expect(controller).to receive(:render_to_string).with(any_args).exactly(3).times post :change_tab, :params => {:tab_id => tab, :parent_tab_id => 'settings_tags'} end