class Marty::ReportForm < Marty::Form # override apply for background generation action :apply do |a| a.text = a.tooltip = I18n.t('reporting.background') a.handler = :netzke_on_apply a.icon_cls = 'fa fa-cloud glyph' a.disabled = false end action :foreground do |a| a.text = a.tooltip = I18n.t('reporting.generate') a.icon_cls = 'fa fa-download glyph' a.disabled = false end action :link do |a| a.text = a.tooltip = I18n.t('reporting.link') a.icon_cls = 'fa fa-link glyph' a.disabled = false end ###################################################################### def default_bbar [ '->', :apply, :foreground, :link ] end ###################################################################### def self.get_report_engine(params) d_params = ActiveSupport::JSON.decode(params[:data] || '{}') d_params.each_pair do |k, v| d_params[k] = nil if v.blank? || v == 'null' end tag_id = d_params.delete('selected_tag_id') script_name = d_params.delete('selected_script_name') node = d_params.delete('selected_node') engine = Marty::ScriptSet.new(tag_id).get_engine(script_name) roles = engine.evaluate(node, 'roles', {}) rescue nil if roles && !roles.any? { |r| Marty::User.has_role(r) } # insufficient permissions return [] end d_params['p_title'] ||= engine.evaluate(node, 'title', {}).to_s [engine, d_params, node] end def self.run_eval(params) engine, d_params, node = get_report_engine(params) raise 'Insufficient permissions' unless engine raise 'no selected report node' unless String === node begin engine.evaluate(node, 'result', d_params) rescue StandardError => exc Marty::Util.logger.error "run_eval failed: #{exc.backtrace}" res = Delorean::Engine.grok_runtime_exception(exc) res['backtrace'] = res['backtrace'].map { |m, line, fn| "#{m}:#{line} #{fn}" }.join('\n') res end end endpoint :submit do |params| # We get here when user is asking for a background report engine, d_params, node = self.class.get_report_engine(params) return client.netzke_notify 'Insufficient permissions to run report!' unless engine # start background promise to get report result engine.background_eval(node, d_params, ['result', 'title', 'format'], ) client.netzke_notify 'Report can be accessed from the Jobs Dashboard ...' end ###################################################################### client_class do |c| # Find the mount path for the Marty engine. FIXME: this is likely # very brittle. @@mount_path = Rails.application.routes.routes.detect do |r| r.app.app == Marty::Engine end.format({}) c.mount_path = l(<<-JS) function() { return "#{@@mount_path}" } JS c.include :report_form end endpoint :netzke_load do |params| end def eval_form_items(engine, items) case items when Array items.map { |x| eval_form_items(engine, x) } when Hash items.each_with_object({}) do |(key, value), result| result[key] = eval_form_items(engine, value) end when String items.starts_with?(':') ? items[1..-1].to_sym : items when Class raise "bad value in form #{items}" unless items < Delorean::BaseModule::BaseClass attrs = engine.enumerate_attrs_by_node(items) engine.eval_to_hash(items, attrs, {}) when Numeric, TrueClass, FalseClass items else raise "bad value in form #{items}" end end def configure(c) super unless root_sess[:selected_script_name] && root_sess[:selected_node] c.title = 'No Report selected.' return end begin sset = Marty::ScriptSet.new(root_sess[:selected_tag_id]) engine = sset.get_engine(root_sess[:selected_script_name]) raise engine.to_s if engine.is_a?(Hash) items, title, format = engine. evaluate(root_sess[:selected_node], ['form', 'title', 'format'], {}, ) raise 'bad form items' unless items.is_a?(Array) raise 'bad format' unless Marty::ContentHandler::GEN_FORMATS.member?(format) rescue StandardError => exc c.title = 'ERROR' c.items = [ { field_label: 'Exception', xtype: :displayfield, name: 'displayfield1', value: "#{exc}" }, ] return end # if there's a background_only flag, we disable the foreground submit background_only = engine.evaluate(root_sess[:selected_node], 'background_only') rescue nil items = Marty::Xl.symbolize_keys(eval_form_items(engine, items), ':') items = [{ html: '
No input is needed for this report.' }] if items.empty? # add hidden fields for selected tag/script/node items += [:selected_tag_id, :selected_script_name, :selected_node, # just for testing :selected_testing,].map do |f| { name: f, xtype: :textfield, hidden: true, value: root_sess[f], } end c.items = items c.repformat = format c.title = "Generate: #{title}-#{sset.tag.name}" c.reptitle = title c.authenticity_token = controller.send(:form_authenticity_token) [:foreground, :link].each { |a| actions[a].disabled = !!background_only } end end ReportForm = Marty::ReportForm