labimotion 1.1.4 → 1.2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/lib/labimotion/apis/generic_element_api.rb +32 -38
  3. data/lib/labimotion/collection/export.rb +45 -84
  4. data/lib/labimotion/collection/import.rb +60 -54
  5. data/lib/labimotion/entities/element_revision_entity.rb +10 -10
  6. data/lib/labimotion/entities/eln_element_entity.rb +23 -23
  7. data/lib/labimotion/entities/properties_entity.rb +18 -19
  8. data/lib/labimotion/entities/segment_revision_entity.rb +11 -11
  9. data/lib/labimotion/helpers/element_helpers.rb +14 -4
  10. data/lib/labimotion/helpers/generic_helpers.rb +9 -9
  11. data/lib/labimotion/helpers/segment_helpers.rb +1 -2
  12. data/lib/labimotion/libs/converter.rb +12 -12
  13. data/lib/labimotion/libs/export_dataset.rb +32 -6
  14. data/lib/labimotion/libs/nmr_mapper.rb +27 -27
  15. data/lib/labimotion/libs/properties_handler.rb +95 -0
  16. data/lib/labimotion/libs/sample_association.rb +15 -15
  17. data/lib/labimotion/models/concerns/generic_klass_revisions.rb +1 -1
  18. data/lib/labimotion/models/concerns/generic_revisions.rb +3 -3
  19. data/lib/labimotion/models/concerns/linked_properties.rb +18 -0
  20. data/lib/labimotion/models/concerns/segmentable.rb +17 -12
  21. data/lib/labimotion/models/element.rb +26 -17
  22. data/lib/labimotion/utils/export_utils.rb +196 -0
  23. data/lib/labimotion/utils/field_type.rb +23 -0
  24. data/lib/labimotion/utils/import_utils.rb +244 -59
  25. data/lib/labimotion/utils/prop.rb +27 -0
  26. data/lib/labimotion/utils/search.rb +2 -2
  27. data/lib/labimotion/utils/serializer.rb +22 -22
  28. data/lib/labimotion/version.rb +1 -1
  29. data/lib/labimotion.rb +4 -1
  30. metadata +7 -2
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labimotion
4
+ class PropertiesHandler
5
+ class << self
6
+ private
7
+
8
+ def check_val(field, type)
9
+ case type
10
+ when Labimotion::FieldType::DRAG_SAMPLE, Labimotion::FieldType::DRAG_ELEMENT
11
+ return field.dig('value', 'el_id').present?
12
+ when Labimotion::FieldType::UPLOAD
13
+ return field.dig('value', 'files')&.length&.positive?
14
+ when Labimotion::FieldType::TABLE
15
+ return field[Labimotion::Prop::SUBFIELDS]&.length&.positive? && field['sub_values']&.length&.positive?
16
+ end
17
+ false
18
+ rescue StandardError => e
19
+ Labimotion.log_exception(e)
20
+ false
21
+ end
22
+
23
+ def detach_val(properties, field, key, type)
24
+ case type
25
+ when Labimotion::FieldType::DRAG_SAMPLE, Labimotion::FieldType::DRAG_ELEMENT, Labimotion::FieldType::UPLOAD
26
+ idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
27
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value'] = {}
28
+ when Labimotion::FieldType::TABLE
29
+ return properties if check_table_val(field)
30
+
31
+ idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
32
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['sub_values'] = []
33
+ end
34
+ properties
35
+ rescue StandardError => e
36
+ Labimotion.log_exception(e)
37
+ properties
38
+ end
39
+
40
+ def check_table_val(field)
41
+ tsf_samples = field[Labimotion::Prop::SUBFIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_SAMPLE }
42
+ tsf_elements = field[Labimotion::Prop::SUBFIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_ELEMENT }
43
+ tsf_samples.length.zero? && tsf_elements.length.zero?
44
+ rescue StandardError => e
45
+ Labimotion.log_exception(e)
46
+ false
47
+ end
48
+ end
49
+
50
+ def self.check_properties(properties)
51
+ properties.nil? || !properties.is_a?(Hash) || properties[Labimotion::Prop::LAYERS].nil? || properties[Labimotion::Prop::LAYERS].keys.empty?
52
+ end
53
+
54
+ def self.detach(properties, key, type)
55
+ fields = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].select { |ss| ss['type'] == type }
56
+ fields.each do |field|
57
+ next unless check_val(field, type)
58
+
59
+ properties = detach_val(properties, field, key, type)
60
+ end
61
+ properties
62
+ rescue StandardError => e
63
+ Labimotion.log_exception(e)
64
+ properties
65
+ end
66
+
67
+ def self.split(properties, key, type)
68
+ fields = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].select { |ss| ss['type'] == type }
69
+ fields.each do |field|
70
+ next unless check_val(field, type)
71
+
72
+ idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
73
+ ## TODO Split ...
74
+ end
75
+ properties
76
+ rescue StandardError => e
77
+ Labimotion.log_exception(e)
78
+ properties
79
+ end
80
+
81
+ def self.copy(properties, key, type)
82
+ fields = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].select { |ss| ss['type'] == type }
83
+ fields.each do |field|
84
+ next unless check_val(field, type)
85
+
86
+ idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
87
+ ## TODO Copy Sample...
88
+ end
89
+ properties
90
+ rescue StandardError => e
91
+ Labimotion.log_exception(e)
92
+ properties
93
+ end
94
+ end
95
+ end
@@ -34,9 +34,9 @@ module Labimotion
34
34
  def self.build_table_sample(field_tables, current_user, element = nil)
