labimotion 1.4.1 → 2.0.0.rc1

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 +1 -0
  3. data/lib/labimotion/apis/generic_klass_api.rb +3 -2
  4. data/lib/labimotion/apis/labimotion_api.rb +13 -0
  5. data/lib/labimotion/apis/standard_api.rb +26 -0
  6. data/lib/labimotion/apis/standard_layer_api.rb +100 -0
  7. data/lib/labimotion/apis/vocabulary_api.rb +107 -0
  8. data/lib/labimotion/entities/dataset_entity.rb +2 -1
  9. data/lib/labimotion/entities/properties_entity.rb +167 -55
  10. data/lib/labimotion/entities/segment_entity.rb +1 -0
  11. data/lib/labimotion/entities/vocabulary_entity.rb +38 -0
  12. data/lib/labimotion/helpers/element_helpers.rb +8 -6
  13. data/lib/labimotion/helpers/param_helpers.rb +137 -82
  14. data/lib/labimotion/helpers/segment_helpers.rb +1 -1
  15. data/lib/labimotion/helpers/vocabulary_helpers.rb +16 -0
  16. data/lib/labimotion/libs/converter.rb +13 -33
  17. data/lib/labimotion/libs/data/vocab/Standard.json +385 -0
  18. data/lib/labimotion/libs/data/vocab/System.json +131 -0
  19. data/lib/labimotion/libs/nmr_mapper.rb +2 -1
  20. data/lib/labimotion/libs/sample_association.rb +4 -0
  21. data/lib/labimotion/libs/vocabulary_handler.rb +118 -0
  22. data/lib/labimotion/models/concerns/attachment_converter.rb +5 -4
  23. data/lib/labimotion/models/concerns/datasetable.rb +1 -0
  24. data/lib/labimotion/models/concerns/segmentable.rb +2 -0
  25. data/lib/labimotion/models/std_layer.rb +9 -0
  26. data/lib/labimotion/models/std_layers_revision.rb +9 -0
  27. data/lib/labimotion/models/vocabulary.rb +12 -0
  28. data/lib/labimotion/version.rb +1 -1
  29. data/lib/labimotion.rb +10 -0
  30. metadata +20 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a1c30f358902beeb863766ddb2ee02b980b3cca7055f45babe20fb4211277772
4
- data.tar.gz: 86e1e46884b26fbfff1a91618698ab29072940109f9bc7c3d114b48a9b93ee86
3
+ metadata.gz: 9ba4a246b95d088b7928826074a223b671bd3ff8ac7c4bce5904ff983aec1534
4
+ data.tar.gz: c1393205315928947b688566db60ac311eef1fcfccedbb395e521a2dbdfdfbdd
5
5
  SHA512:
6
- metadata.gz: 41655a864b15b848116b370964ae6a05c707512d6ba80987cdec1f392d3fb647476fcf119612f116a2923c4992e32b00127371ac8a77d6e7de6cf1dc94773dbd
7
- data.tar.gz: 8308707ad72ac2ebd38c725bc1336151712b5900fa4f35429674ee54f26cbe6fcc7ed43ef71777b6dd069701411540c776a7f183b183d147c1a3658a124e12a7
6
+ metadata.gz: fbf716f60ca698f40f332b318d55747266d23ffa0c066f2afb5eff44f90c54db1402d8b42e251641fa1564aff167c79abe86411c519653c59ffbca36991a85fd
7
+ data.tar.gz: 4dbeae09a3740df12533e217e11d4fbc003894280ccc9d6f46e2042cf4b0ff4b2ce448215a9d918e38b077458caba39e26c55a31870b9e9e7f753f8d25bfc41b
@@ -12,6 +12,7 @@ module Labimotion
12
12
  helpers CollectionHelpers
13
13
  helpers UserLabelHelpers
14
14
  helpers Labimotion::SampleAssociationHelpers
15
+ helpers Labimotion::VocabularyHelpers
15
16
  helpers Labimotion::GenericHelpers
16
17
  helpers Labimotion::ElementHelpers
17
18
  helpers Labimotion::ParamHelpers
