From e204a91c7d832f0b4c7059f23f7b9e0027e65126 Mon Sep 17 00:00:00 2001 From: Aday Bujeda Date: Tue, 8 Nov 2022 14:56:48 +0000 Subject: [PATCH] Added Custom pages feature --- apps/dashboard/app/apps/nav_bar.rb | 13 +++++++ .../controllers/custom_pages_controller.rb | 13 +++++++ .../app/models/user_configuration.rb | 3 ++ .../app/views/custom_pages/index.html.erb | 13 +++++++ apps/dashboard/config/locales/en.yml | 5 ++- apps/dashboard/config/routes.rb | 3 ++ apps/dashboard/test/apps/nav_bar_test.rb | 13 +++++++ .../custom_pages_controller_test.rb | 28 ++++++++++++++ .../views/widgets/_custom_pages_test.html.erb | 1 + .../custom_pages_integration_test.rb | 37 +++++++++++++++++++ .../test/models/user_configuration_test.rb | 1 + 11 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 apps/dashboard/app/controllers/custom_pages_controller.rb create mode 100644 apps/dashboard/app/views/custom_pages/index.html.erb create mode 100644 apps/dashboard/test/controllers/custom_pages_controller_test.rb create mode 100644 apps/dashboard/test/fixtures/config/views/widgets/_custom_pages_test.html.erb create mode 100644 apps/dashboard/test/integration/custom_pages_integration_test.rb diff --git a/apps/dashboard/app/apps/nav_bar.rb b/apps/dashboard/app/apps/nav_bar.rb index c4d8122728..0cfe5063f4 100644 --- a/apps/dashboard/app/apps/nav_bar.rb +++ b/apps/dashboard/app/apps/nav_bar.rb @@ -24,6 +24,8 @@ def self.items(nav_config) extend_link(matched_apps.first.links.first) if matched_apps.first && matched_apps.first.links.first elsif nav_item.fetch(:profile, nil) extend_link(nav_profile(nav_item, nil, nil)) + elsif nav_item.fetch(:page, nil) + extend_link(nav_page(nav_item, nil, nil)) end end end.flatten.compact @@ -47,6 +49,8 @@ def self.nav_menu(hash_item) nav_apps(item, menu_title, group_title) elsif item.fetch(:profile, nil) nav_profile(item, menu_title, group_title) + elsif item.fetch(:page, nil) + nav_page(item, menu_title, group_title) else # Update subcategory if title was provided group_title = item.fetch(:group, group_title) @@ -81,6 +85,15 @@ def self.nav_profile(item, category, subcategory) OodAppLink.new(profile_data).categorize(category: category, subcategory: subcategory) end + def self.nav_page(item, category, subcategory) + page_code = item.fetch(:page) + page_data = item.clone + page_data[:title] = page_code.titleize unless page_data.fetch(:title, nil) + page_data[:url] = Rails.application.routes.url_helpers.custom_pages_path(page_code) + page_data[:new_tab] = false unless page_data.fetch(:new_tab, nil) + OodAppLink.new(page_data).categorize(category: category, subcategory: subcategory) + end + def self.item_from_token(token) static_link_template = STATIC_LINKS.fetch(token.to_sym, nil) if static_link_template diff --git a/apps/dashboard/app/controllers/custom_pages_controller.rb b/apps/dashboard/app/controllers/custom_pages_controller.rb new file mode 100644 index 0000000000..6db0efcd94 --- /dev/null +++ b/apps/dashboard/app/controllers/custom_pages_controller.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# The controller to add new pages with layouts and widgets based on configuration. +# +# It uses a page_code coming from the URL to determine which layout to use. +# If the page_code does not match a configuration object, an error message is displayed. +class CustomPagesController < ApplicationController + def index + page_code = params[:page_code] + @page_layout = @user_configuration.custom_pages.fetch(page_code.to_sym, {}) + flash.now[:alert] = t('dashboard.custom_pages.invalid', page: page_code) if @page_layout.blank? + end +end diff --git a/apps/dashboard/app/models/user_configuration.rb b/apps/dashboard/app/models/user_configuration.rb index 7909dafcbd..84b4eeb632 100644 --- a/apps/dashboard/app/models/user_configuration.rb +++ b/apps/dashboard/app/models/user_configuration.rb @@ -64,6 +64,9 @@ class UserConfiguration # New navigation definition properties ConfigurationProperty.property(name: :nav_bar, default_value: []), ConfigurationProperty.property(name: :help_bar, default_value: []), + + # Custom pages configuration property + ConfigurationProperty.property(name: :custom_pages, default_value: {}), ].freeze def initialize(request_hostname: nil) diff --git a/apps/dashboard/app/views/custom_pages/index.html.erb b/apps/dashboard/app/views/custom_pages/index.html.erb new file mode 100644 index 0000000000..3c357653e7 --- /dev/null +++ b/apps/dashboard/app/views/custom_pages/index.html.erb @@ -0,0 +1,13 @@ +<%= javascript_include_tag 'dashboard', nonce: true %> + +<%- @page_layout.fetch(:rows, []).each do |row| -%> +
+ <%- row.fetch(:columns, []).each do |col| -%> +
+ <%- Array(col.fetch(:widgets, [])).each do |widget| -%> + <%= render_widget(widget.to_s) %> + <%- end -%> +
+ <%- end -%> +
+<%- end -%> \ No newline at end of file diff --git a/apps/dashboard/config/locales/en.yml b/apps/dashboard/config/locales/en.yml index 986050de3d..83aaa69063 100644 --- a/apps/dashboard/config/locales/en.yml +++ b/apps/dashboard/config/locales/en.yml @@ -226,4 +226,7 @@ en: attachments_js: "Max attachment size is %{max}. Selected file size is %{size}" rt: - creation_success: "Support ticket created in RequestTracker system. TicketId: %{ticket_id}" \ No newline at end of file + creation_success: "Support ticket created in RequestTracker system. TicketId: %{ticket_id}" + + custom_pages: + invalid: "Invalid page code: %{page}. This page has not been configured" diff --git a/apps/dashboard/config/routes.rb b/apps/dashboard/config/routes.rb index 2642260e0f..226e667953 100644 --- a/apps/dashboard/config/routes.rb +++ b/apps/dashboard/config/routes.rb @@ -95,6 +95,9 @@ post "/support", to: "support_ticket#create" end + # Custom pages route + get "/custom/:page_code", to: "custom_pages#index", as: :custom_pages + match "/404", :to => "errors#not_found", :via => :all match "/500", :to => "errors#internal_server_error", :via => :all diff --git a/apps/dashboard/test/apps/nav_bar_test.rb b/apps/dashboard/test/apps/nav_bar_test.rb index ee9eaf9328..771d832e84 100644 --- a/apps/dashboard/test/apps/nav_bar_test.rb +++ b/apps/dashboard/test/apps/nav_bar_test.rb @@ -130,6 +130,19 @@ def setup assert_equal false, result[0].new_tab? end + test "NavBar.items should return navigation page when nav_item has page property" do + nav_item = { + title: "Page Title", + page: "page_code" + } + result = NavBar.items([nav_item]) + assert_equal 1, result.size + assert_equal "layouts/nav/link", result[0].partial_path + assert_equal "Page Title", result[0].title + assert_equal "/custom/page_code", result[0].url + assert_equal false, result[0].new_tab? + end + test "NavBar.items should return navigation link when nav_item has app property" do nav_item = { apps: "sys/bc_jupyter" diff --git a/apps/dashboard/test/controllers/custom_pages_controller_test.rb b/apps/dashboard/test/controllers/custom_pages_controller_test.rb new file mode 100644 index 0000000000..f2e9765403 --- /dev/null +++ b/apps/dashboard/test/controllers/custom_pages_controller_test.rb @@ -0,0 +1,28 @@ +require "test_helper" + +class CustomPagesControllerTest < ActiveSupport::TestCase + + test "index should set flash message if page_code configuration is not found" do + target = CustomPagesController.new + target.instance_variable_set(:@user_configuration, stub("user_configuration", {custom_pages: {}})) + target.stubs(:params).returns({page_code: "not_found_page"}) + flash = ActionDispatch::Request.empty.flash + target.stubs(:flash).returns(flash) + target.expects(:t).with("dashboard.custom_pages.invalid", {:page => "not_found_page"}) + + target.index + end + + test "index should not set flash message if page_code configuration is found" do + page_config = { + rows: [] + } + target = CustomPagesController.new + target.instance_variable_set(:@user_configuration, stub("user_configuration", {custom_pages: {test_page: page_config}})) + target.stubs(:params).returns({page_code: "test_page"}) + target.expects(:flash).times(0) + + target.index + end + +end \ No newline at end of file diff --git a/apps/dashboard/test/fixtures/config/views/widgets/_custom_pages_test.html.erb b/apps/dashboard/test/fixtures/config/views/widgets/_custom_pages_test.html.erb new file mode 100644 index 0000000000..8b6d04d090 --- /dev/null +++ b/apps/dashboard/test/fixtures/config/views/widgets/_custom_pages_test.html.erb @@ -0,0 +1 @@ +