35
35
  sds = []
36
36
  field_tables.each do |field|
37
- next unless field['sub_values'].present? && field['sub_fields'].present?
37
+ next unless field['sub_values'].present? && field[Labimotion::Prop::SUBFIELDS].present?
38
38
 
39
- field_table_samples = field['sub_fields'].select { |ss| ss['type'] == 'drag_sample' }
39
+ field_table_samples = field[Labimotion::Prop::SUBFIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_SAMPLE }
40
40
  next unless field_table_samples.present?
41
41
 
42
42
  col_ids = field_table_samples.map { |x| x.values[0] }
@@ -73,33 +73,33 @@ module Labimotion
73
73
  def self.update_sample_association(properties, current_user, element = nil)
74
74
  sds = []
75
75
  els = []
76
- properties['layers'].keys.each do |key|
77
- layer = properties['layers'][key]
78
- field_samples = layer['fields'].select { |ss| ss['type'] == 'drag_sample' }
76
+ properties[Labimotion::Prop::LAYERS].keys.each do |key|
77
+ layer = properties[Labimotion::Prop::LAYERS][key]
78
+ field_samples = layer[Labimotion::Prop::FIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_SAMPLE }
79
79
  field_samples.each do |field|
80
- idx = properties['layers'][key]['fields'].index(field)
80
+ idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
81
81
  sid = field.dig('value', 'el_id')
82
82
  next if sid.blank?
83
83
 
84
- sds << sid unless properties.dig('layers', key, 'fields', idx, 'value', 'is_new') == true
85
- next unless properties.dig('layers', key, 'fields', idx, 'value', 'is_new') == true
84
+ sds << sid unless properties.dig(Labimotion::Prop::LAYERS, key, Labimotion::Prop::FIELDS, idx, 'value', 'is_new') == true
85
+ next unless properties.dig(Labimotion::Prop::LAYERS, key, Labimotion::Prop::FIELDS, idx, 'value', 'is_new') == true
86
86
 
87
87
  cr_opt = field.dig('value', 'cr_opt')
88
88
  subsample = Labimotion::SampleAssociation.build_sample(sid, element&.collections, current_user, cr_opt) unless sid.nil? || cr_opt.nil?
89
89
  next if subsample.nil?
90
90
 
91
91
  sds << subsample.id