@@ -6,7 +6,7 @@ require 'labimotion/libs/export_element'
6
6
  module Labimotion
7
7
  # Generic Element API
8
8
  class GenericKlassAPI < Grape::API
9
-
9
+
10
10
  resource :generic_klass do
11
11
  namespace :download_klass do
12
12
  desc 'export klass'
@@ -28,7 +28,8 @@ module Labimotion
28
28
  Labimotion.log_exception(e, current_user)
29
29
  {}
30
30
  end
31
- end
31
+ end
32
+
32
33
  end
33
34
  end
34
35
  end
@@ -0,0 +1,13 @@
1
+ # app/api/labimotion/central_api.rb
2
+ module Labimotion
3
+ class LabimotionAPI < Grape::API
4
+ mount Labimotion::ConverterAPI
5
+ mount Labimotion::GenericKlassAPI
6
+ mount Labimotion::GenericElementAPI
7
+ mount Labimotion::GenericDatasetAPI
8
+ mount Labimotion::SegmentAPI
9
+ mount Labimotion::LabimotionHubAPI
10
+ mount Labimotion::StandardLayerAPI
11
+ mount Labimotion::VocabularyAPI
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'labimotion/version'
4
+ require 'labimotion/libs/export_element'
5
+
6
+ module Labimotion
7
+ # Generic Element API
8
+ class StandardAPI < Grape::API
9
+ resource :standards do
10
+ namespace :create_std_layer do
11
+ desc 'create standard layer'
12
+ params do
13
+ use :create_std_layer_params
14
+ end
15
+ post do
16
+ # authenticate_admin!('elements')
17
+ # create_element_klass(current_user, params)
18
+ create_std_layer(current_user, params)
19
+ status 201
20
+ rescue ActiveRecord::RecordInvalid => e
21
+ { error: e.message }
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'labimotion/version'
4
+
5
+ module Labimotion
6
+ # Generic Element API
7
+ class StandardLayerAPI < Grape::API
8
+ include Grape::Kaminari
9
+ helpers Labimotion::ParamHelpers
10
+
11
+ resource :layers do
12
+ namespace :get_all_layers do
13
+ desc 'get all standard layers for designer'
14
+ get do
15
+ list = Labimotion::StdLayer.all.sort_by { |e| e.name }
16
+ # present list, with: Labimotion::StdLayer, root: 'klass'
17
+ # data = Labimotion::StdLayer.represent(col_tree, serializable: true)
18
+ return { mc: 'ss00', data: list }
19
+ rescue StandardError => e
20
+ Labimotion.log_exception(e, current_user)
21
+ { mc: 'se00', msg: e.message, data: [] }
22
+ end
23
+ end
24
+
25
+ namespace :get_standard_layer do
26
+ desc 'get standard layer by id'
27
+ # params do
28
+ # requires :id, type: Integer, desc: 'Layer id'
29
+ # end
30
+ route_param :id do
31
+ before do
32
+ # @element_policy = ElementPolicy.new(current_user, Labimotion::Element.find(params[:id]))
33
+ # error!('401 Unauthorized', 401) unless current_user.matrix_check_by_name('genericElement') && @element_policy.read?
34
+ # rescue ActiveRecord::RecordNotFound
35
+ # error!('404 Not Found', 404)
36
+ end
37
+ get do
38
+ entity = Labimotion::StdLayer.find(params[:id])
39
+ return { mc: 'ss00', data: entity }
40
+ rescue StandardError => e
41
+ Labimotion.log_exception(e, current_user)
42
+ { mc: 'se00', msg: e.message, data: {} }
43
+ end
44
+ end
45
+ end
46
+
47
+ namespace :save_standard_layer do
48
+ desc 'create Generic Element Klass'
49
+ params do
50
+ use :std_layer_save
51
+ end
52
+ before do
53
+ cur_layer = Labimotion::StdLayer.find_by(name: params[:key])
54
+ error!('Error! duplicate name', 409) if cur_layer.present?
55
+ # @element_policy = ElementPolicy.new(current_user, Labimotion::Element.find(params[:id]))
56
+ # error!('401 Unauthorized', 401) unless current_user.matrix_check_by_name('genericElement') && @element_policy.read?
57
+ # rescue ActiveRecord::RecordNotFound
58
+ # Labimotion.log_exception(e, current_user)
59
+ # error!('404 Not Found', 404)
60
+ end
61
+ post do
62
+ attributes = {
63
+ name: params[:key],
64
+ label: params[:label],
65
+ description: params[:description],
66
+ identifier: SecureRandom.uuid,
67
+ created_by: current_user.id,
68
+ properties: declared(params, include_missing: false)
69
+ }
70
+ layer = Labimotion::StdLayer.new(attributes)
71
+ layer.save!
72
+ { mc: 'ss00', data: layer }
73
+ rescue ActiveRecord::RecordInvalid => e
74
+ Labimotion.log_exception(e, current_user)
75
+ { mc: 'se00', msg: e.message, data: {} }
76
+ end
77
+ end
78
+
79
+ namespace :delete_standard_layer do
80
+ desc 'delete standard layer by id'
81
+ params do
82
+ requires :id, type: Integer, desc: 'Standard layer id'
83
+ end
84
+ route_param :id do
85
+ before do
86
+ # error!('401 Unauthorized', 401) unless ElementPolicy.new(current_user, StdLayer.find(params[:id])).destroy?
87
+ end
88
+ delete do
89
+ entity = Labimotion::StdLayer.find(params[:id])
90
+ entity.destroy
91
+ return { mc: 'ss00', data: {} }
92
+ rescue StandardError => e
93
+ Labimotion.log_exception(e, current_user)
94
+ { mc: 'se00', msg: e.message, data: [] }
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'labimotion/version'
4
+
5
+ module Labimotion
6
+ # Generic Element API
7
+ class VocabularyAPI < Grape::API
8
+ include Grape::Kaminari
9
+ helpers Labimotion::ParamHelpers
10
+
11
+ resource :vocab do
12
+ namespace :save_vocabulary do
13
+ desc 'Save vocabularies'
14
+ params do
15
+ use :vocab_save
16
+ end
17
+ before do
18
+ # error!('Error! duplicate record', 409) if ???.present?
19
+ rescue ActiveRecord::RecordNotFound
20
+ error!('404 Not Found', 404)
21
+ end
22
+ post do
23
+ attributes = {
24
+ name: params[:name],
25
+ label: params[:label],
26
+ field_type: params[:field_type],
27
+ opid: 8,
28
+ term_id: params[:term_id],
29
+ source: params[:source],
30
+ source_id: params[:source_id],
31
+ layer_id: params[:layer_id],
32
+ field_id: params[:name],
33
+ identifier: params[:source_id],
34
+ created_by: current_user.id,
35
+ properties: declared(params, include_missing: false),
36
+ }
37
+ voc = Labimotion::Vocabulary.new(attributes)
38
+ voc.save!
39
+ { mc: 'ss00', data: voc }
40
+ rescue StandardError => e
41
+ Labimotion.log_exception(e, current_user)
42
+ { mc: 'se00', msg: e.message, data: {} }
43
+ end
44
+ end
45
+
46
+ namespace :get_all_vocabularies do
47
+ desc 'get all standard layers for designer'
48
+ get do
49
+ # merged_data = []
50
+ # Dir.glob(Rails.public_path.join('generic', 'vocabularies', '*.json')).each do |file_path|
51
+ # file_content = File.read(file_path)
52
+ # json_data = JSON.parse(file_content)
53
+ # merged_data.concat(json_data)
54
+ # end
55
+
56
+ # list = Labimotion::Vocabulary.all.sort_by { |e| e.name }
57
+ # present list, with: Labimotion::StdLayer, root: 'klass'
58
+ combined_data = Labimotion::VocabularyHandler.load_all_vocabularies
59
+ # combined_data = Labimotion::VocabularyEntity.represent(vocabularies, serializable: true)
60
+ return { mc: 'ss00', data: combined_data }
61
+ rescue StandardError => e
62
+ Labimotion.log_exception(e, current_user)
63
+ { mc: 'se00', msg: e.message, data: [] }
64
+ end
65
+ end
66
+
67
+ namespace :field_klasses do
68
+ desc 'get all field klasses for admin function'
69
+ get do
70
+ # Dir.glob(Rails.public_path.join('generic', 'vocabularies', '*.json')).each do |file_path|
71
+ # file_content = File.read(file_path)
72
+ # json_data = JSON.parse(file_content)
73
+ # merged_data.concat(json_data)
74
+ # end
75
+ vocabularies = Labimotion::VocabularyHandler.load_app_vocabularies
76
+ merged_data = Labimotion::FieldKlassEntity.represent(vocabularies, serializable: true)
77
+ # list = Labimotion::Vocabulary.all.sort_by { |e| e.name }
78
+ # present list, with: Labimotion::VocabularyEntity, root: 'klass'
79
+ merged_data
80
+ rescue StandardError => e
81
+ Labimotion.log_exception(e, current_user)
82
+ []
83
+ end
84
+ end
85
+
86
+ namespace :delete_vocabulary do
87
+ desc 'delete vocabulary by id'
88
+ params do
89
+ requires :id, type: Integer, desc: 'Vocabulary id'
90
+ end
91
+ route_param :id do
92
+ before do
93
+ # error!('401 Unauthorized', 401) unless ElementPolicy.new(current_user, Vocabulary.find(params[:id])).destroy?
94
+ end
95
+ delete do
96
+ entity = Labimotion::Vocabulary.find(params[:id])
97
+ entity.destroy
98
+ return { mc: 'ss00', data: {} }
99
+ rescue StandardError => e
100
+ Labimotion.log_exception(e, current_user)
101
+ { mc: 'se00', msg: e.message, data: [] }
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -3,7 +3,7 @@
3
3
  require 'labimotion/entities/application_entity'
