mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
enterprise banner with fallback on sprint sharing settings
This commit is contained in:
@@ -208,7 +208,7 @@ gem "aws-sdk-core", "~> 3.244"
|
||||
# File upload via fog + screenshots on travis
|
||||
gem "aws-sdk-s3", "~> 1.217"
|
||||
|
||||
gem "openproject-token", "~> 8.8.2"
|
||||
gem "openproject-token", "~> 8.9.0"
|
||||
|
||||
gem "plaintext", "~> 0.3.7"
|
||||
|
||||
|
||||
+3
-3
@@ -914,7 +914,7 @@ GEM
|
||||
activesupport (>= 7.2.0)
|
||||
openproject-octicons (>= 19.34.0)
|
||||
view_component (>= 3.1, < 5.0)
|
||||
openproject-token (8.8.2)
|
||||
openproject-token (8.9.0)
|
||||
activemodel
|
||||
openssl (4.0.1)
|
||||
openssl-signature_algorithm (1.3.0)
|
||||
@@ -1693,7 +1693,7 @@ DEPENDENCIES
|
||||
openproject-resource_management!
|
||||
openproject-storages!
|
||||
openproject-team_planner!
|
||||
openproject-token (~> 8.8.2)
|
||||
openproject-token (~> 8.9.0)
|
||||
openproject-two_factor_authentication!
|
||||
openproject-webhooks!
|
||||
openproject-wikis!
|
||||
@@ -2075,7 +2075,7 @@ CHECKSUMS
|
||||
openproject-resource_management (1.0.0)
|
||||
openproject-storages (1.0.0)
|
||||
openproject-team_planner (1.0.0)
|
||||
openproject-token (8.8.2) sha256=081cbff7269d92a82fa1d63e9e09c87b70d47d7aefadcbb80d1e7368bc2cf096
|
||||
openproject-token (8.9.0) sha256=aa08c144889010750de4edaf61f8614ccb82ac6c63beef1d3a21c6a222358605
|
||||
openproject-two_factor_authentication (1.0.0)
|
||||
openproject-webhooks (1.0.0)
|
||||
openproject-wikis (1.0.0)
|
||||
|
||||
+6
-2
@@ -29,7 +29,11 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
<%=
|
||||
render(Primer::Beta::Text.new(tag: :div, color: :muted, mb: 3)) do
|
||||
I18n.t("backlogs.sharing_description")
|
||||
if only_fallback_allowed
|
||||
t(".sharing_fallback_description")
|
||||
else
|
||||
t(".sharing_description")
|
||||
end
|
||||
end
|
||||
%>
|
||||
|
||||
@@ -40,6 +44,6 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
method: :patch,
|
||||
data: { turbo_frame: "_top", controller: "show-when-value-selected" }
|
||||
) do |f|
|
||||
render(Projects::Settings::Backlogs::SharingForm.new(f))
|
||||
render(Projects::Settings::Backlogs::SharingForm.new(f, only_fallback_allowed:))
|
||||
end
|
||||
%>
|
||||
|
||||
+4
-2
@@ -35,15 +35,17 @@ module Projects
|
||||
include ApplicationHelper
|
||||
include OpPrimer::ComponentHelpers
|
||||
|
||||
def initialize(project:)
|
||||
def initialize(project:,
|
||||
only_fallback_allowed: false)
|
||||
super
|
||||
|
||||
@project = project
|
||||
@only_fallback_allowed = only_fallback_allowed
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :project
|
||||
attr_reader :project, :only_fallback_allowed
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -41,7 +41,7 @@ module Projects
|
||||
# is saved.
|
||||
# Ideally the hidden field should automatically be rendered by the `radio_button_group`
|
||||
# helper, similar to how the `collection_radio_buttons` rails helper does.
|
||||
sharing_form.hidden(name: :sprint_sharing, value: "")
|
||||
sharing_form.hidden(name: :sprint_sharing, value: model.sprint_sharing)
|
||||
|
||||
sharing_form.radio_button_group(
|
||||
name: :sprint_sharing,
|
||||
@@ -69,14 +69,22 @@ module Projects
|
||||
)
|
||||
end
|
||||
|
||||
def initialize(only_fallback_allowed: false)
|
||||
super()
|
||||
@only_fallback_allowed = only_fallback_allowed
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :only_fallback_allowed
|
||||
|
||||
def checked?(option)
|
||||
option == model.sprint_sharing
|
||||
end
|
||||
|
||||
def disabled?(option)
|
||||
option == Project::SHARE_ALL_PROJECTS && share_all_projects_disabled?
|
||||
(only_fallback_allowed && option != Projects::SprintSharing::NO_SHARING) ||
|
||||
(option == Project::SHARE_ALL_PROJECTS && share_all_projects_disabled?)
|
||||
end
|
||||
|
||||
def sharing_option_text(option, key, **)
|
||||
@@ -84,12 +92,9 @@ module Projects
|
||||
end
|
||||
|
||||
def caption_for(option)
|
||||
if disabled?(option)
|
||||
if User.current.allowed_in_project?(:view_project, global_sprint_sharer)
|
||||
sharing_option_text(option, :disabled_caption, name: global_sprint_sharer.name)
|
||||
else
|
||||
sharing_option_text(option, :disabled_caption_anonymous)
|
||||
end
|
||||
case option
|
||||
when Project::SHARE_ALL_PROJECTS
|
||||
shared_all_projects_caption
|
||||
else
|
||||
sharing_option_text(option, :caption)
|
||||
end
|
||||
@@ -117,6 +122,16 @@ module Projects
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def shared_all_projects_caption
|
||||
if !disabled?(Project::SHARE_ALL_PROJECTS)
|
||||
sharing_option_text(Project::SHARE_ALL_PROJECTS, :caption)
|
||||
elsif User.current.allowed_in_project?(:view_project, global_sprint_sharer)
|
||||
sharing_option_text(Project::SHARE_ALL_PROJECTS, :disabled_caption, name: global_sprint_sharer.name)
|
||||
else
|
||||
sharing_option_text(Project::SHARE_ALL_PROJECTS, :disabled_caption_anonymous)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,5 +35,18 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
)
|
||||
) %>
|
||||
|
||||
<%= render(Projects::Settings::Backlogs::SharingFormComponent.new(project: @project)) %>
|
||||
<% with_enterprise_banner_guard(
|
||||
:sprint_sharing,
|
||||
inactive_guard: !@project.not_sharing_sprints?,
|
||||
variant: :large,
|
||||
image: "enterprise/project-creation-wizard.png"
|
||||
) do %>
|
||||
<%= render(EnterpriseEdition::BannerComponent.new(:sprint_sharing, variant: :inline)) %>
|
||||
<%= render(
|
||||
Projects::Settings::Backlogs::SharingFormComponent.new(
|
||||
project: @project,
|
||||
only_fallback_allowed: !EnterpriseToken.allows_to?(:sprint_sharing)
|
||||
)
|
||||
) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -98,7 +98,6 @@ en:
|
||||
definition_of_done: "Definition of Done"
|
||||
definition_of_done_caption: "Work packages with these statuses are treated as completed in backlog views and reporting."
|
||||
done_status: "Done status"
|
||||
sharing_description: "This project can either share its own sprints, receive shared sprints or handle sprints independently (no sharing)."
|
||||
sharing: "Sharing"
|
||||
label_burndown_chart: "Burndown chart"
|
||||
label_sprint_board: "Sprint board"
|
||||
@@ -206,6 +205,13 @@ en:
|
||||
story_points: "Story points"
|
||||
story_points_ideal: "Story points (ideal)"
|
||||
|
||||
ee:
|
||||
features:
|
||||
sprint_sharing: "Sprint sharing"
|
||||
upsell:
|
||||
sprint_sharing:
|
||||
description: "Share sprints across projects to align teams and coordinate work in scaled agile setups (SAFe)."
|
||||
|
||||
label_backlog: "Backlog"
|
||||
label_backlog_bucket_edit: "Edit backlog bucket"
|
||||
label_backlog_bucket_new: "New backlog bucket"
|
||||
@@ -257,4 +263,10 @@ en:
|
||||
info: "Sharing a sprint will share the name, status and the start and finish dates in all projects. These cannot be modified in projects that receive and use these sprints."
|
||||
sprint_sharing: Share sprints
|
||||
|
||||
backlogs:
|
||||
sharing_form_component:
|
||||
sharing_description: "This project can either share its own sprints, receive shared sprints or handle sprints independently (no sharing)."
|
||||
sharing_fallback_description: "Lacking a corporate enterprise plan, the sharing options are limited to the project's own sprints. The currently active setting remains active."
|
||||
|
||||
|
||||
remaining_hours: "remaining work"
|
||||
|
||||
@@ -42,7 +42,8 @@ RSpec.describe "Backlogs project settings sprint sharing", :js do
|
||||
login_as current_user
|
||||
end
|
||||
|
||||
context "with share_sprint permission" do
|
||||
context "with share_sprint permission and enterprise token",
|
||||
with_ee: [:sprint_sharing] do
|
||||
it "displays and stores sprint sharing settings" do
|
||||
visit project_settings_backlog_sharing_path(project)
|
||||
|
||||
@@ -127,6 +128,50 @@ RSpec.describe "Backlogs project settings sprint sharing", :js do
|
||||
end
|
||||
end
|
||||
|
||||
context "with share_sprint permission but no enterprise token" do
|
||||
context "without existing sharing setting in the project" do
|
||||
it "shows an enterprise token teaser" do
|
||||
visit project_settings_backlog_sharing_path(project)
|
||||
|
||||
expect(page).to have_text("Share sprints across projects to align teams")
|
||||
|
||||
expect(page).to have_no_field("Don't share")
|
||||
expect(page).to have_no_field("All projects")
|
||||
expect(page).to have_no_field("Subprojects")
|
||||
expect(page).to have_no_field("Receive shared sprints")
|
||||
end
|
||||
end
|
||||
|
||||
context "with existing sharing setting in the project" do
|
||||
before do
|
||||
project.update!(sprint_sharing: "receive_shared")
|
||||
end
|
||||
|
||||
it "shows the existing sharing setting but disables them except for `Don't share`" do
|
||||
visit project_settings_backlog_sharing_path(project)
|
||||
|
||||
# All radio buttons are present with the selected option displayed.
|
||||
# But all except the "Don't share" option are disabled.
|
||||
expect(page).to have_unchecked_field("Don't share")
|
||||
expect(page).to have_unchecked_field("All projects", disabled: true)
|
||||
expect(page).to have_unchecked_field("Subprojects", disabled: true)
|
||||
expect(page).to have_checked_field("Receive shared sprints", disabled: true)
|
||||
|
||||
choose("Don't share")
|
||||
|
||||
click_button "Save"
|
||||
|
||||
# Now that the `Don't share` option is selected, the large enterprise banner is displayed.
|
||||
expect(page).to have_text("Share sprints across projects to align teams")
|
||||
|
||||
expect(page).to have_no_field("Don't share")
|
||||
expect(page).to have_no_field("All projects")
|
||||
expect(page).to have_no_field("Subprojects")
|
||||
expect(page).to have_no_field("Receive shared sprints")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "without share_sprint permission" do
|
||||
let(:permissions) { %i[create_sprints select_done_statuses] }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user