Replace common/upsale with component

This commit is contained in:
Oliver Günther
2025-03-27 13:29:58 +01:00
parent db4fa073f0
commit 9357553e3f
27 changed files with 341 additions and 259 deletions
+1
View File
@@ -27,4 +27,5 @@
@import "work_package_relations_tab/relation_component"
@import "users/hover_card_component"
@import "enterprise_edition/banner_component"
@import "enterprise_edition/upsale_page_component"
@import "work_packages/types/pattern_input"
@@ -23,7 +23,7 @@
end
end
flex.with_row(mt: 2) do |button_layout|
flex.with_row(mt: 2) do
render EnterpriseEdition::UpsaleButtonsComponent.new(feature_key)
end
end
@@ -34,35 +34,26 @@ module EnterpriseEdition
# It will only be rendered if necessary.
class BannerComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include PlanForFeature
# @param feature_key [Symbol, NilClass] The key of the feature to show the banner for.
# @param title [String] The title of the banner.
# @param description [String] The description of the banner.
# @param href [String] The URL to link to.
# @param dismissable [boolean] Allow this banner to be dismissed.
# @param dismiss_key [String] Provide a string to identify this banner when being dismissed. Defaults to feature_key
# @param skip_render [Boolean] Whether to skip rendering the banner.
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
def initialize(feature_key,
title: nil,
description: nil,
link_title: nil,
href: nil,
dismissable: false,
dismiss_key: feature_key,
skip_render: EnterpriseToken.hide_banners?,
**system_arguments)
@system_arguments = system_arguments
@system_arguments[:tag] = :div
@system_arguments[:mb] ||= 2
@system_arguments[:id] = "op-enterprise-banner-#{feature_key.to_s.tr('_', '-')}"
@system_arguments[:test_selector] = @system_arguments[:id]
super
@feature_key = feature_key
@title = title
@description = description
@link_title = link_title
@href = href
@skip_render = skip_render
@dismissable = dismissable
@dismiss_key = dismiss_key
@@ -73,47 +64,6 @@ module EnterpriseEdition
attr_reader :skip_render,
:feature_key
def title
@title || I18n.t("ee.upsale.#{feature_key}.title", default: default_title)
end
def default_title
I18n.t("ee.upsale.plan_title", plan:)
end
def description
@description || begin
if I18n.exists?(:"ee.upsale.#{feature_key}.description_html")
I18n.t("ee.upsale.#{feature_key}.description_html").html_safe
else
I18n.t("ee.upsale.#{feature_key}.description")
end
end
rescue I18n::MissingTranslationData => e
raise e.exception(
<<~TEXT.squish
The expected '#{I18n.locale}.ee.upsale.#{feature_key}.description' nor '#{I18n.locale}.ee.upsale.#{feature_key}.description_html' key does not exist.
Ideally, provide it in the locale file.
If that isn't applicable, a description parameter needs to be provided.
TEXT
)
end
def plan_text
plan_name = render(Primer::Beta::Text.new(font_weight: :bold, classes: "upsale-colored")) { I18n.t("ee.upsale.plan_name", plan:) }
I18n.t("ee.upsale.plan_text_html", plan_name:).html_safe
end
def features
return @features if defined?(@features)
@features = I18n.t("ee.upsale.#{feature_key}.features", default: nil)&.values
end
def plan
@plan ||= OpenProject::Token.lowest_plan_for(feature_key)&.capitalize
end
def render?
!(skip_render || dismissed?)
end
@@ -0,0 +1,83 @@
# 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 EnterpriseEdition
module PlanForFeature
extend ActiveSupport::Concern
included do
attr_accessor :feature_key
end
def title
I18n.t("ee.upsale.#{feature_key}.title", default: default_title)
end
def default_title
I18n.t(feature_key, scope: :enterprise_features)
end
def description
@description || begin
if I18n.exists?(:"ee.upsale.#{feature_key}.description_html")
I18n.t("ee.upsale.#{feature_key}.description_html").html_safe
else
I18n.t("ee.upsale.#{feature_key}.description")
end
end
rescue I18n::MissingTranslationData => e
raise e.exception(
<<~TEXT.squish
The expected '#{I18n.locale}.ee.upsale.#{feature_key}.description' nor '#{I18n.locale}.ee.upsale.#{feature_key}.description_html' key does not exist.
Ideally, provide it in the locale file.
If that isn't applicable, a description parameter needs to be provided.
TEXT
)
end
def features
return @features if defined?(@features)
@features = I18n.t("ee.upsale.#{feature_key}.features", default: nil)&.values
end
def plan
@plan ||= OpenProject::Token.lowest_plan_for(feature_key)&.capitalize
end
def plan_text
plan_name = render(Primer::Beta::Text.new(font_weight: :bold, classes: "upsale-colored")) do
I18n.t("ee.upsale.plan_name", plan:)
end
I18n.t("ee.upsale.plan_text_html", plan_name:).html_safe
end
end
end
@@ -37,11 +37,13 @@ module EnterpriseEdition
def initialize(feature_key, **system_arguments)
super
@system_arguments = system_arguments
@system_arguments[:align_items] ||= :center
@feature_key = feature_key
end
def call
flex_layout(align_items: :center) do |flex|
flex_layout(**@system_arguments) do |flex|
buttons.each_with_index do |button, i|
flex.with_column(ml: (i == 0 ? 0 : 2)) do
button
@@ -74,7 +76,7 @@ module EnterpriseEdition
end
def more_info_button
render(Primer::Beta::Link.new(href:)) do |link|
render(Primer::Beta::Link.new(href: enterprise_link)) do |link|
link.with_trailing_visual_icon(icon: "link-external")
link_title
end
@@ -84,7 +86,7 @@ module EnterpriseEdition
I18n.t("ee.upsale.#{feature_key}.link_title", default: I18n.t("ee.upsale.link_title"))
end
def href
def enterprise_link
href_value = OpenProject::Static::Links.links.dig(:enterprise_docs, feature_key, :href)
unless href_value
@@ -0,0 +1,47 @@
<% helpers.write_augur_to_gon %>
<% if !EnterpriseToken.current.present? %>
<% helpers.write_trial_key_to_gon %>
<% end %>
<div class="op-enterprise-upsale-page">
<%=
render(Primer::OpenProject::FlexLayout.new(justify_content: :center, align_items: :center)) do |flex|
flex.with_column do
render(Primer::Beta::Octicon.new(icon: :"op-enterprise-addons",
size: :medium,
classes: "upsale-colored"))
end
flex.with_column(ml: 2) do
render(Primer::Beta::Heading.new(tag: :h2)) { title }
end
end
%>
<p class="upsale--feature-reference">
<%= render(Primer::Beta::Text.new) { description } %>
<%= render(Primer::Beta::Text.new) { plan_text } %>
</p>
<% if more_info_text.present? %>
<%= render(Primer::Beta::Text.new(tag: :p, color: :muted)) { more_info_text } %>
<% end %>
<% if features.present? %>
<ul>
<% features.each do |text| %>
<li><%= text %></li>
<% end %>
</ul>
<% end %>
<% if @video.present? %>
<%= video_tag @video, controls: false, class: "widget-box--teaser-video", autoplay: true, loop: true, muted: true %>
<% elsif @image.present? %>
<%= image_tag @image, class: "widget-box--teaser-image" %>
<% else %>
<%= image_tag "enterprise-add-on.svg", class: "widget-box--teaser-image_default" %>
<% end %>
<%= render EnterpriseEdition::UpsaleButtonsComponent.new(feature_key, justify_content: :center) %>
</div>
@@ -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 EnterpriseEdition
# A full page banner for the enterprise edition
class UpsalePageComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include PlanForFeature
# @param feature_key [Symbol, NilClass] The key of the feature to show the upsale page for.
# @param i18n_scope [String] Provide the i18n scope to look for title, description, and features.
# Defaults to "ee.upsale.{feature_key}"
# @param image [String, NilClass] Path to the image to show on the upsale page, or nil.
# @param video [String, NilClass] Path to the video to show on the upsale page, or nil.
def initialize(feature_key, i18n_scope: "ee.upsale.#{feature_key}", image: nil, video: nil)
super
self.feature_key = feature_key
self.i18n_scope = i18n_scope
@image = image
@video = video
end
def more_info_text
I18n.t(:more_info, scope: i18n_scope, default: nil)
end
private
def render?
!EnterpriseToken.hide_banners?
end
end
end
@@ -0,0 +1,53 @@
/*!
/ -- 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-enterprise-upsale-page
max-width: 50vw
margin: auto
padding-top: 20px
text-align: center
.widget-box--teaser-image,
.widget-box--teaser-video
width: 100%
height: auto
margin-bottom: 20px
box-shadow: 4px 4px 10px rgb(0 0 0 / 15%)
border-radius: 25px
border: 1px solid var(--borderColor-default)
.widget-box--teaser-image_default
width: 30%
margin-bottom: 20px
box-shadow: 4px 4px 10px rgb(0 0 0 / 15%)
border-radius: 25px
a.button,
a.button--link
text-decoration: none
@@ -1,3 +1,5 @@
# frozen_string_literal: true
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
@@ -30,7 +32,7 @@ module Admin::Settings
class VirusScanningSettingsController < ::Admin::SettingsController
menu_item :attachments
before_action :require_ee
before_action :require_ee, except: :show # rubocop:disable Rails/LexicallyScopedActionFilter
before_action :check_clamav, only: %i[update], if: -> { scan_enabled? }
def show_local_breadcrumb
@@ -52,14 +54,16 @@ module Admin::Settings
private
def require_ee
render("upsale") unless EnterpriseToken.allows_to?(:virus_scanning)
return if EnterpriseToken.allows_to?(:virus_scanning)
redirect_to action: :show
end
def mark_unscanned_attachments
@unscanned_attachments = Attachment.status_uploaded
end
def check_clamav
def check_clamav # rubocop:disable Metrics/AbcSize
return if params.dig(:settings, :antivirus_scan_mode) == "disabled"
service = ::Attachments::ClamAVService.new(params[:settings][:antivirus_scan_mode].to_sym,
+1 -7
View File
@@ -86,13 +86,7 @@ class CustomActionsController < ApplicationController
return if EnterpriseToken.allows_to?(:custom_actions)
if request.get?
render template: "common/upsale",
locals: {
feature_title: I18n.t("custom_actions.upsale.title"),
feature_description: I18n.t("custom_actions.upsale.description"),
feature_reference: "custom_actions_admin",
feature_video: "enterprise/custom-actions.mp4"
}
render template: "custom_actions/upsale"
else
render_403
end
@@ -36,6 +36,8 @@ See COPYRIGHT and LICENSE files for more details.
)
%>
<%= render EnterpriseEdition::BannerComponent.new(:virus_scanning) %>
<%= styled_form_tag(
admin_settings_virus_scanning_path,
method: :patch,
@@ -52,6 +54,7 @@ See COPYRIGHT and LICENSE files for more details.
["ClamAV (Socket)", :clamav_socket],
["ClamAV (Host)", :clamav_host]
],
disabled: !EnterpriseToken.allows_to?(:virus_scanning),
container_class: "-wide",
data: {
action: "refresh-on-form-changes#triggerTurboStream"
@@ -67,5 +70,7 @@ See COPYRIGHT and LICENSE files for more details.
</div>
<%= render partial: "av_form", locals: { selected: Setting.antivirus_scan_mode } %>
<%= styled_button_tag t(:button_save), class: "-primary -with-icon icon-checkmark" %>
<%= styled_button_tag t(:button_save),
disabled: !EnterpriseToken.allows_to?(:virus_scanning),
class: "-primary -with-icon icon-checkmark" %>
<% end %>
-74
View File
@@ -1,74 +0,0 @@
<% more_info = local_assigns[:feature_more_info] %>
<% feature_video = local_assigns[:feature_video] %>
<% feature_image = local_assigns[:feature_image] %>
<% additional_classes = local_assigns[:additional_classes] %>
<% write_augur_to_gon %>
<% if !EnterpriseToken.current.present? %>
<% write_trial_key_to_gon %>
<% end %>
<div class="upsale-notification <%= additional_classes %>">
<%= render(Primer::Beta::Heading.new(tag: :h2)) { feature_title } %>
<% if feature_description.empty? %>
<p class="upsale--feature-reference">
<%= t("js.admin.enterprise.upsale.benefits.description") %>
<br>
<%= t("js.admin.enterprise.upsale.benefits.premium_features_text") %>
<br>
<%= t("js.admin.enterprise.upsale.benefits.professional_support_text") %>
</p>
<% else %>
<%= render(Primer::Beta::Text.new) { feature_description } %>
<% end %>
<p class="upsale--feature-reference">
<%= more_info %>
</p>
<% if feature_video.present? %>
<%= video_tag feature_video, controls: false, class: "widget-box--teaser-video", autoplay: true, loop: true, muted: true %>
<% elsif feature_image.present? %>
<%= image_tag feature_image, class: "widget-box--teaser-image" %>
<% else %>
<%= image_tag "enterprise-add-on.svg", class: "widget-box--teaser-image_default" %>
<% end %>
<p> <%= feature_title %> <%= t("admin.enterprise.enterprise_info_html") %>
<br>
<%= t("admin.enterprise.upgrade_info") %>
</p>
<%=
render(Primer::OpenProject::FlexLayout.new(align_items: :center, style: "justify-self: center")) do |flex|
flex.with_column do
render(Primer::Beta::Button.new(
tag: :a,
scheme: :secondary,
href: OpenProject::Static::Links.links[:contact_us][:href],
target: "_blank",
title: t("admin.enterprise.buttons.contact"),
aria_label: t("admin.enterprise.buttons.contact"),
)) { t("admin.enterprise.buttons.contact") }
end
flex.with_column(ml: 1) do
render(Primer::Beta::Button.new(
tag: :a,
scheme: :primary,
href: OpenProject::Static::Links.links[:pricing][:href],
target: "_blank",
title: t("admin.enterprise.buttons.upgrade"),
aria_label: t("admin.enterprise.buttons.upgrade"),
)) do |link|
link.with_leading_visual_icon(icon: :"op-enterprise-addons")
t("admin.enterprise.buttons.upgrade")
end
end
flex.with_column(ml: 1) do
angular_component_tag("opce-free-trial-button")
end
end
%>
</div>
@@ -27,11 +27,9 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<% html_title t(:label_administration), t("settings.antivirus.title") %>
<% html_title t(:label_administration), t("custom_actions.upsale.title") %>
<%= render template: "common/upsale",
locals: {
feature_title: t("settings.antivirus.title"),
feature_description: t("settings.antivirus.upsale.description"),
feature_reference: "antivirus_scanning"
} %>
<%= render EnterpriseEdition::UpsalePageComponent.new(
:custom_actions,
video: "enterprise/custom-actions.mp4"
) %>
+4 -8
View File
@@ -29,11 +29,7 @@ See COPYRIGHT and LICENSE files for more details.
<% html_title t(:label_administration), t(:label_custom_style) %>
<%= render template: "common/upsale",
locals: {
feature_title: t(:label_custom_style),
feature_description: t("admin.custom_styles.customize"),
feature_more_info: t("admin.custom_styles.enterprise_more_info"),
feature_reference: "enterprise-custom-styles",
feature_video: "enterprise/custom-design.mp4"
} %>
<%= render EnterpriseEdition::UpsalePageComponent.new(
:define_custom_style,
video: "enterprise/custom-design.mp4"
) %>
+4 -9
View File
@@ -1,11 +1,6 @@
<% html_title t("js.notifications.title") %>
<% content_for :content_body do %>
<%= render template: "common/upsale",
locals: {
feature_title: t("enterprise_features.date_alerts"),
feature_description: t("ee.upsale.date_alerts.description"),
feature_reference: "enterprise-date-alerts",
feature_video: "enterprise/date-alert-notifications.mp4"
} %>
<% end %>
<%= render EnterpriseEdition::UpsalePageComponent.new(
:date_alerts,
video: "enterprise/date-alert-notifications.mp4"
) %>
@@ -1,11 +1,6 @@
<% html_title t("js.notifications.title") %>
<% content_for :content_body do %>
<%= render template: "common/upsale",
locals: {
feature_title: t("enterprise_features.work_package_sharing"),
feature_description: t("ee.upsale.work_package_sharing.description"),
feature_reference: "enterprise-work-package-sharing",
feature_video: "enterprise/share-work-package.mp4"
} %>
<% end %>
<%= render EnterpriseEdition::UpsalePageComponent.new(
:work_package_sharing,
video: "enterprise/share-work-package.mp4"
) %>
+2 -7
View File
@@ -62,11 +62,6 @@ See COPYRIGHT and LICENSE files for more details.
<%= render PlaceholderUsers::TableComponent.new(rows: @placeholder_users) %>
<% else %>
<%= render template: "common/upsale",
locals: {
feature_title: I18n.t("placeholder_users.upsale.title"),
feature_description: I18n.t("placeholder_users.upsale.description"),
feature_reference: "placeholder_users",
feature_video: "enterprise/placeholder_users.mp4"
} %>
<%= render EnterpriseEdition::UpsalePageComponent.new(:placeholder_users,
video: "enterprise/placeholder_users.mp4") %>
<% end %>
+15 -17
View File
@@ -72,9 +72,6 @@ en:
main-menu-bg-selected-background: "Main menu when selected"
main-menu-bg-hover-background: "Main menu on hover"
custom_colors: "Custom colors"
customize: "Customize your OpenProject installation with your own logo and colors."
enterprise_notice: "As a special 'Thank you!' for their financial contribution to develop OpenProject, this tiny add-on is only available for Enterprise edition support subscribers."
enterprise_more_info: "Note: the used logo will be publicly accessible."
manage_colors: "Edit color select options"
instructions:
primary-button-color: "Strong accent color, used for the most important button on a screen."
@@ -237,9 +234,6 @@ en:
new: "New custom action"
edit: "Edit custom action %{name}"
execute: "Execute %{name}"
upsale:
title: "Custom actions"
description: "Custom actions are one-click shortcuts to a set of pre-defined actions that you can make available on certain work packages based on status, role, type or project."
custom_fields:
admin:
@@ -587,12 +581,6 @@ en:
the data of another deleted account.
irreversible: "This action is irreversible"
confirmation: "Enter the placeholder user name %{name} to confirm the deletion."
upsale:
title: Placeholder users
description: >
Placeholder users are a way to assign work packages to users who are not part of your project.
They can be useful in a range of scenarios; for example, if you need to track tasks for a resource that is not yet named or available,
or if you dont want to give that person access to OpenProject but still want to track tasks assigned to them.
prioritiies:
edit:
priority_color_text: |
@@ -2065,9 +2053,21 @@ en:
description: "With date alerts, you will be notified of upcoming start or finish dates so that you never miss or forget an important deadline."
work_package_sharing:
description: "Share work packages with users who are not members of the project."
define_custom_style:
title: "Custom color theme and logo"
more_info: "Note: the used logo will be publicly accessible."
description: Customize your OpenProject installation with your own logo and colors.
custom_actions:
title: "Custom actions"
description: "Custom actions are one-click shortcuts to a set of pre-defined actions that you can make available on certain work packages based on status, role, type or project."
virus_scanning:
description: "Ensure uploaded files in OpenProject are scanned for viruses before being accessible by other users."
placeholder_users:
title: Placeholder users
description: >
Placeholder users are a way to assign work packages to users who are not part of your project.
They can be useful in a range of scenarios; for example, if you need to track tasks for a resource that is not yet named or available,
or if you dont want to give that person access to OpenProject but still want to track tasks assigned to them.
enumeration_activities: "Time tracking activities"
enumeration_work_package_priorities: "Work package priorities"
enumeration_reported_project_statuses: "Reported project status"
@@ -3911,8 +3911,6 @@ en:
Virus scanning has been enabled successfully.
There are %{file_count} that were uploaded previously and still need to be scanned.
This process has been scheduled in the background. The files will remain accessible during the scan.
upsale:
description: "Ensure uploaded files in OpenProject are scanned for viruses before being accessible by other users."
actions:
delete: "Delete the file"
quarantine: "Quarantine the file"
+20
View File
@@ -153,6 +153,26 @@ enterprise_docs:
href: https://www.openproject.org/docs/user-guide/agile-boards/#action-boards-enterprise-add-on
custom_field_hierarchies:
href: https://www.openproject.org/docs/system-admin-guide/custom-fields/#hierarchy-custom-field-enterprise-add-on
define_custom_style:
href: https://www.openproject.org/enterprise-edition
custom_actions:
href: https://www.openproject.org/enterprise-edition
date_alerts:
href: https://www.openproject.org/enterprise-edition
work_package_sharing:
href: https://www.openproject.org/enterprise-edition
virus_scanning:
href: https://www.openproject.org/enterprise-edition
sso_auth_providers:
href: https://www.openproject.org/enterprise-edition
ldap_groups:
href: https://www.openproject.org/enterprise-edition
team_planner:
href: https://www.openproject.org/enterprise-edition
placeholder_users:
href: https://www.openproject.org/enterprise-edition
one_drive_sharepoint_file_storage:
href: https://www.openproject.org/enterprise-edition
sysadmin_docs:
saml:
href: https://www.openproject.org/docs/system-admin-guide/authentication/saml/
@@ -1,28 +1,3 @@
.upsale-notification
max-width: 50vw
margin: auto
padding-top: 20px
text-align: center
.widget-box--teaser-image,
.widget-box--teaser-video
width: 100%
height: auto
margin-bottom: 20px
box-shadow: 4px 4px 10px rgb(0 0 0 / 15%)
border-radius: 25px
border: 1px solid var(--borderColor-default)
.widget-box--teaser-image_default
width: 30%
margin-bottom: 20px
box-shadow: 4px 4px 10px rgb(0 0 0 / 15%)
border-radius: 25px
a.button,
a.button--link
text-decoration: none
.upsale-actions
display: flex
flex-wrap: wrap
@@ -1,9 +1,3 @@
<% html_title(t(:label_administration), t("ldap_groups.synchronized_groups.plural")) -%>
<%= render template: "common/upsale",
locals: {
feature_title: t("ldap_groups.synchronized_groups.plural"),
feature_description: t("ldap_groups.synchronized_groups.upsale.description"),
feature_reference: "enterprise-ldap-groups",
feature_image: "enterprise/ldap-groups.jpg"
} %>
<%= render EnterpriseEdition::UpsalePageComponent.new(:ldap_groups, image: "enterprise/ldap-groups.jpg") %>
@@ -1,4 +1,9 @@
en:
ee:
upsale:
ldap_groups:
title: 'LDAP group synchronization'
description: 'Synchronize LDAP groups with OpenProject groups to manage users, change their permissions and facilitate user management across groups.'
plugin_openproject_ldap_groups:
name: "OpenProject LDAP groups"
description: "Synchronization of LDAP group memberships."
@@ -1,9 +1,5 @@
<% html_title(t(:label_administration), t("storages.upsale.title")) -%>
<%= render template: "common/upsale",
locals: {
feature_title: t("storages.upsale.title"),
feature_description: t("storages.upsale.description"),
feature_reference: "one_drive_sharepoint_file_storage",
feature_video: "enterprise/one_drive_sharepoint_integration.mp4"
} %>
<%= render EnterpriseEdition::UpsalePageComponent.new(:one_drive_sharepoint_file_storage,
video: "enterprise/one_drive_sharepoint_integration.mp4",
i18n_scope: "storages.upsale") %>
@@ -1,10 +1,4 @@
<% html_title(t(:label_administration), t("team_planner.upsale.title")) -%>
<%= render template: "common/upsale",
locals: {
feature_title: t("team_planner.upsale.title"),
feature_description: t("team_planner.upsale.description"),
feature_reference: "team_planner",
feature_video: "enterprise/team-planner-animation.mp4",
additional_classes: "upsale-notification_hide-breadcrumb"
} %>
<%= render EnterpriseEdition::UpsalePageComponent.new(:team_planner_view,
video: "enterprise/team-planner-animation.mp4") %>
+8 -3
View File
@@ -8,12 +8,17 @@ en:
permission_manage_team_planner: "Manage team planner"
project_module_team_planner_view: "Team planners"
ee:
feature_names:
team_planner_view: "Team planner"
upsale:
team_planner_view:
title: "Team planner"
description: "Get a complete overview of your teams planning with Team Planner. Stretch, shorten and drag-and-drop work packages to modify dates, move them or change assignees."
team_planner:
label_team_planner: "Team planner"
label_new_team_planner: "New team planner"
label_create_new_team_planner: "Create new team planner"
label_team_planner_plural: "Team planners"
label_assignees: "Assignees"
upsale:
title: "Team planner"
description: "Get a complete overview of your teams planning with Team Planner. Stretch, shorten and drag-and-drop work packages to modify dates, move them or change assignees."
@@ -1,9 +0,0 @@
<% html_title(t(:label_administration), t("two_factor_authentication.settings.title")) -%>
<%= render template: "common/upsale",
locals: {
feature_title: t("two_factor_authentication.upsale.title"),
feature_description: t("two_factor_authentication.upsale.description"),
feature_reference: "2fa",
feature_image: "enterprise/two-factor-authentication.jpg"
} %>
@@ -46,8 +46,7 @@ RSpec.describe CustomActionsController, with_ee: %i[custom_actions] do
end
it "renders enterprise_token" do
expect(response)
.to render_template "common/upsale"
expect(response).to render_template "custom_actions/upsale"
end
end
end