4
4
  module Labimotion
5
5
  # Dataset entity
6
- class DatasetEntity < ApplicationEntity
6
+ class DatasetEntity < PropertiesEntity
7
7
  expose :id, :dataset_klass_id, :properties, :properties_release, :element_id, :element_type, :klass_ols, :klass_label, :klass_uuid
8
8
  def klass_ols
9
9
  object&.dataset_klass&.ols_term_id
@@ -12,5 +12,6 @@ module Labimotion
12
12
  def klass_label
13
13
  object&.dataset_klass&.label
14
14
  end
15
+
15
16
  end
16
17
  end
@@ -1,61 +1,162 @@
1
1
  require 'labimotion/entities/application_entity'
2
2
 
3
- # Entity module
4
3
  module Labimotion
5
4
  class PropertiesEntity < Labimotion::ApplicationEntity
6
-
7
- # TODO: Refactor this method to something more readable/understandable
8
5
  def properties
6
+ process_layers do |key, layer|
7
+ process_fields(key, layer)
8
+ end
9
+ object.properties
10
+ end
11
+
12
+ private
13
+
14
+ def process_layers
9
15
  (object&.properties.is_a?(Hash) && object.properties[Labimotion::Prop::LAYERS]&.keys || []).each do |key|
10
- # layer = object.properties[key]
11
- field_sample_molecules = object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_SAMPLE || ss['type'] == Labimotion::FieldType::DRAG_MOLECULE }
12
- field_sample_molecules.each do |field|
13
- idx = object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
14
- sid = field.dig('value', 'el_id')
15
- next unless sid.present?
16
-
17
- el = field['type'] == Labimotion::FieldType::DRAG_SAMPLE ? Sample.find_by(id: sid) : Molecule.find_by(id: sid)
18
- next unless el.present?
19
- next unless object.properties.dig(Labimotion::Prop::LAYERS, key, Labimotion::Prop::FIELDS, idx, 'value').present?
20
-
21
- object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_label'] = el.short_label if field['type'] == Labimotion::FieldType::DRAG_SAMPLE
22
- object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_tip'] = el.short_label if field['type'] == Labimotion::FieldType::DRAG_SAMPLE
23
- object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_svg'] = field['type'] == Labimotion::FieldType::DRAG_SAMPLE ? el.get_svg_path : File.join('/images', 'molecules', el&.molecule_svg_file || 'nosvg')
24
- end
16
+ yield(key, object.properties[Labimotion::Prop::LAYERS][key])
17
+ end
18
+ end
25
19
 