92
- properties['layers'][key]['fields'][idx]['value']['el_id'] = subsample.id
93
- properties['layers'][key]['fields'][idx]['value']['el_label'] = subsample.short_label
94
- properties['layers'][key]['fields'][idx]['value']['el_tip'] = subsample.short_label
95
- properties['layers'][key]['fields'][idx]['value']['is_new'] = false
92
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_id'] = subsample.id
93
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_label'] = subsample.short_label
94
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_tip'] = subsample.short_label
95
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['is_new'] = false
96
96
  Labimotion::ElementsSample.find_or_create_by(element_id: element.id, sample_id: subsample.id) if element.present?
97
97
  end
98
- field_tables = properties['layers'][key]['fields'].select { |ss| ss['type'] == 'table' }
98
+ field_tables = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].select { |ss| ss['type'] == Labimotion::FieldType::TABLE }
99
99
  sds << Labimotion::SampleAssociation.build_table_sample(field_tables, current_user, element) if element.present?
100
- field_elements = layer['fields'].select { |ss| ss['type'] == 'drag_element' }
100
+ field_elements = layer[Labimotion::Prop::FIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_ELEMENT }
101
101
  field_elements.each do |field|
102
- idx = properties['layers'][key]['fields'].index(field)
102
+ idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
103
103
  sid = field.dig('value', 'el_id')
104
104
  next if element.nil? || sid.blank? || sid == element.id
105
105
 
@@ -15,7 +15,7 @@ module Labimotion
15
15
  if properties_release['flowObject'].present?
16
16
  elements = (properties_release['flowObject']['nodes'] || []).map do |el|
17
17
  if el['data'].present? && el['data']['lKey'].present?
18
- layer = properties_release['layers'][el['data']['lKey']]
18
+ layer = properties_release[Labimotion::Prop::LAYERS][el['data']['lKey']]
19
19
  el['data']['layer'] = layer if layer.present?
20
20
  end
21
21
  el
@@ -28,9 +28,9 @@ module Labimotion
28
28
 
29
29
  def delete_attachments
30
30
  att_ids = []
31
- properties && properties['layers']&.keys&.each do |key|
32
- layer = properties['layers'][key]
33
- field_uploads = layer['fields'].select { |ss| ss['type'] == 'upload' }
31
+ properties && properties[Labimotion::Prop::LAYERS]&.keys&.each do |key|
32
+ layer = properties[Labimotion::Prop::LAYERS][key]
33
+ field_uploads = layer[Labimotion::Prop::FIELDS].select { |ss| ss['type'] == Labimotion::FieldType::UPLOAD }
34
34
  field_uploads.each do |field|
35
35
  (field['value'] && field['value']['files'] || []).each do |file|
36
36
  att_ids.push(file['aid']) unless file['aid'].nil?
@@ -0,0 +1,18 @@
1
+ module Labimotion
2
+ # Segmentable concern
3
+ module LinkedProperties
4
+ extend ActiveSupport::Concern
5
+
6
+ def detach_properties(properties)
7
+ return properties if Labimotion::PropertiesHandler.check_properties(properties)
8
+
9
+ properties[Labimotion::Prop::LAYERS]&.keys&.each do |key|
10
+ properties = Labimotion::PropertiesHandler.detach(properties, key, Labimotion::FieldType::DRAG_SAMPLE)
11
+ properties = Labimotion::PropertiesHandler.detach(properties, key, Labimotion::FieldType::DRAG_ELEMENT)
12
+ properties = Labimotion::PropertiesHandler.detach(properties, key, Labimotion::FieldType::UPLOAD)
13
+ properties = Labimotion::PropertiesHandler.detach(properties, key, Labimotion::FieldType::TABLE)
14
+ end
15
+ properties
16
+ end
17
+ end
18
+ end
@@ -16,21 +16,26 @@ module Labimotion
16
16
  segments = save_segments(segments: args[:segments], current_user_id: args[:current_user_id])
17
17
  segments.each do |segment|
18
18
  properties = segment.properties
