Class: Labimotion::ElementVariationColumnSet

Inherits:
Object
  • Object
show all
Defined in:
lib/labimotion/libs/element_variation_column_set.rb

Overview

ElementVariationColumnSet Resolves the ordered set of columns for an element's variations grid.

Both ExportElementVariations and ImportElementVariations go through this class, so a workbook written by the exporter is always readable by the importer. The ordering mirrors the React grid (GenericElementVariationsColumnDefs.js): driven by the stored layout when there is one, otherwise inferred from the variation data itself -- the same fallback the frontend applies when it loads a record with an empty layout.

Defined Under Namespace

Classes: Column

Constant Summary collapse

UUID_KEY =
'__uuid'
NAME_KEY =
'__variation'
ANALYSES_FIELD =
'__analyses__'
LAYERS =

Mirrors Labimotion::Prop::LAYERS / ::FIELDS. Held locally because requiring labimotion/utils/prop here would race the gem's autoload.

'layers'
FIELDS =
'fields'
GROUPS =
%w[properties metadata segments].freeze
GROUP_LABELS =
{
  'properties' => 'Properties',
  'metadata' => 'Metadata',
  'segments' => 'Segments'
}.freeze
METADATA_FIELDS =
%w[notes analyses group].freeze
METADATA_LABELS =
{
  'notes' => 'Notes',
  'analyses' => 'Analyses (IDs)',
  'group' => 'Group'
}.freeze
COLUMN_FIELD_TYPES =

Mirrors the field-type allowlist chem-generic-ui applies when it offers columns. select-multi deliberately has no Labimotion::FieldType constant.

%w[
  integer number select system-defined text date datetime select-multi
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(element, variation, segment_klasses: nil) ⇒ ElementVariationColumnSet

Returns a new instance of ElementVariationColumnSet.



74
75
76
77
78
79
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 74

def initialize(element, variation, segment_klasses: nil)
  @element = element
  @variations = variation.respond_to?(:variations_hash) ? variation.variations_hash : {}
  @layout = variation.respond_to?(:layout_hash) ? variation.layout_hash : {}
  @segment_klasses = segment_klasses
end

Instance Attribute Details

#elementObject (readonly)

Returns the value of attribute element.



81
82
83
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 81

def element
  @element
end

#layoutObject (readonly)

Returns the value of attribute layout.



81
82
83
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 81

def layout
  @layout
end

#variationsObject (readonly)

Returns the value of attribute variations.



81
82
83
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 81

def variations
  @variations
end

Class Method Details

.analyses_property_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
71
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 68

def analyses_property_key?(key)
  decoded = decode_property_key(key)
  !decoded.nil? && decoded[:field_key] == ANALYSES_FIELD
end

.build(element, variation, segment_klasses: nil) ⇒ Object



53
54
55
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 53

def build(element, variation, segment_klasses: nil)
  new(element, variation, segment_klasses: segment_klasses).columns
end

.decode_property_key(key) ⇒ Object



61
62
63
64
65
66
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 61

def decode_property_key(key)
  match = key.to_s.match(/\Alayer(.+?)field(.+)\z/m)
  return nil unless match

  { layer_key: match[1], field_key: match[2] }
end

.encode_property_key(layer_key, field_key) ⇒ Object



57
58
59
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 57

def encode_property_key(layer_key, field_key)
  "layer#{layer_key}field#{field_key}"
end

Instance Method Details

#columnsObject



83
84
85
86
87
88
89
90
91
92
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 83

def columns
  @columns ||= begin
    cols = [
      Column.new(key: UUID_KEY, label: 'Row ID', unit: '', kind: :uuid, field_type: nil),
      Column.new(key: NAME_KEY, label: 'Variation', unit: '', kind: :name, field_type: nil)
    ]
    group_order.each { |group| cols.concat(columns_for_group(group)) }
    cols
  end
end

#lookup(key) ⇒ Object



94
95
96
97
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 94

def lookup(key)
  @lookup ||= columns.each_with_object({}) { |col, acc| acc[col.key] = col }
  @lookup[key]
end

#rowsObject

Variation rows in the grid's display order: layout rowOrder first, then anything the layout does not mention, uuid-sorted (as sortedRows does).



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 101

def rows
  seen = {}
  ordered = []
  Array(layout['rowOrder']).each do |uuid|
    row = variations[uuid.to_s]
    next unless row.is_a?(Hash)

    ordered << row
    seen[uuid.to_s] = true
  end
  remaining = variations.reject { |uuid, row| seen[uuid.to_s] || !row.is_a?(Hash) }
  ordered + remaining.values.sort_by { |row| row['uuid'].to_s }
end

#segment_klass(klass_id) ⇒ Object



119
120
121
122
123
124
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 119

def segment_klass(klass_id)
  @segment_klass_index ||= segment_klasses.each_with_object({}) do |klass, acc|
    acc[klass.id.to_s] = klass
  end
  @segment_klass_index[klass_id.to_s]
end

#segment_klassesObject



115
116
117
# File 'lib/labimotion/libs/element_variation_column_set.rb', line 115

def segment_klasses
  @segment_klasses ||= Labimotion::SegmentKlass.where(element_klass_id: element.element_klass_id).to_a
end