Skip to content

Commit

Permalink
Refs #35274 - Add possibility to re-use columns
Browse files Browse the repository at this point in the history
  • Loading branch information
ofedoren committed Jul 28, 2022
1 parent 8e1c80c commit 05b9415
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 14 deletions.
33 changes: 29 additions & 4 deletions app/registries/foreman/selectable_columns/category.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,51 @@ module SelectableColumns
class Category < Array
attr_reader :id, :label

def initialize(id, label, default: false)
def initialize(id, label, table, default: false)
@id = id
@label = label
@table = table
@default = default
@columns_to_use = HashWithIndifferentAccess.new
super(0)
end

def column(key, th:, td:)
self << { key: key.to_s, th: th, td: td }
end

# This instance is not meant to be updated after it was created by DSL
# Thus, saving once computed keys
def use_column(key, from:)
@columns_to_use[from] ||= []
@columns_to_use[from] << key.to_s
end

# This instance can be updated after it was created by DSL, but
# only at the initialization time.
# This method is only for actual runtime usage,
# after the Storage is fully defined/updated.
# Thus, saving once computed result.
def keys
@keys ||= map { |c| c[:key] }.sort
@keys ||= columns.map { |c| c[:key] }.sort
end

def default?
@default
end

def columns
self + foreign_columns
end

private

# This is meant for actual runtime usage,
# after the categories are fully defined.
# Thus, saving once computed result.
def foreign_columns
@foreign_columns ||= @columns_to_use.keys.map do |category_id|
@table.find { |cat| cat.id == category_id }.select { |col| @columns_to_use[category_id].include?(col[:key]) }
end.flatten
end
end
end
end
20 changes: 12 additions & 8 deletions app/registries/foreman/selectable_columns/storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def defined_for(table)
{
id: category.id,
name: category.label,
columns: category.map { |c| { id: c[:key], name: c[:th][:label] } },
columns: category.columns.map { |c| { id: c[:key], name: c[:th][:label] } },
}
end
end
Expand All @@ -39,13 +39,17 @@ def selected_by(user, table)
return unless tables[table]

selected_keys = user.table_preferences.find_by(name: table)&.columns&.sort
if selected_keys
tables[table].select { |category| (category.keys & selected_keys).any? }
.flatten
.select { |col| selected_keys.include?(col[:key]) }
else
tables[table].select { |category| category.default? }.flatten
end
result = if selected_keys
tables[table].select { |category| (category.keys & selected_keys).any? }
.map(&:columns)
.flatten
.select { |col| selected_keys.include?(col[:key]) }
else
tables[table].select { |category| category.default? }
.map(&:columns)
.flatten
end
result.uniq
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions app/registries/foreman/selectable_columns/table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def initialize(name)
end

def category(id, label: _('General'), default: false, &block)
category = find_or_create(id.to_sym, label, default)
category = find_or_create(id.to_s, label, default)
category.instance_eval(&block)
end

Expand All @@ -18,7 +18,7 @@ def category(id, label: _('General'), default: false, &block)
def find_or_create(id, label, default)
category = find { |c| c.id == id }
unless category
category = Category.new(id, label, default: default)
category = Category.new(id, label, self, default: default)
self << category
end
category
Expand Down
6 changes: 6 additions & 0 deletions developer_docs/how_to_create_a_plugin.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ selectable_columns :table do
},
callback: ->(record) { record.value }
}
use_column :key, from :category_id
end
end
----
Expand Down Expand Up @@ -495,6 +496,11 @@ Where for `td`:
* `callback`: [Lambda] (Required) A callback that will be used to process data to be shown.
* `attr_callbacks`: [Hash] (Optional) Only use if you need to process values for HTML attributes dynamically.

Where for `use_column`:

* `key`: [Symbol] (Required) Key of the defined column to include in the current category.
* `from`: [Symbol] (Required) ID of the category defining the column to use. Category must be in the same table.

You can also define HTML attributes for `<th>` and `<td>` tags. Some common are
listed below, but you can use your own.
_Note: all except `:callback`, `:sortable`, `:default_sort`, `:attr_callbacks`
Expand Down

0 comments on commit 05b9415

Please sign in to comment.