Skip to content

Commit

Permalink
feat[Op#50985]: Separate primer banner from FlashMessageComponent
Browse files Browse the repository at this point in the history
  • Loading branch information
akabiru committed Nov 23, 2023
1 parent dc09586 commit a6195e6
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 43 deletions.
22 changes: 9 additions & 13 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,23 +115,23 @@ def due_date_distance_in_words(date)
end
end

def render_primer_flash_message?
flash[:primer_flash].present?
def render_primer_banner_message?
flash[:primer_banner].present?
end

def render_primer_flash_message
return unless render_primer_flash_message?
def render_primer_banner_message
return unless render_primer_banner_message?

render(FlashMessageComponent.new(**flash[:primer_flash].to_hash))
render(BannerMessageComponent.new(**flash[:primer_banner].to_hash))
end

# Renders flash messages
def render_legacy_flash_messages
return if render_primer_flash_message?
def render_flash_messages
return if render_primer_banner_message?

messages = flash
.reject { |k, _| k.start_with? '_' }
.map { |k, v| render_legacy_flash_message(k, v) }
.map { |k, v| render_flash_message(k, v) }

safe_join messages, "\n"
end
Expand All @@ -144,24 +144,20 @@ def join_flash_messages(messages)
end
end

def render_legacy_flash_message(type, message, html_options = {}) # rubocop:disable Metrics/AbcSize
def render_flash_message(type, message, html_options = {})
if type.to_s == 'notice'
type = 'success'
end

toast_css_classes = ["op-toast -#{type}", html_options.delete(:class)]

# Add autohide class to notice flashes if configured
if type.to_s == 'success' && User.current.pref.auto_hide_popups?
toast_css_classes << 'autohide-toaster'
end

html_options = { class: toast_css_classes.join(' '), role: 'alert' }.merge(html_options)
close_button = content_tag :a, '', class: 'op-toast--close icon-context icon-close',
title: I18n.t('js.close_popup_title'),
tabindex: '0'
toast = content_tag(:div, join_flash_messages(message), class: 'op-toast--content')

content_tag :div, '', class: 'op-toast--wrapper' do
content_tag :div, '', class: 'op-toast--casing' do
content_tag :div, html_options do
Expand Down
4 changes: 2 additions & 2 deletions app/views/layouts/base.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,15 @@ See COPYRIGHT and LICENSE files for more details.
<% end %>
<div class="content-overlay"></div>
<main id="content-wrapper" class="<%= initial_classes %>">
<%= render_primer_flash_message %>
<%= render_primer_banner_message %>
<% if show_decoration %>
<div id="breadcrumb" class="<%= initial_classes %><%= show_breadcrumb ? ' -show' : '' %>">
<%= you_are_here_info %>
<%= full_breadcrumb %>
<%= call_hook :view_layouts_base_breadcrumb %>
</div>
<% end %>
<%= render_legacy_flash_messages %>
<%= render_flash_messages %>
<% if show_onboarding_modal? %>
<section data-augmented-model-wrapper
data-modal-initialize-now="true"
Expand Down
32 changes: 32 additions & 0 deletions modules/meeting/app/components/banner_message_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<%#-- copyright
OpenProject is an open source project management software.
Copyright (C) 2012-2023 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::Banner.new(full:, full_when_narrow:, dismiss_scheme:, icon:, scheme:,test_selector:)) { message }
%>
44 changes: 44 additions & 0 deletions modules/meeting/app/components/banner_message_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2023 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 BannerMessageComponent < ApplicationComponent # rubocop:disable OpenProject/AddPreviewForViewComponent
def initialize(message: nil, full: false, full_when_narrow: false, dismiss_scheme: :none, icon: false, scheme: :default,
test_selector: "primer-banner-message-component")
super

@message = message
@full = full
@full_when_narrow = full_when_narrow
@dismiss_scheme = dismiss_scheme
@icon = icon
@scheme = scheme
@test_selector = test_selector
end

attr_reader :message, :full, :full_when_narrow, :dismiss_scheme, :icon, :scheme, :test_selector
end
31 changes: 7 additions & 24 deletions modules/meeting/app/components/flash_message_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,49 +31,32 @@ class FlashMessageComponent < ApplicationComponent
include OpTurbo::Streamable
include OpPrimer::ComponentHelpers

def initialize(message: nil, full: false, full_when_narrow: false, dismissible: false, icon: false, scheme: :default,
test_selector: "primer-flash-message-component")
def initialize(message: nil, full: false, spacious: false, dismissible: false, icon: nil, scheme: :default)
super

@message = message
@full = full
@full_when_narrow = full_when_narrow
@dismissible = dismissible
@spacious = spacious
@dismissible = dismissible # TODO: not working yet -> JS dependency not provided?
@icon = icon
@scheme = scheme
@test_selector = test_selector
end

def call
component_wrapper do
# even without provided message, the wrapper should be rendered as this allows
# for triggering a flash message via turbo stream
if message.present?
if @message.present?
flash_partial
end
end
end

private

attr_reader :message, :full, :full_when_narrow, :dismissible, :icon, :scheme, :test_selector

def flash_partial
# The banner component is similar to the flash message component, but is more feature rich.
# - It ALWAYS renders with an icon
# - It can be dismissed
# - It allows for custom actions while flash messages only allow for a dismiss action (which doesn't work yet :/)
# See https://primer.style/components/banner/rails/alpha
render(
Primer::Alpha::Banner.new(
full:, full_when_narrow:,
dismiss_scheme:, icon:, scheme:,
test_selector:
)
) { message }
end

def dismiss_scheme
dismissible ? :remove : :none
render(Primer::Beta::Flash.new(
full: @full, spacious: @spacious, dismissible: @dismissible, icon: @icon, scheme: @scheme
)) { @message }
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ def create
service_result = call_update_service

if service_result.success?
flash[:primer_flash] = {
flash[:primer_banner] = {
message: I18n.t(:'storages.notice_successful_storage_connection'),
scheme: :success,
dismissible: true,
dismiss_scheme: :hide,
full: true
}
redirect_to admin_settings_storages_path
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ def create # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
format.turbo_stream { render :create }
end
elsif @storage.provider_type_one_drive?
flash[:primer_flash] = {
flash[:primer_banner] = {
message: I18n.t(:'storages.notice_successful_storage_connection'),
scheme: :success,
dismissible: true,
dismiss_scheme: :hide,
full: true
}
redirect_to admin_settings_storages_path
Expand Down

0 comments on commit a6195e6

Please sign in to comment.