19
- properties['layers'].keys.each do |key|
20
- layer = properties['layers'][key]
21
- field_uploads = layer['fields'].select { |ss| ss['type'] == 'upload' }
19
+ properties[Labimotion::Prop::LAYERS].keys.each do |key|
20
+ layer = properties[Labimotion::Prop::LAYERS][key]
21
+ field_uploads = layer[Labimotion::Prop::FIELDS].select { |ss| ss['type'] == Labimotion::FieldType::UPLOAD }
22
22
  field_uploads&.each do |upload|
23
- idx = properties['layers'][key]['fields'].index(upload)
23
+ idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(upload)
24
24
  files = upload["value"] && upload["value"]["files"]
25
25
  files&.each_with_index do |fi, fdx|
26
- aid = properties['layers'][key]['fields'][idx]['value']['files'][fdx]['aid']
27
- unless aid.nil?
28
- copied_att = Attachment.find(aid)&.copy(attachable_type: 'SegmentProps', attachable_id: segment.id, transferred: true)
29
- unless copied_att.nil?
30
- copied_att.save!
31
- properties['layers'][key]['fields'][idx]['value']['files'][fdx]['aid'] = copied_att.id
32
- properties['layers'][key]['fields'][idx]['value']['files'][fdx]['uid'] = copied_att.identifier
33
- end
26
+ aid = files[fdx]['aid']
27
+ uid = files[fdx]['uid']
28
+ next if aid.nil?
29
+
30
+ att = Attachment.find_by(id: aid)
31
+ att = Attachment.find_by(identifier: uid) if att.nil?
32
+ copied_att = att&.copy(attachable_type: Labimotion::Prop::SEGMENTPROPS, attachable_id: segment.id, transferred: true)
33
+ if copied_att.nil?
34
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['files'].delete_at(fdx)
35
+ else
36
+ copied_att.save!
37
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['files'][fdx]['aid'] = copied_att.id
38
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['files'][fdx]['uid'] = copied_att.identifier
34
39
  end
35
40
  end
36
41
  end
@@ -2,19 +2,20 @@
2
2
  require 'labimotion/models/concerns/generic_revisions'
3
3
  require 'labimotion/models/concerns/segmentable'
4
4
  require 'labimotion/models/concerns/workflow'
5
+ require 'labimotion/models/concerns/linked_properties'
5
6
 
6
7
  module Labimotion
7
8
  class Element < ApplicationRecord
8
9
  acts_as_paranoid
9
10
  self.table_name = :elements
10
- include PgSearch if Labimotion::IS_RAILS5 == true
11
- include PgSearch::Model if Labimotion::IS_RAILS5 == false
11
+ include PgSearch::Model
12
12
  include ElementUIStateScopes
13
13
  include Collectable
14
14
  include Taggable
15
15
  include Workflow
16
16
  include Segmentable
17
17
  include GenericRevisions
18
+ include LinkedProperties
18
19
 
19
20
  multisearchable against: %i[name short_label]
20
21
 
@@ -30,6 +31,8 @@ module Labimotion
30
31
 
31
32
  belongs_to :element_klass, class_name: 'Labimotion::ElementKlass'
32
33
 
34
+ has_ancestry orphan_strategy: :adopt
35
+
33
36
  has_many :collections_elements, inverse_of: :element, dependent: :destroy, class_name: 'Labimotion::CollectionsElement'
34
37
  has_many :collections, through: :collections_elements
35
38
  has_many :attachments, as: :attachable
@@ -51,7 +54,7 @@ module Labimotion
51
54
  has_many :elements_elements, foreign_key: :parent_id, class_name: 'Labimotion::ElementsElement'
52
55
  has_many :elements, through: :elements_elements, source: :element, class_name: 'Labimotion::Element'
53
56
 
54
- before_create :auto_set_short_label
57
+ before_save :auto_set_short_label
55
58
  after_create :update_counter
56
59
  before_destroy :delete_attachment
57
60
 
@@ -69,6 +72,10 @@ module Labimotion
69
72
  end
70
73
 
71
74
  def auto_set_short_label
75
+ return if short_label && !short_label_changed?
76
+
77
+ return if parent && (self.short_label = "#{parent.short_label}-#{parent.children.with_deleted.count.to_i.succ}")
78
+
72
79
  prefix = element_klass.klass_prefix
