labimotion 1.1.3 → 1.2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 -13
  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