26
- field_sys_reactions = object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].select { |ss| ss['type'] == Labimotion::FieldType::SYS_REACTION }
27
- field_sys_reactions.each do |field|
28
- idx = object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
29
- sid = field.dig('value', 'el_id')
30
- next unless sid.present?
20
+ def process_fields(key, layer)
21
+ process_sample_and_molecule_fields(key, layer)
22
+ process_reaction_fields(key, layer)
23
+ process_table_fields(key, layer)
24
+ # process_voc_fields(key, layer)
25
+ end
31
26
 
32
- el = Reaction.find_by(id: sid)
33
- if el.blank?
34
- object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_tip'] = 'ERROR'
35
- object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_svg'] = ''
36
- end
27
+ def process_sample_and_molecule_fields(key, layer)
28
+ select_fields(layer, [Labimotion::FieldType::DRAG_SAMPLE, Labimotion::FieldType::DRAG_MOLECULE]).each do |field, idx|
29
+ update_sample_or_molecule_field(key, field, idx)
30
+ end
31
+ end
32
+
33
+ def process_reaction_fields(key, layer)
34
+ select_fields(layer, [Labimotion::FieldType::SYS_REACTION]).each do |field, idx|
35
+ update_reaction_field(key, field, idx)
36
+ end
37
+ end
37
38
 