73
80
  if creator.counters[element_klass.name].nil?
74
81
  creator.counters[element_klass.name] = '0'
@@ -99,22 +106,24 @@ module Labimotion
99
106
  end
100
107
 
101
108
  def thumb_svg
102
- if Labimotion::IS_RAILS5 == true
103
- image_atts = attachments.select do |a_img|
104
- a_img&.content_type&.match(Regexp.union(%w[jpg jpeg png tiff tif]))
105
- end
106
-
107
- attachment = image_atts[0] || attachments[0]
108
- preview = attachment.read_thumbnail if attachment
109
- preview && Base64.encode64(preview) || 'not available'
110
- else
111
- image_atts = attachments.select(&:type_image?)
112
- attachment = image_atts[0] || attachments[0]
113
- preview = attachment&.read_thumbnail
114
- (preview && Base64.encode64(preview)) || 'not available'
115
- end
109
+ image_atts = attachments.select(&:type_image?)
110
+ attachment = image_atts[0] || attachments[0]
111
+ preview = attachment&.read_thumbnail
112
+ (preview && Base64.encode64(preview)) || 'not available'
116
113
  end
117
114
 
115
+ def split(user, col_ids)
116
+ subelement = self.dup
117
+ subelement.name = self.name if self.name.present?
118
+ subelement.parent = self
119
+ subelement.properties = detach_properties(properties)
120
+ subelement.created_by = user.id
121
+ collections = (Collection.where(id: col_ids) | Collection.where(user_id: user, label: 'All', is_locked: true))
122
+ subelement.collections << collections
123
+ subelement.container = Container.create_root_container
124
+ subelement.save!
125
+ subelement
126
+ end
118
127
 
119
128
  def migrate_workflow
120
129
  return if properties.nil? || properties_release.nil?
