class Gzr::Commands::Dashboard::Import

Public Class Methods

new(file, dest_space_id, options) click to toggle source
Calls superclass method Gzr::Command::new
# File lib/gzr/commands/dashboard/import.rb, line 41
def initialize(file, dest_space_id, options)
  super()
  @file = file
  @dest_space_id = dest_space_id
  @options = options
end

Public Instance Methods

copy_result_maker_filterables(new_element) click to toggle source
# File lib/gzr/commands/dashboard/import.rb, line 188
def copy_result_maker_filterables(new_element)
  return nil unless new_element[:result_maker]
  if new_element[:result_maker].fetch(:filterables,[]).length > 0
    result_maker = { :filterables => [] }
    new_element[:result_maker][:filterables].each do |filterable|
      result_maker[:filterables] << filterable.select do |k,v|
        true unless [:can].include? k
      end
    end
    return result_maker
  end
  nil
end
execute(input: $stdin, output: $stdout) click to toggle source
# File lib/gzr/commands/dashboard/import.rb, line 48
def execute(input: $stdin, output: $stdout)
  say_warning("options: #{@options.inspect}", output: output) if @options[:debug]
  with_session("3.1") do

    @me ||= query_me("id")

    read_file(@file) do |data|

      dashboard = sync_dashboard(data,@dest_space_id, output: output)


      dashboard[:dashboard_filters] ||= []
      source_filters = data[:dashboard_filters].sort { |a,b| a[:row] <=> b[:row] }
      source_filters.each do |new_filter|
        filter = new_filter.select do |k,v|
          (keys_to_keep('create_dashboard_filter') + [:row]).include? k
        end
        filter[:dashboard_id] = dashboard.id
        say_warning "Creating filter" if @options[:debug]
        dashboard[:dashboard_filters].push create_dashboard_filter(filter)
      end

      dashboard[:dashboard_elements] ||= []
      elem_table = data[:dashboard_elements].map do |new_element|
        element = new_element.select do |k,v|
          (keys_to_keep('create_dashboard_element') - [:dashboard_id, :look_id, :query_id, :merge_result_id, :result_maker_id]).include? k
        end
        (element[:query_id],element[:look_id],element[:merge_result_id]) = process_dashboard_element(new_element) 
        say_warning "Creating dashboard element #{element.inspect}" if @options[:debug]
        element[:dashboard_id] = dashboard.id
        result_maker = copy_result_maker_filterables(new_element)
        element[:result_maker] = result_maker if result_maker
        dashboard_element = create_dashboard_element(element)
        dashboard[:dashboard_elements].push dashboard_element
        [new_element[:id], dashboard_element.id]
      end

      source_dashboard_layouts = data[:dashboard_layouts].map do |new_layout|
        layout_obj = nil
        if new_layout[:active] 
          layout_obj = get_dashboard_layout(dashboard[:dashboard_layouts].first.id)
          say_warning "Updating layout #{layout_obj.id}" if @options[:debug]
        else  
          layout = new_layout.select do |k,v|
            (keys_to_keep('create_dashboard_layout') - [:dashboard_id]).include? k
          end
          layout[:dashboard_id] = dashboard.id
          say_warning "Creating dashboard layout #{layout}" if @options[:debug]
          layout_obj = create_dashboard_layout(layout)
        end
        layout_components = new_layout[:dashboard_layout_components].zip(layout_obj.dashboard_layout_components)
        layout_components.each do |source,target|
          component = keys_to_keep('update_dashboard_layout_component').collect do |e|
            [e,nil]
          end.to_h
          component[:dashboard_layout_id] = target.dashboard_layout_id

          component.merge!(source.select do |k,v|
            (keys_to_keep('update_dashboard_layout_component') - [:id,:dashboard_layout_id]).include? k
          end)

          component[:dashboard_element_id] = elem_table.assoc(source[:dashboard_element_id])[1]
          say_warning "Updating dashboard layout component #{target.id}" if @options[:debug]
          update_dashboard_layout_component(target.id,component)
        end
      end
      upsert_plans_for_dashboard(dashboard.id,@me.id,data[:scheduled_plans]) if data[:scheduled_plans]
      output.puts "Imported dashboard #{dashboard.id}" unless @options[:plain] 
      output.puts dashboard.id if @options[:plain] 
    end
  end