38
- next unless el.present?
39
- next unless object.properties.dig(Labimotion::Prop::LAYERS, key, Labimotion::Prop::FIELDS, idx, 'value').present?
39
+ def process_table_fields(key, layer)
40
+ select_fields(layer, [Labimotion::FieldType::TABLE]).each do |field, idx|
41
+ update_table_field(key, field, idx)
42
+ end
43
+ end
40
44
 
41
- object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_label'] = el.short_label
42
- object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_tip'] = el.short_label
43
- object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value']['el_svg'] = el.reaction_svg_file
44
- end
45
+ def process_voc_fields(key, layer)
46
+ select_fields(layer, nil, true).each do |field, idx|
47
+ update_voc_field(key, field, idx)
48
+ end
49
+ end
45
50
 
46
- field_tables = object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].select { |ss| ss['type'] == Labimotion::FieldType::TABLE }
47
- field_tables.each do |field|
48
- idx = object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS].index(field)
49
- next unless field['sub_values'].present? && field[Labimotion::Prop::SUBFIELDS].present?
51
+ def select_fields(layer, types = nil, is_voc = false)
52
+ fields = layer[Labimotion::Prop::FIELDS]
53
+ fields = fields.select { |f| types.include?(f['type']) } if types
54
+ fields = fields.select { |f| f['is_voc'] == true } if is_voc
55
+ fields.map { |f| [f, layer[Labimotion::Prop::FIELDS].index(f)] }
56
+ end
57
+
58
+ def update_sample_or_molecule_field(key, field, idx)
59
+ sid = field.dig('value', 'el_id')
60
+ return unless sid.present?
50
61
 
51
- field_table_molecules = field[Labimotion::Prop::SUBFIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_MOLECULE }
52
- object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx] = set_table(field, field_table_molecules, Labimotion::Prop::MOLECULE) if field_table_molecules.present?
62
+ el = field['type'] == Labimotion::FieldType::DRAG_SAMPLE ? Sample.find_by(id: sid) : Molecule.find_by(id: sid)
63
+ return unless el.present? && object.properties.dig(Labimotion::Prop::LAYERS, key, Labimotion::Prop::FIELDS, idx, 'value').present?
64
+
65
+ update_field_value(key, idx, {
66
+ 'el_label' => el.short_label,
67
+ 'el_tip' => el.short_label,
68
+ 'el_svg' => field['type'] == Labimotion::FieldType::DRAG_SAMPLE ? el.get_svg_path : File.join('/images', 'molecules', el&.molecule_svg_file || 'nosvg')
69
+ })
70
+ end
71
+
72
+ def update_reaction_field(key, field, idx)
73
+ sid = field.dig('value', 'el_id')
74
+ return unless sid.present?
75
+
76
+ el = Reaction.find_by(id: sid)
77
+ if el.blank?
78
+ update_field_value(key, idx, { 'el_tip' => 'ERROR', 'el_svg' => '' })
79
+ return
80
+ end
53
81
 