@@ -0,0 +1,196 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Labimotion
4
+ class ExportUtils
5
+ class << self
6
+ private
7
+ def uid(uuids, key, id)
8
+ return nil if uuids.nil? || key.nil? || id.nil?
9
+
10
+ new_id = uuids.fetch(key, nil)&.fetch(id, nil)
11
+ new_id || id
12
+ rescue StandardError => e
13
+ Labimotion.log_exception(e)
14
+ raise
15
+ end
16
+
17
+ def el_type(name)
18
+ return nil if name.nil?
19
+
20
+ case name
21
+ when Labimotion::FieldType::DRAG_ELEMENT
22
+ Labimotion::Prop::L_ELEMENT
23
+ when Labimotion::FieldType::DRAG_SAMPLE
24
+ Labimotion::Prop::SAMPLE
25
+ when Labimotion::FieldType::DRAG_MOLECULE
26
+ Labimotion::Prop::MOLECULE
27
+ end
28
+ rescue StandardError => e
29
+ Labimotion.log_exception(e)
30
+ name
31
+ end
32
+
33
+ def fetch_molecule(type, id)
34
+ return if type != Labimotion::FieldType::DRAG_MOLECULE || id.nil?
35
+
36
+ molecule = Molecule.find_by(id: id)
37
+ yield(molecule) if molecule.present?
38
+ rescue StandardError => e
39
+ Labimotion.log_exception(e)
40
+ raise
41
+ end
42
+
43
+ def set_seg_prop(properties, uuids, key, type, &fetch_one)
44
+ layer = properties[Labimotion::Prop::LAYERS][key]
45
+ fields = layer[Labimotion::Prop::FIELDS].select { |ss| ss['type'] == type }
46
+ fields.each do |field|
47
+ idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
48
+ next unless field.fetch('value', nil).is_a?(Hash)
49
+
50
+ id = field.fetch('value', nil)&.fetch('el_id', nil) unless idx.nil?
51
+ next unless id.is_a?(Integer)
52
+ next if properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]&.fetch('value', nil).nil?
53
+ next unless properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value'].is_a?(Hash)
54
+
55
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_id'] = uid(uuids, el_type(type), id)
56
+ end
57
+ properties
58
+ rescue StandardError => e
59
+ Labimotion.log_exception(e)
60
+ properties
61
+ end
62
+
63
+ def set_prop(properties, uuids, key, type, &fetch_one)
64
+ layer = properties.fetch(Labimotion::Prop::LAYERS, nil)&.fetch(key, nil)
65
+ return properties if layer.nil?
66
+
67
+ fields = layer[Labimotion::Prop::FIELDS]&.select { |ss| ss['type'] == type }
68
+ fields&.each do |field|
69
+ idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
70
+ next unless field.fetch('value', nil).is_a?(Hash)
71
+
72
+ id = field.fetch('value', nil)&.fetch('el_id', nil) unless idx.nil?
73
+ fetch_molecule(type, id, &fetch_one)
74
+ next if properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]&.fetch('value', nil).nil?
75
+
76
+ next unless properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value'].is_a?(Hash)
77
+
78
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_id'] = uid(uuids, el_type(type), id)
79
+ end
80
+ properties
81
+ rescue StandardError => e
82
+ Labimotion.log_exception(e)
83
+ properties
84
+ end
85
+
86
+ def set_ai(instance, properties, uuids, key)
87
+ return properties unless instance.is_a?(Element)
88
+
89
+ layer = properties[Labimotion::Prop::LAYERS][key]
90
+ layer&.fetch('ai', nil)&.each_with_index do |ai, idx|
91
+ properties[Labimotion::Prop::LAYERS][key]['ai'][idx] = uid(uuids, Labimotion::Prop::CONTAINER, ai)
92
+ end
93
+ properties
94
+ rescue StandardError => e
95
+ Labimotion.log_exception(e)
96
+ properties
97
+ end
98
+
99
+ def set_upload(instance, properties, attachments, uuids, key, type)
100
+ attachments = [] if attachments.nil?
101
+ layer = properties[Labimotion::Prop::LAYERS][key]
102
+ fields = layer[Labimotion::Prop::FIELDS].select { |ss| ss['type'] == type }
103
+ fields.each do |field|
104
+ idx = properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
105
+ files = field.fetch('value', nil)&.fetch('files', nil)
106
+ files&.each_with_index do |fi, fdx|
107
+ att = Attachment.find_by(id: fi['aid'])
108
+ if att.nil?
109
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['files'].delete_at(fdx)
110
+ else
111
+ attachments += [att] if att.present?
112
+ uuaid = yield(att, {'attachable_id' => instance.class.name})
113
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['files'][fdx]['aid'] = uuaid unless att.nil?
114
+ end
115
+ end
116
+ id = field.fetch('value', nil)&.fetch('el_id', nil) unless idx.nil?
117
+ if properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx].fetch('value', nil).is_a?(Hash)
118
+ properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_id'] = uid(uuids, el_type(type), id)
119
+ end
120
+ end
121
+ [properties, attachments]
122
+ rescue StandardError => e
123
+ Labimotion.log_exception(e)
124
+ [properties, attachments]
125
+ end
126
+
127
+
128
+ def set_table_prop(field, uuids, type, &fetch_one)
129
+ fields = field[Labimotion::Prop::SUBFIELDS].select { |ss| ss['type'] == type }
130
+ return field if fields.empty?
131
+
132
+ col_ids = fields.map { |x| x.values[0] }
133
+ col_ids&.each do |col_id|
134
+ field['sub_values'].each do |sub_value|
135
+ next unless sub_value.fetch(col_id, nil)&.fetch('value', nil).is_a?(Hash)
136
+ next if sub_value.fetch(col_id, nil)&.fetch('value', nil)&.fetch('el_id', nil).nil?
137
+ next unless id = sub_value[col_id]['value']['el_id']
138
+
139
+ fetch_molecule(type, id, &fetch_one)
140
+ sub_value[col_id]['value']['el_id'] = uid(uuids, el_type(type), id)
141
+ end
142
+ end
143
+ field
144
+ rescue StandardError => e
145
+ Labimotion.log_exception(e)
146
+ field
147
+ end
148
+
149
+ def set_table(properties, uuids, key, type, &fetch_one)
150
+ layer = properties[Labimotion::Prop::LAYERS][key]
151
+ fields = layer[Labimotion::Prop::FIELDS].select { |ss| ss['type'] == type }
152
+ fields&.each do |field|
153
+ next unless field['sub_values'].present? && field[Labimotion::Prop::SUBFIELDS].present?
154
+
155
+ set_table_prop(field, uuids, Labimotion::FieldType::DRAG_MOLECULE, &fetch_one)
156
+ set_table_prop(field, uuids, Labimotion::FieldType::DRAG_SAMPLE, &fetch_one)
157
+ end
158
+ properties
159
+ rescue StandardError => e
160
+ Labimotion.log_exception(e)
161
+ properties
162
+ end
163
+ end
164
+
165
+ def self.fetch_seg_properties(segment, uuids)
166
+ properties = segment['properties'] || {}
167
+ properties[Labimotion::Prop::LAYERS].keys.each do |key|
168
+ properties = set_seg_prop(properties, uuids, key, Labimotion::FieldType::DRAG_ELEMENT)
169
+ properties = set_seg_prop(properties, uuids, key, Labimotion::FieldType::DRAG_SAMPLE)
170
+ end
171
+ segment['properties'] = properties
172
+ segment
173
+ rescue StandardError => e
174
+ Labimotion.log_exception(e)
175
+ segment
176
+ end
177
+
178
+ def self.fetch_properties(instance, uuids, attachments, &fetch_one)
179
+ attachments = [] if attachments.nil?
180
+ properties = instance.properties
181
+ properties[Labimotion::Prop::LAYERS].keys.each do |key|
182
+ properties = set_ai(instance, properties, uuids, key)
183
+ properties = set_prop(properties, uuids, key, Labimotion::FieldType::DRAG_ELEMENT, &fetch_one)
184
+ properties = set_prop(properties, uuids, key, Labimotion::FieldType::DRAG_MOLECULE, &fetch_one)
185
+ properties = set_prop(properties, uuids, key, Labimotion::FieldType::DRAG_SAMPLE, &fetch_one)
186
+ properties, attachments = set_upload(instance, properties, attachments, uuids, key, Labimotion::FieldType::UPLOAD, &fetch_one)
187
+ properties = set_table(properties, uuids, key, Labimotion::FieldType::TABLE, &fetch_one)
188
+ end
189
+ instance.properties = properties
190
+ [instance, attachments]
191
+ rescue StandardError => e
192
+ Labimotion.log_exception(e)
193
+ [instance, attachments]
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,23 @@
1
+ module Labimotion
2
+ ## Properties Field Type
3
+ class FieldType
4
+ CHECKBOX = 'checkbox'.freeze
5
+ DATE = 'date'.freeze
6
+ DATETIME = 'datetime'.freeze
7
+ DATETIME_RANGE = 'datetime-range'.freeze
8
+ SELECT = 'select'.freeze
9
+ INTEGER = 'integer'.freeze
10
+ SYSTEM_DEFINED = 'system-defined'.freeze
11
+ DRAG = 'drag'.freeze
12
+ DRAG_ELEMENT = 'drag_element'.freeze
13
+ DRAG_MOLECULE = 'drag_molecule'.freeze
14
+ DRAG_SAMPLE = 'drag_sample'.freeze
15
+ DRAG_REACTION = 'drag_reaction'.freeze
16
+ DRAG_MS = [DRAG_MOLECULE, DRAG_SAMPLE].freeze
17
+ DRAG_ALL = [DRAG_ELEMENT, DRAG_MOLECULE, DRAG_SAMPLE, DRAG_REACTION].freeze
18
+ TABLE = 'table'.freeze
19
+ UPLOAD = 'upload'.freeze
20
+ TEXT = 'text'.freeze
21
+ TEXTAREA = 'textarea'.freeze
22
+ end
23
+ end