271 lines
11 KiB
Ruby
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 " : ''
|
|
window_to_display = options[:window_to].present? ? " #{options[:window_to]}:00" : ''
|
|
window = " #{content_tag(:span, '', class: 'fa fa-clock-o')} #{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
|