54
- field_table_samples = field[Labimotion::Prop::SUBFIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_SAMPLE }
55
- object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx] = set_table(field, field_table_samples, Labimotion::Prop::SAMPLE) if field_table_samples.present?
82
+ return unless object.properties.dig(Labimotion::Prop::LAYERS, key, Labimotion::Prop::FIELDS, idx, 'value').present?
83
+
84
+ update_field_value(key, idx, {
85
+ 'el_label' => el.short_label,
86
+ 'el_tip' => el.short_label,
87
+ 'el_svg' => el.reaction_svg_file
88
+ })
89
+ end
90
+
91
+ def update_table_field(key, field, idx)
92
+ return unless field['sub_values'].present? && field[Labimotion::Prop::SUBFIELDS].present?
93
+
94
+ field_table_molecules = field[Labimotion::Prop::SUBFIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_MOLECULE }
95
+ object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx] = set_table(field, field_table_molecules, Labimotion::Prop::MOLECULE) if field_table_molecules.present?
96
+
97
+ field_table_samples = field[Labimotion::Prop::SUBFIELDS].select { |ss| ss['type'] == Labimotion::FieldType::DRAG_SAMPLE }
98
+ object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx] = set_table(field, field_table_samples, Labimotion::Prop::SAMPLE) if field_table_samples.present?
99
+ end
100
+
101
+ def update_voc_field(key, field, idx)
102
+ root_element = get_root_element
103
+ case field['source']
104
+ when Labimotion::Prop::ELEMENT
105
+ update_element_voc_field(key, field, idx, root_element)
106
+ when Labimotion::Prop::SEGMENT
107
+ update_segment_voc_field(key, field, idx, root_element)
108
+ when Labimotion::Prop::DATASET
109
+ update_dataset_voc_field(key, field, idx, root_element)
110
+ end
111
+ end
112
+
113
+ def get_root_element
114
+ case object.class.name
115
+ when Labimotion::Prop::L_ELEMENT
116
+ object
117
+ when Labimotion::Prop::L_SEGMENT
118
+ object&.element
119
+ when Labimotion::Prop::L_DATASET
120
+ object&.element&.root_element
121
+ end
122
+ end
123
+
124
+ def update_element_voc_field(key, field, idx, root_element)
125
+ if field['identifier'] == 'element.name'
126
+ update_field_value(key, idx, root_element&.name)
127
+ end
128
+ end
129
+
130
+ def update_segment_voc_field(key, field, idx, root_element)
131
+ segs = root_element&.segments&.select { |ss| field['source_id'] == ss.segment_klass&.identifier }
132
+ return if segs.empty? || field['layer_id'].blank? || field['field_id'].blank?
133
+
134
+ seg = segs&.first
135
+ seg_fields = seg.properties.dig(Labimotion::Prop::LAYERS, field['layer_id'], Labimotion::Prop::FIELDS).select { |ff| ff['field'] == field['field_id'] }
136
+ seg_field = seg_fields&.first
137
+ update_field_value(key, idx, seg_field['value'])
138
+ end
139
+
140
+ def update_dataset_voc_field(key, field, idx, root_element)
141
+ dk = DatasetKlass.find_by(identifier: field["source_id"])
142
+ dk["ols_term_id"]
143
+ anas = root_element.analyses.select { |ana| ana.extended_metadata["kind"].split("|")&.first&.strip == dk["ols_term_id"] }
144
+ anas.each do |ana|
145
+ ana.children.each do |cds|
146
+ next unless cds.dataset.present?
147
+
148
+ ds_prop = cds.dataset.properties
149
+ ds_fields = ds_prop.dig(Labimotion::Prop::LAYERS, field['layer_id'], Labimotion::Prop::FIELDS).select { |ff| ff['field'] == field['field_id'] }
150
+ ds_field = ds_fields&.first
151
+ if object.properties[Labimotion::Prop::LAYERS][key].present? && ds_field['value'].present?
152
+ update_field_value(key, idx, ds_field['value'])
153
+ end
56
154
  end