end
process_dashboard_element(dash_elem) click to toggle source
# File lib/gzr/commands/dashboard/import.rb, line 202
def process_dashboard_element(dash_elem)
  return [nil, upsert_look(@me.id, create_fetch_query(dash_elem[:look][:query]).id, @dest_space_id, dash_elem[:look]).id, nil] if dash_elem[:look]

  query = dash_elem[:result_maker]&.fetch(:query, false) || dash_elem[:query]
  return [create_fetch_query(query).id, nil, nil] if query

  merge_result = dash_elem[:result_maker]&.fetch(:merge_result, false) || dash_elem[:merge_result]
  return [nil,nil,create_merge_result(merge_result).id] if merge_result

  [nil,nil,nil]
end
sync_dashboard(source, target_space_id, output: $stdout) click to toggle source
# File lib/gzr/commands/dashboard/import.rb, line 121
def sync_dashboard(source, target_space_id, output: $stdout)
  # try to find dashboard by slug in target space
  existing_dashboard = search_dashboards_by_slug(source[:slug], target_space_id).fetch(0,nil) if source[:slug]
  # check for dash of same title in target space
  title_used = search_dashboards_by_title(source[:title], target_space_id).select {|d| !d[:deleted] }.fetch(0,nil)

  # If there is no match by slug in target space or no slug given, then we match by title
  existing_dashboard ||= title_used

  # same_title is now a flag indicating that there is already a dash in the same space with
  # that title, and it is the one we are updating.
  same_title = (title_used&.fetch(:id,nil) == existing_dashboard&.fetch(:id,nil))

  # check if the slug is used by any dashboard
  slug_used = search_dashboards_by_slug(source[:slug]).fetch(0,nil) if source[:slug]

  # same_slug is now a flag indicating that there is already a dash with
  # that slug, but it is the one we are updating.
  same_slug = (slug_used&.fetch(:id,nil) == existing_dashboard&.fetch(:id,nil))

  if slug_used && !same_slug then
    say_warning "slug #{slug_used.slug} already used for dashboard #{slug_used.title} in space #{slug_used.space_id}", output: output
    say_warning("That dashboard is in the 'Trash' but not fully deleted yet", output: output) if slug_used.deleted
    say_warning "dashboard will be imported with new slug", output: output
  end

  if existing_dashboard then
    if title_used && !same_title then
      raise Gzr::CLI::Error, "Dashboard #{source[:title]} already exists in space #{target_space_id}\nDelete it before trying to upate another dashboard to have that title."
    end
    raise Gzr::CLI::Error, "Dashboard #{existing_dashboard[:title]} with slug #{existing_dashboard[:slug]} already exists in space #{target_space_id}\nUse --force if you want to overwrite it" unless @options[:force]

    say_ok "Modifying existing dashboard #{existing_dashboard.id} #{existing_dashboard[:title]} in space #{target_space_id}", output: output
    new_dash = source.select do |k,v|
      (keys_to_keep('update_dashboard') - [:space_id,:folder_id,:user_id,:slug]).include? k
    end
    new_dash[:slug] = source[:slug] unless slug_used
    new_dash[:deleted] = false if existing_dashboard[:deleted]
    d = update_dashboard(existing_dashboard.id,new_dash)

    d.dashboard_filters.each do |f|
      delete_dashboard_filter(f.id)
    end
    d.dashboard_filters = []

    d.dashboard_elements.each do |e|
      delete_dashboard_element(e.id)
    end
    d.dashboard_elements = []

    d.dashboard_layouts.each do |l|
      delete_dashboard_layout(l.id) unless l.active
    end
    d.dashboard_layouts.select! { |l| l.active }

    return d
  else
    new_dash = source.select do |k,v|
      (keys_to_keep('create_dashboard') - [:space_id,:folder_id,:user_id,:slug]).include? k
    end
    new_dash[:slug] = source[:slug] unless slug_used
    new_dash[:space_id] = target_space_id
    new_dash[:user_id] = @me.id
    return create_dashboard(new_dash)
  end
end