labimotion 1.4.1 → 2.0.0.rc2

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 +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 +39 -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: 608624a39eb174198e63db9cde2e4440425aa6bad1c604801c817ea13caea859
4
+ data.tar.gz: c691e2f9e670d301acc2494745e02836bf8ffcb1479c86c747f02ff9fadc6617
5
5
  SHA512:
6
- metadata.gz: 41655a864b15b848116b370964ae6a05c707512d6ba80987cdec1f392d3fb647476fcf119612f116a2923c4992e32b00127371ac8a77d6e7de6cf1dc94773dbd
7
- data.tar.gz: 8308707ad72ac2ebd38c725bc1336151712b5900fa4f35429674ee54f26cbe6fcc7ed43ef71777b6dd069701411540c776a7f183b183d147c1a3658a124e12a7
6
+ metadata.gz: e3c03f09293537ad8993158d1e1871fff2bf6a84ff88d90ca5d55af663fa862df4907a72639a2cdfb4bb7a2371911bf37b146cc97fbf0030945d3c23b5777de9
7
+ data.tar.gz: c746e80182b677d03c5bf06608285441a7b7022fdfcf521aec2aeaab61470d7a774ce059919d35e4b671446890b4055e3707da8b9a7f2fa52b4446fe52fbf655
@@ -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: SecureRandom.uuid,
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,39 @@
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
+ voc['source_name'] = ElementKlass.find_by(identifier: voc['source_id'])&.label
25
+ # if voc['identifier'] == 'element.name'
26
+ # voc['source_name'] = ElementKlass.find_by(identifier: voc['source_id'])&.name
27
+ # end
28
+ when Labimotion::Prop::SEGMENT
29
+ voc['source_name'] = SegmentKlass.find_by(identifier: voc['source_id'])&.label
30
+ when Labimotion::Prop::DATASET
31
+ voc['source_name'] = DatasetKlass.find_by(identifier: voc['source_id'])&.label
32
+ end
33
+ voc
34
+ end
35
+ expose :ontology do |obj|
36
+ (obj[:properties] && obj[:properties]['ontology']) || {}
37
+ end
38
+ end
39
+ 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
+ new_properties = update_vocabularies(element.properties, current_user, element)
135
+ element.update_column(:properties, new_properties)
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