57
155
  end
58
- object.properties
156
+ end
157
+
158
+ def update_field_value(key, idx, value)
159
+ object.properties[Labimotion::Prop::LAYERS][key][Labimotion::Prop::FIELDS][idx]['value'] = value
59
160
  end
60
161
 
61
162
  def set_table(field, field_table_objs, obj)
@@ -69,23 +170,34 @@ module Labimotion
69
170
 
70
171
  case obj
71
172
  when Labimotion::Prop::MOLECULE
72
- sub_value[col_id]['value']['el_svg'] = File.join('/images', 'molecules', find_obj.molecule_svg_file) if find_obj&.molecule_svg_file&.present?
73
- sub_value[col_id]['value']['el_inchikey'] = find_obj.inchikey
74
- sub_value[col_id]['value']['el_smiles'] = find_obj.cano_smiles
75
- sub_value[col_id]['value']['el_iupac'] = find_obj.iupac_name
76
- sub_value[col_id]['value']['el_molecular_weight'] = find_obj.molecular_weight
173
+ update_molecule_sub_value(sub_value, col_id, find_obj)
77
174
  when Labimotion::Prop::SAMPLE
78
- sub_value[col_id]['value']['el_svg'] = find_obj.get_svg_path
79
- sub_value[col_id]['value']['el_label'] = find_obj.short_label
80
- sub_value[col_id]['value']['el_short_label'] = find_obj.short_label
81
- sub_value[col_id]['value']['el_name'] = find_obj.name
82
- sub_value[col_id]['value']['el_external_label'] = find_obj.external_label
83
- sub_value[col_id]['value']['el_molecular_weight'] = find_obj.decoupled ? find_obj.molecular_mass : find_obj.molecule.molecular_weight
175
+ update_sample_sub_value(sub_value, col_id, find_obj)
84
176
  end
85
177
  end
86
178
  end
87
179
  field
88
180
  end
89
181
 
182
+ def update_molecule_sub_value(sub_value, col_id, find_obj)
183
+ sub_value[col_id]['value'].merge!({
184
+ 'el_svg' => File.join('/images', 'molecules', find_obj.molecule_svg_file),
185
+ 'el_inchikey' => find_obj.inchikey,
186
+ 'el_smiles' => find_obj.cano_smiles,
187
+ 'el_iupac' => find_obj.iupac_name,
188
+ 'el_molecular_weight' => find_obj.molecular_weight
189
+ })
190
+ end
191
+
192
+ def update_sample_sub_value(sub_value, col_id, find_obj)
193
+ sub_value[col_id]['value'].merge!({
194
+ 'el_svg' => find_obj.get_svg_path,
195
+ 'el_label' => find_obj.short_label,
196
+ 'el_short_label' => find_obj.short_label,
197
+ 'el_name' => find_obj.name,
198
+ 'el_external_label' => find_obj.external_label,
199
+ 'el_molecular_weight' => find_obj.decoupled ? find_obj.molecular_mass : find_obj.molecule.molecular_weight
200
+ })
201
+ end
90
202
  end
91
- end
203
+ end
@@ -10,5 +10,6 @@ module Labimotion
10
10
  object.segment_klass.label
11
11
  end
12
12
 
13
+
13
14
  end
