module HaveAPI::Fs::Components
class ResourceDir < Directory
component :resource_dir
attr_reader :resource
def initialize(resource)
super()
@resource = resource
end
def setup
super
@index = use(:actions, :index)
@data = nil
end
def contents
load_contents if @index && (!@data || @refresh)
ret = super + %w(actions) + subresources.map(&:to_s)
ret.concat(@data.map { |v| v.id.to_s }) if @data
ret << 'create.yml' if find(:actions).find(:create)
if @index
ret.concat(@index.action.input_params.keys.map { |v| "by-#{v}" })
end
ret
end
def refresh
@refresh = true
end
def delete(id)
return unless @data
i = @data.index { |v| v.id == id }
@data.delete_at(i) if i
end
def title
"Resource #{@resource._name.to_s.capitalize}"
end
protected
def new_child(name)
if child = super
child
elsif name == :actions
[ResourceActionDir, @resource]
elsif subresources.include?(name)
[ResourceDir, @resource.send(name)]
elsif /^\d+$/ =~ name
id = name.to_s.to_i
if @data
r = @data.detect { |v| v.id == id }
[ResourceInstanceDir, r] if r
else
begin
obj = @resource.show(id, meta: meta_params)
case @resource.actions[:show].output_layout
when :object
[ResourceInstanceDir, obj]
when :hash
[ResourceInstanceDir, HaveAPI::Fs::HashWrapper.new(
@resource.instance_variable_get('@client'),
@resource.instance_variable_get('@api'),
@resource,
@resource.actions[:show],
obj.response
)]
else
fail "Unexpected layout '#{@resource.actions[:show].output_layout}'"
end
rescue HaveAPI::Client::ActionFailed
end
end
elsif name == :'create.yml' && create_dir = use(:actions, :create)
[InstanceCreate, create_dir]
elsif @index && name.to_s.start_with?('by-')
by_param = name.to_s[3..-1].to_sym
return nil unless @index.action.input_params.has_key?(by_param)
[IndexFilter, self, by_param]
else
nil
end
end
def subresources
return @subresources if @subresources
@subresources = []
@resource.resources.each do |r_name, r|
r.actions.each do |a_name, a|
if a.url.index(":#{@resource._name}_id").nil?
@subresources << r_name
break
end
end
end
@subresources
end
def meta_params
{
includes: @resource.actions[:show].params.select do |n, p|
p[:type] == 'Resource'
end.map do |n, p|
n
end.join(',')
}
end
def load_contents
if context.opts[:index_limit] && file = @index.find(:input).find(:limit)
limit = context.opts[:index_limit].to_i
v = file.value
param = @index.action.input_params[:limit]
if (!v && !param[:default]) \
|| (v && v > limit) \
|| (param[:default] && param[:default] > limit)
file.write_safe(limit)
end
end
@index.exec(meta: meta_params)
new_data = @index.output.data
if @data
current_map = id_map(@data)
res = []
new_data.each do |v|
if current_map.has_key?(v.id)
res << current_map[v.id]
else
res << v
end
end
@data = res
else
@data = new_data
end
changed
@refresh = false
end
def id_map(list)
ret = {}
list.each { |v| ret[v.id] = v }
ret
end
end
end