diff --git a/app/components/_index.sass b/app/components/_index.sass index 7fb1cf543d5a..eb4fcff82185 100644 --- a/app/components/_index.sass +++ b/app/components/_index.sass @@ -44,6 +44,7 @@ @import "work_packages/progress/modal_body_component" @import "work_packages/reminder/modal_body_component" @import "work_packages/split_view_component" +@import "header/project_select_component" @import "homescreen/link_component" @import "homescreen/links_component" @import "homescreen/new_features_component" diff --git a/app/components/header/project_select_component.html.erb b/app/components/header/project_select_component.html.erb new file mode 100644 index 000000000000..3e1435420457 --- /dev/null +++ b/app/components/header/project_select_component.html.erb @@ -0,0 +1,81 @@ +<%#-- copyright +OpenProject is an open source project management software. +Copyright (C) the OpenProject GmbH + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 3. + +OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +Copyright (C) 2006-2013 Jean-Philippe Lang +Copyright (C) 2010-2013 the ChiliProject Team + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +See COPYRIGHT and LICENSE files for more details. + +++#%> + +<%= render( + Primer::Alpha::Overlay.new( + title: t("header_project_select.title"), + visually_hide_title: true, + anchor_side: :outside_bottom, + anchor_align: :start, + size: :auto, + padding: :none + ) + ) do |overlay| %> + <% overlay.with_show_button( + id: "projects-menu", + classes: "op-project-select--trigger-button", + scheme: :invisible, + data: { "test-selector": "op-projects-menu" } + ) do |button| %> + <%= trigger_label %> + <% button.with_trailing_visual_icon(icon: :"triangle-down") %> + <% end %> + + <% overlay.with_body(classes: "op-project-select--body", data: { controller: "header-project-select" }) do %> + <%= render( + Primer::OpenProject::FilterableTreeView.new( + src: tree_src, + include_sub_items_check_box_arguments: { hidden: true }, + filter_mode_control_arguments: logged_in? ? {} : { hidden: true } + ) + ) do |tree_view| %> + <% if logged_in? %> + <% tree_view.with_filter_mode(name: "all", label: t("filterable_tree_view.filter_mode.all"), selected: true) %> + <% tree_view.with_filter_mode(name: "favorited", label: t("header_project_select.favorites")) %> + <% end %> + <% end %> + + <% unless OpenProject::FeatureDecisions.portfolio_models_active? %> + <%= helpers.flex_layout(justify_content: :flex_end, p: 2) do |bar| %> + <% bar.with_column(mr: 2) do %> + <%= render(Primer::Beta::Button.new(tag: :a, href: projects_path)) do %> + <%= t("header_project_select.all_projects") %> + <% end %> + <% end %> + <% if can_create_projects? %> + <% bar.with_column do %> + <%= render(Primer::Beta::Button.new(tag: :a, href: new_project_path, scheme: :primary)) do %> + <%= t("header_project_select.new_project") %> + <% end %> + <% end %> + <% end %> + <% end %> + <% end %> + <% end %> +<% end %> diff --git a/app/components/header/project_select_component.rb b/app/components/header/project_select_component.rb new file mode 100644 index 000000000000..51a9f046d0dc --- /dev/null +++ b/app/components/header/project_select_component.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module Header + class ProjectSelectComponent < ApplicationComponent + include OpenProject::StaticRouting::UrlHelpers + + def initialize(current_project: nil, current_user: User.current, current_menu_item: nil) + super() + @current_project = current_project + @current_user = current_user + @current_menu_item = current_menu_item + end + + def trigger_label + @current_project&.name || I18n.t("header_project_select.trigger_no_project") + end + + def tree_src + header_projects_path( + current_project_id: @current_project&.id, + jump: @current_menu_item.presence + ) + end + + def can_create_projects? + @current_user.allowed_globally?(:add_project) + end + + def logged_in? + @current_user.logged? + end + end +end diff --git a/app/components/header/project_select_component.sass b/app/components/header/project_select_component.sass new file mode 100644 index 000000000000..35c55bbfae9a --- /dev/null +++ b/app/components/header/project_select_component.sass @@ -0,0 +1,41 @@ +//-- copyright +// OpenProject is an open source project management software. +// Copyright (C) the OpenProject GmbH +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See COPYRIGHT and LICENSE files for more details. +//++ + +.op-project-select + &--body + max-height: 75dvh + overflow: hidden + margin: var(--base-size-16) + margin-right: 0 + + &--trigger-button + min-width: unset + display: block + + .Button-label + @include text-shortener diff --git a/app/controllers/header/projects_controller.rb b/app/controllers/header/projects_controller.rb new file mode 100644 index 000000000000..15946aea5533 --- /dev/null +++ b/app/controllers/header/projects_controller.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +class Header::ProjectsController < ApplicationController + no_authorization_required! :index + + MAX_NUMBER_OF_PROJECTS = 300 + + def index + @current_project_id = params[:current_project_id]&.to_i + @jump = params[:jump].presence + @projects = load_projects + @favorited_ids = load_favorited_ids + @tree = build_tree(@projects) + + render layout: false + end + + private + + def query + params[:query].to_s.strip + end + + def filter_mode + params[:filter_mode].to_s + end + + def load_projects + projects = base_scope.to_a + ensure_current_project_present(projects) + end + + def base_scope + scope = Project.visible.active.order(:lft).limit(MAX_NUMBER_OF_PROJECTS) + scope = scope.where("LOWER(name) LIKE LOWER(?)", "%#{ActiveRecord::Base.sanitize_sql_like(query)}%") if query.present? + scope = scope.where(id: favorite_project_ids) if filter_mode == "favorited" && User.current.logged? + scope + end + + def ensure_current_project_present(projects) + return projects if query.present? || @current_project_id.blank? + return projects if projects.any? { |p| p.id == @current_project_id } + + current = Project.visible.active.find_by(id: @current_project_id) + return projects unless current + + (projects + current.self_and_ancestors.active.to_a).uniq(&:id).sort_by(&:lft) + end + + def favorite_project_ids + Favorite.where(favorited_type: "Project", user_id: User.current.id).select(:favorited_id) + end + + def load_favorited_ids + return Set.new unless User.current.logged? + + Favorite + .where(favorited_type: "Project", user_id: User.current.id, favorited_id: @projects.map(&:id)) + .pluck(:favorited_id) + .to_set + end + + # Builds a nested structure from a flat, lft-ordered list of projects. + # Projects whose parent is not in the result set appear as roots. + # Each level is sorted alphabetically by project name. + def build_tree(projects) + nodes = projects.index_by(&:id).transform_values { |p| { project: p, children: [] } } + + roots = [] + projects.each do |project| + node = nodes[project.id] + parent = nodes[project.parent_id] + + if parent + parent[:children] << node + else + roots << node + end + end + + sort_nodes(roots) + end + + def sort_nodes(nodes) + nodes.sort_by { |n| n[:project].name.downcase }.each do |node| + node[:children] = sort_nodes(node[:children]) + node[:expanded] = node[:children].any? { |c| c[:project].id == @current_project_id || c[:expanded] } + end + end +end diff --git a/app/views/header/projects/_node.html.erb b/app/views/header/projects/_node.html.erb new file mode 100644 index 000000000000..4db5cb13fbc2 --- /dev/null +++ b/app/views/header/projects/_node.html.erb @@ -0,0 +1,81 @@ +<%#-- copyright +OpenProject is an open source project management software. +Copyright (C) the OpenProject GmbH + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 3. + +OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +Copyright (C) 2006-2013 Jean-Philippe Lang +Copyright (C) 2010-2013 the ChiliProject Team + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +See COPYRIGHT and LICENSE files for more details. + +++#%> + +<% project = node[:project] %> +<% children = node[:children] %> +<% is_current = project.id == current_project_id %> +<% is_favorited = favorited_ids.include?(project.id) %> +<% href = jump.present? ? project_path(project.identifier, jump:) : project_path(project.identifier) %> +<% is_expanded = node[:expanded] %> + +<% add_icons = ->(tree_node) do + if is_current + tree_node.with_trailing_action_button( + icon: :"x-circle", + tag: :a, + href: home_path(jump:), + show_tooltip: false, + aria: { label: t("header_project_select.leave_project") } + ) + end + if is_favorited + tree_node.with_trailing_visual_icon(icon: :"star-fill", classes: "op-primer--star-icon") + end + end %> + +<% if children.any? %> + <% component.with_sub_tree( + label: project.name, + select_variant: :none, + current: is_current, + expanded: is_expanded, + href:, + data: { node_id: project.id } + ) do |sub| %> + <% add_icons.call(sub) %> + <% children.each do |child_node| %> + <%= render "header/projects/node", + component: sub, + node: child_node, + current_project_id: current_project_id, + favorited_ids: favorited_ids, + jump: %> + <% end %> + <% end %> +<% else %> + <% component.with_leaf( + label: project.name, + select_variant: :none, + current: is_current, + href:, + data: { node_id: project.id } + ) do |leaf| %> + <% add_icons.call(leaf) %> + <% end %> +<% end %> diff --git a/app/views/header/projects/index.html.erb b/app/views/header/projects/index.html.erb new file mode 100644 index 000000000000..e58e600da780 --- /dev/null +++ b/app/views/header/projects/index.html.erb @@ -0,0 +1,44 @@ +<%#-- copyright +OpenProject is an open source project management software. +Copyright (C) the OpenProject GmbH + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 3. + +OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +Copyright (C) 2006-2013 Jean-Philippe Lang +Copyright (C) 2010-2013 the ChiliProject Team + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +See COPYRIGHT and LICENSE files for more details. + +++#%> + +<%= render( + Primer::Alpha::TreeView.new( + node_variant: :anchor, + data: { target: "filterable-tree-view.treeViewList" } + ) + ) do |tree| %> + <% @tree.each do |node| %> + <%= render "header/projects/node", + component: tree, + node: node, + current_project_id: @current_project_id, + favorited_ids: @favorited_ids, + jump: @jump %> + <% end %> +<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 0fc9db206d6e..d7f75f3a0634 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -136,7 +136,7 @@ en: title: "Beta - Try it out!" description: "This Jira Migrator is currently in beta. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time." contribution_callout: > - Please, help us improve the Jira Migrator with your feedback and private data donations. You can [join the development community](link) of the Jira Migrator. + Please, help us improve the Jira Migrator with your feedback and private data donations. You can [join the development community](link) of the Jira Migrator. supported_versions: "" form: fields: @@ -3520,6 +3520,14 @@ en: catppt: "Catppt available (optional)" tesseract: "Tesseract available (optional)" + header_project_select: + all_projects: "All projects" + favorites: "Favorites" + leave_project: "Leave project" + new_project: "New project" + title: "Projects" + trigger_no_project: "Select a project" + filterable_tree_view: filter_mode: all: "All" diff --git a/config/locales/js-en.yml b/config/locales/js-en.yml index 50545ecb1255..1054bba75373 100644 --- a/config/locales/js-en.yml +++ b/config/locales/js-en.yml @@ -452,7 +452,6 @@ en: label_per_page: "Per page:" label_please_wait: "Please wait" label_project: "Project" - label_project_list: "Project lists" label_project_plural: "Projects" label_visibility_settings: "Visibility settings" label_quote_comment: "Quote this comment" @@ -1145,16 +1144,13 @@ en: all: "All projects" selected: "Only selected" search_placeholder: "Search projects..." - search_placeholder_favorites: "Search favorites..." include_subprojects: "Include all sub-projects" tooltip: include_all_selected: "Project already included since Include all sub-projects is enabled." current_project: "This is the current project you are in." does_not_match_search: "Project does not match the search criteria." no_results: "No project matches your search criteria." - no_favorite_results: "No favorite project matches your search criteria." include_workspaces: - search_placeholder: "Search..." types: program: "Program" portfolio: "Portfolio" diff --git a/config/routes.rb b/config/routes.rb index 0b53becfc638..e157f76f06bb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -286,6 +286,10 @@ resource :identifier_suggestion, only: %i[show], controller: "identifier_suggestion" end + namespace :header do + resources :projects, only: :index + end + %w[portfolio project program].each do |workspace_type| resources workspace_type.pluralize, only: %i[new create], diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 540fb751c88f..fcb316af0370 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -189,6 +189,9 @@ "fsevents": "*" } }, + "../../../Users/hdinger/code/primer_view_components": { + "extraneous": true + }, "node_modules/@algolia/abtesting": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.14.1.tgz", @@ -5000,6 +5003,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/@github/auto-check-element/-/auto-check-element-6.0.0.tgz", "integrity": "sha512-87mHEywJEtlG/37zFrx4PUgDqczgtv9jrauW3IojNy9y+nALIAm6e2jnWpfgcqeMWSevzph2M6reJoHpuSjyWw==", + "license": "MIT", "dependencies": { "@github/mini-throttle": "^2.1.0" } @@ -5008,45 +5012,52 @@ "version": "3.8.0", "resolved": "https://registry.npmjs.org/@github/auto-complete-element/-/auto-complete-element-3.8.0.tgz", "integrity": "sha512-rS2Uj38V1BsenLvrIswV5IXfiYH2/KUhz6inot+JXho/fFOO+01tsW1HxqSdIXqh5EDuoY0f/GQsztZcH22AXQ==", + "license": "MIT", "dependencies": { "@github/combobox-nav": "^2.1.7" } }, "node_modules/@github/catalyst": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@github/catalyst/-/catalyst-1.8.0.tgz", - "integrity": "sha512-uLpi/D/mKfylYaFLfzNuloXNENi0AlcM0Z7hwYLH8Z030jBCr+ueMdX2xLxCzpMH/keYXKh0uPrHSMfcbxU6KA==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@github/catalyst/-/catalyst-1.8.1.tgz", + "integrity": "sha512-dnN4WWpbeuQvA17LvsGdlXEueJdBk9y+I+WO5pdNpoHNOXPsFcz3hJrq1iRmdsNgQOf4S8e83axtwIxvG62eWA==", "license": "MIT" }, "node_modules/@github/clipboard-copy-element": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@github/clipboard-copy-element/-/clipboard-copy-element-1.3.0.tgz", - "integrity": "sha512-wyntkQkwoLbLo+Hqg2LIVMXDIzcvUb9bSDz+clX6nVJItwzh103rHxdXFRZD+DmxVbuEW5xSznYQXkz1jZT+xg==" + "integrity": "sha512-wyntkQkwoLbLo+Hqg2LIVMXDIzcvUb9bSDz+clX6nVJItwzh103rHxdXFRZD+DmxVbuEW5xSznYQXkz1jZT+xg==", + "license": "MIT" }, "node_modules/@github/combobox-nav": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/@github/combobox-nav/-/combobox-nav-2.3.1.tgz", - "integrity": "sha512-gwxPzLw8XKecy1nP63i9lOBritS3bWmxl02UX6G0TwMQZbMem1BCS1tEZgYd3mkrkiDrUMWaX+DbFCuDFo3K+A==" + "integrity": "sha512-gwxPzLw8XKecy1nP63i9lOBritS3bWmxl02UX6G0TwMQZbMem1BCS1tEZgYd3mkrkiDrUMWaX+DbFCuDFo3K+A==", + "license": "MIT" }, "node_modules/@github/details-menu-element": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/@github/details-menu-element/-/details-menu-element-1.0.13.tgz", - "integrity": "sha512-gMkii86w/oUP5dq8yOWZn1sgbgtFj3AYETxxtpsqRggZktgd8te4+npAn4Hm+936c/lxmEzXqfjARL/CzGR4+w==" + "integrity": "sha512-gMkii86w/oUP5dq8yOWZn1sgbgtFj3AYETxxtpsqRggZktgd8te4+npAn4Hm+936c/lxmEzXqfjARL/CzGR4+w==", + "license": "MIT" }, "node_modules/@github/image-crop-element": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@github/image-crop-element/-/image-crop-element-5.0.0.tgz", - "integrity": "sha512-Vgm2OwWAs1ESoib/t5sjxsAYo6YTOxxAjWDRxswX7qrqoyCejTZ3hshdo4Ep5e+Mz/GVTZC3rdMtg06dk/eT4g==" + "integrity": "sha512-Vgm2OwWAs1ESoib/t5sjxsAYo6YTOxxAjWDRxswX7qrqoyCejTZ3hshdo4Ep5e+Mz/GVTZC3rdMtg06dk/eT4g==", + "license": "MIT" }, "node_modules/@github/include-fragment-element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@github/include-fragment-element/-/include-fragment-element-6.3.0.tgz", - "integrity": "sha512-BJTt8ZE/arsbC9lQtTH8c1hZS0ZigiN+kzH54ffQ6MhHLT83h0OpSdS9NEVocPl2uuO6w3qxnEKTDzUGMQ5rdQ==" + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@github/include-fragment-element/-/include-fragment-element-6.4.1.tgz", + "integrity": "sha512-ffgXc7qwBtY/rYcMkAjxZJlyOPFaeC9K1Oc+n7Edwt3BAHPokUSdMfDivb+/dGO+NU2n7l1/L4v5uQN+wBeV4g==", + "license": "MIT" }, "node_modules/@github/mini-throttle": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@github/mini-throttle/-/mini-throttle-2.1.1.tgz", - "integrity": "sha512-KtOPaB+FiKJ6jcKm9UKyaM5fPURHGf+xcp+b4Mzoi81hOc6M1sIGpMZMAVbNzfa2lW5+RPGKq888Px0j76OZ/A==" + "integrity": "sha512-KtOPaB+FiKJ6jcKm9UKyaM5fPURHGf+xcp+b4Mzoi81hOc6M1sIGpMZMAVbNzfa2lW5+RPGKq888Px0j76OZ/A==", + "license": "MIT" }, "node_modules/@github/relative-time-element": { "version": "5.0.0", @@ -5057,12 +5068,14 @@ "node_modules/@github/remote-input-element": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@github/remote-input-element/-/remote-input-element-0.4.0.tgz", - "integrity": "sha512-apsMwsFW24F+w2wzT8oKoBi9lpm6GeFOmtuL+1YwDVmIiwixfHOD3MnEsEOv0RwmHsMdWmIjP9mxWyTWPKZHGg==" + "integrity": "sha512-apsMwsFW24F+w2wzT8oKoBi9lpm6GeFOmtuL+1YwDVmIiwixfHOD3MnEsEOv0RwmHsMdWmIjP9mxWyTWPKZHGg==", + "license": "MIT" }, "node_modules/@github/tab-container-element": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/@github/tab-container-element/-/tab-container-element-3.4.0.tgz", - "integrity": "sha512-Yx70pO8A0p7Stnm9knKkUNX8i4bjuwDYZarRkM8JH0Z+ffhpe++oNAPbzGI9GEcGugRHvKuSC6p4YOdoHtTniQ==" + "integrity": "sha512-Yx70pO8A0p7Stnm9knKkUNX8i4bjuwDYZarRkM8JH0Z+ffhpe++oNAPbzGI9GEcGugRHvKuSC6p4YOdoHtTniQ==", + "license": "MIT" }, "node_modules/@github/webauthn-json": { "version": "2.1.1", @@ -8002,9 +8015,10 @@ } }, "node_modules/@primer/behaviors": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@primer/behaviors/-/behaviors-1.3.5.tgz", - "integrity": "sha512-HWwz+6MrfK5NTWcg9GdKFpMBW/yrAV937oXiw2eDtsd88P3SRwoCt6ZO6QmKp9RP3nDU9cbqmuGZ0xBh0eIFeg==" + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@primer/behaviors/-/behaviors-1.10.2.tgz", + "integrity": "sha512-93juWZbWg2DRhC11+7RT7hMpY1VD3lBosLmccqEZ65yrCHqkBCjI8Uj8wxs3y0U+wWE07LAoLHAPylyWbifg5A==", + "license": "MIT" }, "node_modules/@primer/css": { "version": "22.1.0", @@ -29011,9 +29025,9 @@ } }, "@github/catalyst": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@github/catalyst/-/catalyst-1.8.0.tgz", - "integrity": "sha512-uLpi/D/mKfylYaFLfzNuloXNENi0AlcM0Z7hwYLH8Z030jBCr+ueMdX2xLxCzpMH/keYXKh0uPrHSMfcbxU6KA==" + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@github/catalyst/-/catalyst-1.8.1.tgz", + "integrity": "sha512-dnN4WWpbeuQvA17LvsGdlXEueJdBk9y+I+WO5pdNpoHNOXPsFcz3hJrq1iRmdsNgQOf4S8e83axtwIxvG62eWA==" }, "@github/clipboard-copy-element": { "version": "1.3.0", @@ -29036,9 +29050,9 @@ "integrity": "sha512-Vgm2OwWAs1ESoib/t5sjxsAYo6YTOxxAjWDRxswX7qrqoyCejTZ3hshdo4Ep5e+Mz/GVTZC3rdMtg06dk/eT4g==" }, "@github/include-fragment-element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@github/include-fragment-element/-/include-fragment-element-6.3.0.tgz", - "integrity": "sha512-BJTt8ZE/arsbC9lQtTH8c1hZS0ZigiN+kzH54ffQ6MhHLT83h0OpSdS9NEVocPl2uuO6w3qxnEKTDzUGMQ5rdQ==" + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@github/include-fragment-element/-/include-fragment-element-6.4.1.tgz", + "integrity": "sha512-ffgXc7qwBtY/rYcMkAjxZJlyOPFaeC9K1Oc+n7Edwt3BAHPokUSdMfDivb+/dGO+NU2n7l1/L4v5uQN+wBeV4g==" }, "@github/mini-throttle": { "version": "2.1.1", @@ -30838,9 +30852,9 @@ } }, "@primer/behaviors": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@primer/behaviors/-/behaviors-1.3.5.tgz", - "integrity": "sha512-HWwz+6MrfK5NTWcg9GdKFpMBW/yrAV937oXiw2eDtsd88P3SRwoCt6ZO6QmKp9RP3nDU9cbqmuGZ0xBh0eIFeg==" + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@primer/behaviors/-/behaviors-1.10.2.tgz", + "integrity": "sha512-93juWZbWg2DRhC11+7RT7hMpY1VD3lBosLmccqEZ65yrCHqkBCjI8Uj8wxs3y0U+wWE07LAoLHAPylyWbifg5A==" }, "@primer/css": { "version": "22.1.0", diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index 1bca3a907a7b..3690db39bf6a 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -68,13 +68,6 @@ import { OpenprojectEnterpriseModule } from 'core-app/features/enterprise/openpr import { ConfirmDialogService } from 'core-app/shared/components/modals/confirm-dialog/confirm-dialog.service'; import { ConfirmDialogModalComponent } from 'core-app/shared/components/modals/confirm-dialog/confirm-dialog.modal'; import { DynamicContentModalComponent } from 'core-app/shared/components/modals/modal-wrapper/dynamic-content.modal'; -import { - OpHeaderProjectSelectComponent, -} from 'core-app/shared/components/header-project-select/header-project-select.component'; -import { - OpHeaderProjectSelectListComponent, -} from 'core-app/shared/components/header-project-select/list/header-project-select-list.component'; - import { PaginationService } from 'core-app/shared/components/table-pagination/pagination-service'; import { MainMenuResizerComponent } from 'core-app/shared/components/resizer/resizer/main-menu-resizer.component'; import { OpenprojectTabsModule } from 'core-app/shared/components/tabs/openproject-tabs.module'; @@ -264,10 +257,6 @@ export function runBootstrap(appRef:ApplicationRef) { // Main menu MainMenuResizerComponent, - // Project selector - OpHeaderProjectSelectComponent, - OpHeaderProjectSelectListComponent, - // Form configuration OpDragScrollDirective, ], @@ -418,7 +407,6 @@ export class OpenProjectModule implements DoBootstrap { registerCustomElement('opce-editable-query-props', EditableQueryPropsComponent, { injector }); registerCustomElement('opce-time-entry-trigger-actions', TriggerActionsEntryComponent, { injector }); registerCustomElement('opce-wp-overview-graph', WorkPackageOverviewGraphComponent, { injector }); - registerCustomElement('opce-header-project-select', OpHeaderProjectSelectComponent, { injector }); registerCustomElement('opce-no-results', NoResultsComponent, { injector }); registerCustomElement('opce-non-working-days-list', OpNonWorkingDaysListComponent, { injector }); registerCustomElement('opce-main-menu-resizer', MainMenuResizerComponent, { injector }); diff --git a/frontend/src/app/shared/components/grids/widgets/project-favorites/widget-project-favorites.component.html b/frontend/src/app/shared/components/grids/widgets/project-favorites/widget-project-favorites.component.html index ad9434bb1e43..d3447d4d4c81 100644 --- a/frontend/src/app/shared/components/grids/widgets/project-favorites/widget-project-favorites.component.html +++ b/frontend/src/app/shared/components/grids/widgets/project-favorites/widget-project-favorites.component.html @@ -9,16 +9,16 @@ @if ((projects$ | async); as projects) {