14
15
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ require 'labimotion/entities/application_entity'
4
+ module Labimotion
5
+ # Dataset entity
6
+ class VocabularyEntity < ApplicationEntity
7
+ expose :id, :identifier, :name, :label, :field_type, :opid, :term_id,
8
+ :field_id, :properties, :source, :source_id, :layer_id
9
+ # expose :source do |obj|
10
+ # (obj[:properties] && obj[:properties]['voc'] && obj[:properties]['voc']['source']) || ''
11
+ # end
12
+ # expose :source_id do |obj|
13
+ # (obj[:properties] && obj[:properties]['voc'] && obj[:properties]['voc']['source_id']) || ''
14
+ # end
15
+ # expose :layer_id do |obj|
16
+ # (obj[:properties] && obj[:properties]['voc'] && obj[:properties]['voc']['layer_id']) || ''
17
+ # end
18
+
19
+ expose :voc do |obj|
20
+ voc = (obj[:properties] && obj[:properties]['voc']) || {}
21
+
22
+ case voc['source']
23
+ when Labimotion::Prop::ELEMENT
24
+ if voc['identifier'] == 'element.name'
25
+ # voc['source_name'] = ElementKlass.find_by(identifier: voc['source_id'])&.name
26
+ end
27
+ when Labimotion::Prop::SEGMENT
28
+ voc['source_name'] = SegmentKlass.find_by(identifier: voc['source_id'])&.label
29
+ when Labimotion::Prop::DATASET
30
+ voc['source_name'] = DatasetKlass.find_by(identifier: voc['source_id'])&.label
31
+ end
32
+ voc
33
+ end
34
+ expose :ontology do |obj|
35
+ (obj[:properties] && obj[:properties]['ontology']) || {}
36
+ end
37
+ end
38
+ end
@@ -93,7 +93,8 @@ module Labimotion
93
93
  all_coll = Collection.get_all_collection_for_user(current_user.id)
94
94
  element.collections << all_coll
95
95
  element.save!
96
- element.properties = update_sample_association(params[:properties], current_user, element)
96
+ _properties = update_sample_association(params[:properties], current_user, element)
97
+ element.properties = update_vocabularies(_properties, current_user, element)
97
98
  element.container = update_datamodel(params[:container], current_user)
98
99
  element.save!
99
100
  update_element_labels(element, params[:user_labels], current_user.id)
@@ -112,7 +113,6 @@ module Labimotion
112
113
  params.delete(:properties)
113
114
  update_element_labels(element, params[:user_labels], current_user.id)
114
115
  params.delete(:user_labels)
115
-
116
116
  attributes = declared(params.except(:segments), include_missing: false)
117
117
  properties['pkg'] = Labimotion::Utils.pkg(properties['pkg'])
118
118
  if element.klass_uuid != properties['klass_uuid'] || element.properties != properties || element.name != params[:name]
@@ -123,15 +123,16 @@ module Labimotion
123
123
  properties.delete('flow') unless properties['flow'].nil?
124
124
  properties.delete('flowObject') unless properties['flowObject'].nil?
125
125
  properties.delete('select_options') unless properties['select_options'].nil?
126
-
127
126
  attributes['properties'] = properties
128
127
  attributes['properties']['uuid'] = uuid
129
128
  attributes['uuid'] = uuid
130
129
  attributes['klass_uuid'] = properties['klass_uuid']
131
-
132
130
  element.update(attributes)
133
131
  end
134
132
  element.save_segments(segments: params[:segments], current_user_id: current_user.id)
133
+ element.reload
134
+ element.properties = update_vocabularies(element.properties, current_user, element)
135
+ element.save!
135
136
  element
136
137
  rescue StandardError => e
137
138
  Labimotion.log_exception(e, current_user)
@@ -321,7 +322,6 @@ module Labimotion
321
322
  return { status: 'success', message: "The element: #{attributes['name']} has been created using version: #{attributes['version']}!" }
322
323
  end
323
324
  end
324
-
325
325
  rescue StandardError => e
326
326
  Labimotion.log_exception(e, current_user)
327
327
  return { status: 'error', message: e.message }
@@ -351,7 +351,9 @@ module Labimotion
351
351
  _att
352
352
  end
353
353
  attachments
354
+ rescue StandardError => e
355
+ Labimotion.log_exception(e)
356
+ attachments
354
357
  end
355
-
356
358
  end
357
359
  end