Files
dunlop-core/app/helpers/dunlop/application_helper.rb
T
2018-01-20 13:02:44 -03:00

271 lines
11 KiB
Ruby

module Dunlop
module ApplicationHelper
include Dunlop::ActiveClassHelper
include Dunlop::AuthorizationHelper
include Dunlop::TableHelper
include Dunlop::StateBadgeHelper
include Dunlop::InterpretedTextHelper
delegate :mathjax_path, to: :main_app
def application_name
Rails.application.config.application_name || Rails.application.class.name.deconstantize
end
def search_result_info(records)
from_item = (records.current_page - 1) * records.limit_value + 1
to_item = [from_item + records.size - 1, records.total_count].min
from_item = 0 if records.total_count.zero?
"#{from_item} - #{to_item} / #{records.total_count}"
end
def body_classes
classes = []
classes << 'archived-mode' if session[:archived_mode]
classes
end
# Use this helper to show a boolean. Then a unifor way of displaying can be implemented.
def boolean_show(value)
content_tag(:i, nil, class: ['boolean-show', (value.present? ? 'yes checkmark box icon' : 'no square outline icon')])
end
def show_address(record)
[record.zipcode, "#{record.housenumber}#{record.housenumber_ext}"].map(&:presence).compact.join(' ')
end
# https://coderwall.com/p/7gqmog/display-flash-messages-with-semantic-ui-in-rails
def flash_class(level)
case level.to_sym
when :success then "ui positive message"
when :error, :alert then "ui negative message"
when :notice then "ui info message"
else "ui #{level} message"
end
end
#def render_cascaded(*args)
# options = args.extract_options!
# controller_parts = controller_path.split('/')
# if args.first.is_a?(String) or options[:partial].present?
# partial_name = args.first.presence || options[:partial]
# lookup_name = "_#{partial_name}"
# controller_parts.pop until lookup_context.template_exists?(File.join(*controller_parts, lookup_name))
# options[:partial] = File.join(*controller_parts, partial_name)
# render options
# elsif options[:template].present?
# lookup_name = options[:template]
# controller_parts.pop until lookup_context.template_exists?(File.join(*controller_parts, lookup_name))
# options[:template] = File.join(*controller_parts, lookup_name)
# render options
# else
# render *args
# end
#end
# Try to find a template containing the workflow step info specification of the record
# and render nothing if it cannot be found
# an OwnerServiceWindow1Preparation::Scenario1 record will search for a template
# named "info_fields" in the following locations:
# app/views/owner_service_window1_preparations/scenario1s/info_fields.html.haml
# app/views/owner_service_window1_preparations/info_fields.html.haml
def record_info_fields(record, options = {})
lookup_cascade = record.class.name.underscore.split('/').map(&:pluralize)
lookup_name = 'info_fields'
template_path = File.join(*lookup_cascade, lookup_name)
until lookup_context.template_exists?(template_path) or lookup_cascade.empty?
return if lookup_cascade.empty? # not template for record found
lookup_cascade.pop
template_path = File.join(*lookup_cascade, lookup_name)
end
render template: template_path, locals: options.merge(record: record) if lookup_context.template_exists?(template_path)
end
def scope_model(model = nil)
@scope_model = model if model
@scope_model
end
def at(attribute_name, scope_model=nil)
scope_model ||= @scope_model
scope_model.human_attribute_name(attribute_name)
end
def page_title(*args)
res = content_tag :h3, class: 'page-title ui header' do
if resource_title?(args)
@scope_model = args[1].is_a?(ActiveRecord::Base) ? args[1].class : args[1]
page_title_for_resource(args)
else
page_title_for_string(args)
end
end
content_for :page_title, res
res
end
def resource_title?(args)
args.first.is_a?(Symbol) &&
(args[1].respond_to?(:model_name) || args[1].class.respond_to?(:model_name))
end
def page_title_for_string(args)
args.first
end
def page_title_for_resource(args)
options = args.extract_options!
model = args[1].respond_to?(:model_name) ? args[1] : args[1].class
if args.first == :index
title = t('action.index.label', models: model.model_name.human_plural)
else
title = t("action.#{args.first}.label", model: model.model_name.human)
end
if back_options = options[:back]
url =
case back_options
when Array then polymorphic_path(back_options)
when true then :back
else back_options
end
if url
back_link = link_to content_tag(:i, nil, class: 'left arrow icon'), url, class: 'title-back-link'
title = [back_link, title].join.html_safe
end
end
title
end
# It returns a proper array to select the hour of the day
def hours_for_select
(0..23).map{|v| DayTimeMinutes.new 60 * v }
end
# This is a wrapper to create collapsible content.
def collapsible_content(title, options = {}, &blk)
content = capture(&blk) if blk.present?
content ||= options.delete(:content)
collapsed = options.has_key?(:collapsed) ? options.delete(:collapsed) : true
classes = Array.wrap(options[:class]) | ["collapsible-container", collapsed ? 'collapsed' : nil]
title_tag = content_tag(:div, "<span></span>#{title}".html_safe, class: 'collapsible-title')
content_tag(:div, title_tag + content_tag(:div, content, class: 'collapsible-content'), options.merge(class: classes))
end
# Need a custom one, since rails still does not support non present dates
def dunlop_localize(date, options = {})
return '' unless date.present?
l(date, options)
end
# Return a page relative time tag. The current time is meant to be replaced by relative time from
# the moment javascript library
def page_time(time = Time.current)
content_tag(:span, time, id: 'page-time', data: {time: time.utc.iso8601, format: 'relative'})
end
# Tested through the migration decorator
def plan_date(options = {})
return '' unless options[:date] or options[:window_from] or options[:window_to]
date = options[:date].try(:strftime, '%d-%m-%Y')
window = ''
if options[:window_from].present? or options[:window_to].present?
window_from_display = options[:window_from].present? ? "#{options[:window_from]}:00&nbsp;" : ''
window_to_display = options[:window_to].present? ? "&nbsp;#{options[:window_to]}:00" : ''
window = "&nbsp;#{content_tag(:span, '', class: 'fa fa-clock-o')}&nbsp;&nbsp;#{window_from_display}-#{window_to_display}"
end
"#{date} #{window}".strip.html_safe
end
def plan_date_for_record(record)
return '' unless record.present?
plan_date(
date: record.plan_date,
window_from: record.window_from,
window_to: record.window_to
)
end
def empty_collection(model)
content_tag(:div, t('collection.empty', models: model.model_name.human_plural), class: 'empty-collection')
end
def workflow_step_buttons_for(workflow_instance_class)
#buttons = []
#record_class.workflow_step_classes.each do |workflow_step|
# next unless can?(:manage, workflow_step)
# base_name = workflow_step.name.underscore.split('/').first
# buttons << content_tag(:button, t('perform_batch_actions_button', scope: base_name), class: "#{base_name.pluralize}-actions", data: {action: 'workflow_step', workflow_step: base_name})
#end
#buttons.join.html_safe
workflow_instance_class.workflow_step_classes.map{|workflow_step| workflow_step_button_for workflow_step }.compact.join.html_safe
end
def workflow_step_button_for(workflow_step, data_attributes = {})
return unless can?(:manage, workflow_step)
base_name = workflow_step.name.underscore.split('/').first
data_attributes[:action] ||= 'collection_edit'
data_attributes[:resource] ||= workflow_step.name.underscore
data_attributes[:request_params] = data_attributes[:request_params].to_json if data_attributes[:request_params].is_a?(Hash)
data_attributes[:request_params] ||= {workflow_instance_ids: 'selected_ids'}.to_json
text = t('workflow_step.update_button_text', models: workflow_step.model_name.human_plural)
content = content_tag(:span, text, class: 'text') + content_tag(:span, '', class: 'icon')
content_tag(:button, content, class: "#{base_name.pluralize}-actions workflow-step-actions collection-edit", data: data_attributes)
end
def human_duration(duration)
return duration.inspect unless duration.is_a?(ActiveSupport::Duration)
# taken and modified from ActiveSupport::Duration#inspect version 4.2.6
duration.parts.
reduce(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }.
sort_by {|unit, _ | [:years, :months, :days, :minutes, :seconds].index(unit)}.
map {|unit, val| "#{val} #{val == 1 ? t(unit, scope: 'dunlop.duration', default: unit.to_s.chop) : t(unit, scope: 'dunlop.duration.plural', default: unit.to_s)}"}.
to_sentence(locale: ::I18n.locale)
end
def render_as_dunlop_modal(partial_name, options={})
render "dunlop/workflow_step/modal_renderer", partial_name: partial_name, options: options
end
def dunlop_class_ability(permission, klass, options={})
user = options[:user] || @user
check_box_tag "user[role_names][]", "#{permission}-class-#{klass.name}", user.role_names.include?("#{permission}-class-#{klass.name}"), id: "role-#{klass.name.underscore.parameterize}"
end
def dunlop_ability(permission, type, target, options={})
user = options[:user] || @user
authorization = [permission, type, target].join('-')
check_box_tag "user[role_names][]", authorization, user.role_names.include?(authorization), id: "role-#{authorization}"
end
def tarray(array, options={})
array.map do |entry|
if entry.respond_to?(:model_name)
if can?(:read, entry)
[entry.model_name.human, entry]
end
else
[entry, entry]
end
end.compact
end
def link_to_model(model)
return nil unless model.present?
return nil unless can?(:read, model)
class_base = model.class.name.deconstantize
name = model.try(:presentation_name) || model.try(:model_name).try(:human) || model.class.name
if %w[SourceFile ExecutionBatch].include?(class_base)
path = dunlop.polymorphic_path(model.becomes(class_base.constantize)) rescue nil
else
path = main_app.polymorphic_path(model) rescue nil
#TODO: handle becomes?
end
return model.try(:presentation_name) unless path.present?
link_to name, path
end
end
end