Custom Pages Test Widget

\ No newline at end of file diff --git a/apps/dashboard/test/integration/custom_pages_integration_test.rb b/apps/dashboard/test/integration/custom_pages_integration_test.rb new file mode 100644 index 0000000000..a5add85986 --- /dev/null +++ b/apps/dashboard/test/integration/custom_pages_integration_test.rb @@ -0,0 +1,37 @@ +require 'test_helper' + +class CustomPagesIntegrationTest < ActionDispatch::IntegrationTest + + test "should render configured page layout" do + stub_user_configuration({ + custom_pages: { + docs: { + rows: [ + {columns: [ + { + widgets: 'custom_pages_test' + } + ]}, + {columns: [ + { + width: 8, + widgets: 'custom_pages_test' + } + ]} + ] + } + } + }) + + get custom_pages_path(page_code: "docs") + + assert :success + assert_select 'div.row', 2 + assert_select 'div.row > div.col-md-12', 1 + assert_select 'div.row > div.col-md-12 > h3', text: "Extended Pages Test Widget" + assert_select 'div.row > div.col-md-8', 1 + assert_select 'div.row > div.col-md-8 > h3', text: "Extended Pages Test Widget" + end + + +end \ No newline at end of file diff --git a/apps/dashboard/test/models/user_configuration_test.rb b/apps/dashboard/test/models/user_configuration_test.rb index bfe2807d9f..e03acb1afc 100644 --- a/apps/dashboard/test/models/user_configuration_test.rb +++ b/apps/dashboard/test/models/user_configuration_test.rb @@ -62,6 +62,7 @@ class UserConfigurationTest < ActiveSupport::TestCase nav_categories: ["Apps", "Files", "Jobs", "Clusters", "Interactive Apps"], nav_bar: [], help_bar: [], + custom_pages: {}, } # ensure all properties are tested