labimotion 2.1.0.rc4 → 2.1.0.rc5
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.
- checksums.yaml +4 -4
- data/lib/labimotion/apis/generic_element_api.rb +39 -3
- data/lib/labimotion/libs/sample_association.rb +4 -3
- data/lib/labimotion/models/concerns/element_fetchable.rb +53 -0
- data/lib/labimotion/models/device_description.rb +36 -0
- data/lib/labimotion/models/reaction.rb +36 -0
- data/lib/labimotion/models/research_plan.rb +40 -0
- data/lib/labimotion/models/sample.rb +36 -0
- data/lib/labimotion/models/screen.rb +36 -0
- data/lib/labimotion/models/wellplate.rb +40 -0
- data/lib/labimotion/version.rb +1 -1
- data/lib/labimotion.rb +8 -0
- metadata +9 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e23b274f29ceb300bbb97f91830dbe2fdc454966d229e88608cd434b6586a3b3
|
|
4
|
+
data.tar.gz: da620e95cb04ce10a69cba25d8cb63f22cb1e21142a1a6a3c93d9fecc33840aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: db1827e8ad8c56f05c55215f3cd5e3830174f937875c2af49e7899dc4875180364111b1788eecc430b6f3ca8b39e3e0234eb21a3c1036c3b7ab064676f8bb4d1
|
|
7
|
+
data.tar.gz: 3f1667aa18030745ab178330cac70f234d4aa3eab46e3622546aeb4268aaf379e9d8dd0369060324327dd3db67efa2da6e94b6568feb33a88e987bec8030a737
|
|
@@ -87,6 +87,37 @@ module Labimotion
|
|
|
87
87
|
end
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
+
namespace :search_basic_by_like do
|
|
91
|
+
desc 'Search basic elements by name and short label (case-insensitive like search)'
|
|
92
|
+
params do
|
|
93
|
+
requires :klass_name, type: String, desc: 'Class name (device_description or wellplate or ...etc.)', default: 'device_description'
|
|
94
|
+
requires :name, type: String, desc: 'Search query for basic element name'
|
|
95
|
+
requires :short_label, type: String, desc: 'Search query for basic element short label'
|
|
96
|
+
optional :limit, type: Integer, desc: 'Maximum number of results', default: 20
|
|
97
|
+
end
|
|
98
|
+
get do
|
|
99
|
+
# Convert snake_case to PascalCase (e.g. device_description -> DeviceDescription)
|
|
100
|
+
klass_name = params[:klass_name].camelize
|
|
101
|
+
klass = "Labimotion::#{klass_name}".constantize
|
|
102
|
+
|
|
103
|
+
scope = klass.fetch_for_user(
|
|
104
|
+
current_user.id,
|
|
105
|
+
name: params[:name],
|
|
106
|
+
short_label: params[:short_label],
|
|
107
|
+
limit: params[:limit]
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
results = scope.map do |record|
|
|
111
|
+
Labimotion::ElementLookupEntity.represent(record)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
{ elements: results, total_count: results.count }
|
|
115
|
+
rescue StandardError => e
|
|
116
|
+
Labimotion.log_exception(e, current_user)
|
|
117
|
+
{ elements: [], total_count: 0, error: e.message }
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
90
121
|
namespace :export do
|
|
91
122
|
desc 'export element'
|
|
92
123
|
params do
|
|
@@ -253,12 +284,13 @@ module Labimotion
|
|
|
253
284
|
desc 'list Generic Element Klass'
|
|
254
285
|
params do
|
|
255
286
|
optional :is_generic, type: Boolean, desc: 'Is Generic or Non-Generic Element'
|
|
256
|
-
optional :is_active, type: Boolean, desc: 'Active or Inactive
|
|
287
|
+
optional :is_active, type: Boolean, desc: 'Active or Inactive'
|
|
257
288
|
optional :displayed_in_list, type: Boolean, desc: 'Display in list format', default: true
|
|
258
289
|
end
|
|
259
290
|
get do
|
|
260
291
|
scope = params[:displayed_in_list] ? Labimotion::ElementKlass.for_list_display : Labimotion::ElementKlass.all
|
|
261
292
|
scope = scope.where(is_generic: params[:is_generic]) if params.key?(:is_generic)
|
|
293
|
+
scope = scope.where(is_active: params[:is_active]) if params.key?(:is_active)
|
|
262
294
|
|
|
263
295
|
list = scope.sort_by(&:place)
|
|
264
296
|
present list, with: Labimotion::ElementKlassEntity, root: 'klass', displayed_in_list: params[:displayed_in_list]
|
|
@@ -498,8 +530,12 @@ module Labimotion
|
|
|
498
530
|
class ElementLookupEntity < Grape::Entity
|
|
499
531
|
expose :id
|
|
500
532
|
expose :name
|
|
501
|
-
expose :short_label
|
|
502
|
-
|
|
533
|
+
expose :short_label do |element|
|
|
534
|
+
element.respond_to?(:short_label) ? element.short_label : nil
|
|
535
|
+
end
|
|
536
|
+
expose :element_klass_id, as: :element_klass_id do |element|
|
|
537
|
+
element.element_klass&.id
|
|
538
|
+
end
|
|
503
539
|
expose :klass_label, as: :klass_label do |element|
|
|
504
540
|
element.element_klass&.label
|
|
505
541
|
end
|
|
@@ -113,11 +113,12 @@ module Labimotion
|
|
|
113
113
|
Labimotion::ElementsElement.find_or_create_by(parent_id: element.id, element_id: el.id)
|
|
114
114
|
els << el.id
|
|
115
115
|
end
|
|
116
|
-
|
|
117
116
|
end
|
|
118
117
|
if element.present?
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
sds = sds.flatten.uniq
|
|
119
|
+
els = els.flatten.uniq
|
|
120
|
+
es_list = sds.present? ? Labimotion::ElementsSample.where(element_id: element.id).where.not(sample_id: sds) : Labimotion::ElementsSample.where(element_id: element.id)
|
|
121
|
+
ee_list = els.present? ? Labimotion::ElementsElement.where(parent_id: element.id).where.not(element_id: els) : Labimotion::ElementsElement.where(parent_id: element.id)
|
|
121
122
|
es_list.destroy_all if es_list.present?
|
|
122
123
|
ee_list.destroy_all if ee_list.present?
|
|
123
124
|
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Labimotion
|
|
4
|
+
module ElementFetchable
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
class_methods do
|
|
8
|
+
def element_klass
|
|
9
|
+
Labimotion::ElementKlass.find_by(name: element_klass_name)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def fetch_for_user(user_id, name: nil, short_label: nil, limit: 20)
|
|
13
|
+
# Prevent abuse by capping and validating limit
|
|
14
|
+
limit = [limit.to_i, 100].min
|
|
15
|
+
limit = 20 if limit <= 0
|
|
16
|
+
|
|
17
|
+
# Build base scope with common filters
|
|
18
|
+
apply_filters = lambda do |scope|
|
|
19
|
+
scope = scope.where("#{table_name}.name ILIKE ?", "%#{sanitize_sql_like(name)}%") if name.present?
|
|
20
|
+
scope = scope.where("#{table_name}.short_label ILIKE ?", "%#{sanitize_sql_like(short_label)}%") if short_label.present? && column_names.include?('short_label')
|
|
21
|
+
scope
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Owned records
|
|
25
|
+
owned = apply_filters.call(
|
|
26
|
+
joins(collections: :user).where(collections: { user_id: user_id })
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Shared (synced) records
|
|
30
|
+
shared = apply_filters.call(
|
|
31
|
+
joins(collections: :sync_collections_users).where(sync_collections_users: { user_id: user_id })
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# Combine (remove duplicates), order, and limit
|
|
35
|
+
order_column = column_names.include?('short_label') ? :short_label : :name
|
|
36
|
+
from("(#{owned.to_sql} UNION #{shared.to_sql}) AS #{table_name}")
|
|
37
|
+
.order(order_column => :desc)
|
|
38
|
+
.limit(limit)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def element_klass_name
|
|
44
|
+
raise NotImplementedError, "Subclass must define element_klass_name"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Instance method to get element_klass for a record
|
|
49
|
+
def element_klass
|
|
50
|
+
self.class.element_klass
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file extends the existing DeviceDescription model in the consuming app
|
|
4
|
+
# and defines a Labimotion::DeviceDescription wrapper for convenient access.
|
|
5
|
+
|
|
6
|
+
ActiveSupport.on_load(:active_record) do
|
|
7
|
+
if defined?(::DeviceDescription)
|
|
8
|
+
::DeviceDescription.class_eval do
|
|
9
|
+
include Labimotion::ElementFetchable
|
|
10
|
+
|
|
11
|
+
def self.element_klass_name
|
|
12
|
+
'device_description'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
else
|
|
16
|
+
warn "[Labimotion] DeviceDescription is not defined when Labimotion extension was loaded."
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Namespace wrapper to keep your preferred call style
|
|
21
|
+
module Labimotion
|
|
22
|
+
module DeviceDescription
|
|
23
|
+
# Delegate class methods to ::DeviceDescription
|
|
24
|
+
def self.method_missing(method, *args, &block)
|
|
25
|
+
if ::DeviceDescription.respond_to?(method)
|
|
26
|
+
::DeviceDescription.public_send(method, *args, &block)
|
|
27
|
+
else
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.respond_to_missing?(method, include_private = false)
|
|
33
|
+
::DeviceDescription.respond_to?(method, include_private) || super
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file extends the existing Reaction model in the consuming app
|
|
4
|
+
# and defines a Labimotion::Reaction wrapper for convenient access.
|
|
5
|
+
|
|
6
|
+
ActiveSupport.on_load(:active_record) do
|
|
7
|
+
if defined?(::Reaction)
|
|
8
|
+
::Reaction.class_eval do
|
|
9
|
+
include Labimotion::ElementFetchable
|
|
10
|
+
|
|
11
|
+
def self.element_klass_name
|
|
12
|
+
'reaction'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
else
|
|
16
|
+
warn "[Labimotion] Reaction is not defined when Labimotion extension was loaded."
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Namespace wrapper to keep your preferred call style
|
|
21
|
+
module Labimotion
|
|
22
|
+
module Reaction
|
|
23
|
+
# Delegate class methods to ::Reaction
|
|
24
|
+
def self.method_missing(method, *args, &block)
|
|
25
|
+
if ::Reaction.respond_to?(method)
|
|
26
|
+
::Reaction.public_send(method, *args, &block)
|
|
27
|
+
else
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.respond_to_missing?(method, include_private = false)
|
|
33
|
+
::Reaction.respond_to?(method, include_private) || super
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file extends the existing ResearchPlan model in the consuming app
|
|
4
|
+
# and defines a Labimotion::ResearchPlan wrapper for convenient access.
|
|
5
|
+
|
|
6
|
+
# rubocop:disable Style/RedundantConstantBase
|
|
7
|
+
|
|
8
|
+
ActiveSupport.on_load(:active_record) do
|
|
9
|
+
if defined?(::ResearchPlan)
|
|
10
|
+
::ResearchPlan.class_eval do
|
|
11
|
+
include Labimotion::ElementFetchable
|
|
12
|
+
|
|
13
|
+
def self.element_klass_name
|
|
14
|
+
'research_plan'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
warn '[Labimotion] ResearchPlan is not defined when Labimotion extension was loaded.'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Namespace wrapper to keep your preferred call style
|
|
23
|
+
module Labimotion
|
|
24
|
+
module ResearchPlan
|
|
25
|
+
# Delegate class methods to ::ResearchPlan
|
|
26
|
+
def self.method_missing(method, *args, &block)
|
|
27
|
+
if ::ResearchPlan.respond_to?(method)
|
|
28
|
+
::ResearchPlan.public_send(method, *args, &block)
|
|
29
|
+
else
|
|
30
|
+
super
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.respond_to_missing?(method, include_private = false)
|
|
35
|
+
::ResearchPlan.respond_to?(method, include_private) || super
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# rubocop:enable Style/RedundantConstantBase
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file extends the existing Sample model in the consuming app
|
|
4
|
+
# and defines a Labimotion::Sample wrapper for convenient access.
|
|
5
|
+
|
|
6
|
+
ActiveSupport.on_load(:active_record) do
|
|
7
|
+
if defined?(::Sample)
|
|
8
|
+
::Sample.class_eval do
|
|
9
|
+
include Labimotion::ElementFetchable
|
|
10
|
+
|
|
11
|
+
def self.element_klass_name
|
|
12
|
+
'sample'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
else
|
|
16
|
+
warn "[Labimotion] Sample is not defined when Labimotion extension was loaded."
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Namespace wrapper to keep your preferred call style
|
|
21
|
+
module Labimotion
|
|
22
|
+
module Sample
|
|
23
|
+
# Delegate class methods to ::Sample
|
|
24
|
+
def self.method_missing(method, *args, &block)
|
|
25
|
+
if ::Sample.respond_to?(method)
|
|
26
|
+
::Sample.public_send(method, *args, &block)
|
|
27
|
+
else
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.respond_to_missing?(method, include_private = false)
|
|
33
|
+
::Sample.respond_to?(method, include_private) || super
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file extends the existing Screen model in the consuming app
|
|
4
|
+
# and defines a Labimotion::Screen wrapper for convenient access.
|
|
5
|
+
|
|
6
|
+
ActiveSupport.on_load(:active_record) do
|
|
7
|
+
if defined?(::Screen)
|
|
8
|
+
::Screen.class_eval do
|
|
9
|
+
include Labimotion::ElementFetchable
|
|
10
|
+
|
|
11
|
+
def self.element_klass_name
|
|
12
|
+
'screen'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
else
|
|
16
|
+
warn "[Labimotion] Screen is not defined when Labimotion extension was loaded."
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Namespace wrapper to keep your preferred call style
|
|
21
|
+
module Labimotion
|
|
22
|
+
module Screen
|
|
23
|
+
# Delegate class methods to ::Screen
|
|
24
|
+
def self.method_missing(method, *args, &block)
|
|
25
|
+
if ::Screen.respond_to?(method)
|
|
26
|
+
::Screen.public_send(method, *args, &block)
|
|
27
|
+
else
|
|
28
|
+
super
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.respond_to_missing?(method, include_private = false)
|
|
33
|
+
::Screen.respond_to?(method, include_private) || super
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file extends the existing Wellplate model in the consuming app
|
|
4
|
+
# and defines a Labimotion::Wellplate wrapper for convenient access.
|
|
5
|
+
|
|
6
|
+
# rubocop:disable Style/RedundantConstantBase
|
|
7
|
+
|
|
8
|
+
ActiveSupport.on_load(:active_record) do
|
|
9
|
+
if defined?(::Wellplate)
|
|
10
|
+
::Wellplate.class_eval do
|
|
11
|
+
include Labimotion::ElementFetchable
|
|
12
|
+
|
|
13
|
+
def self.element_klass_name
|
|
14
|
+
'wellplate'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
warn '[Labimotion] Wellplate is not defined when Labimotion extension was loaded.'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Namespace wrapper to keep your preferred call style
|
|
23
|
+
module Labimotion
|
|
24
|
+
module Wellplate
|
|
25
|
+
# Delegate class methods to ::Wellplate
|
|
26
|
+
def self.method_missing(method, *args, &block)
|
|
27
|
+
if ::Wellplate.respond_to?(method)
|
|
28
|
+
::Wellplate.public_send(method, *args, &block)
|
|
29
|
+
else
|
|
30
|
+
super
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.respond_to_missing?(method, include_private = false)
|
|
35
|
+
::Wellplate.respond_to?(method, include_private) || super
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# rubocop:enable Style/RedundantConstantBase
|
data/lib/labimotion/version.rb
CHANGED
data/lib/labimotion.rb
CHANGED
|
@@ -113,9 +113,17 @@ module Labimotion
|
|
|
113
113
|
autoload :StdLayer, 'labimotion/models/std_layer'
|
|
114
114
|
autoload :StdLayersRevision, 'labimotion/models/std_layers_revision'
|
|
115
115
|
|
|
116
|
+
autoload :DeviceDescription, 'labimotion/models/device_description'
|
|
117
|
+
autoload :Reaction, 'labimotion/models/reaction'
|
|
118
|
+
autoload :ResearchPlan, 'labimotion/models/research_plan'
|
|
119
|
+
autoload :Sample, 'labimotion/models/sample'
|
|
120
|
+
autoload :Screen, 'labimotion/models/screen'
|
|
121
|
+
autoload :Wellplate, 'labimotion/models/wellplate'
|
|
122
|
+
|
|
116
123
|
######## Models/Concerns
|
|
117
124
|
autoload :GenericKlassRevisions, 'labimotion/models/concerns/generic_klass_revisions'
|
|
118
125
|
autoload :GenericRevisions, 'labimotion/models/concerns/generic_revisions'
|
|
126
|
+
autoload :ElementFetchable, 'labimotion/models/concerns/element_fetchable'
|
|
119
127
|
autoload :Segmentable, 'labimotion/models/concerns/segmentable'
|
|
120
128
|
autoload :Datasetable, 'labimotion/models/concerns/datasetable'
|
|
121
129
|
autoload :AttachmentConverter, 'labimotion/models/concerns/attachment_converter.rb'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: labimotion
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.1.0.
|
|
4
|
+
version: 2.1.0.rc5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chia-Lin Lin
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2025-10-
|
|
12
|
+
date: 2025-10-27 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: caxlsx
|
|
@@ -116,6 +116,7 @@ files:
|
|
|
116
116
|
- lib/labimotion/models/collections_element.rb
|
|
117
117
|
- lib/labimotion/models/concerns/attachment_converter.rb
|
|
118
118
|
- lib/labimotion/models/concerns/datasetable.rb
|
|
119
|
+
- lib/labimotion/models/concerns/element_fetchable.rb
|
|
119
120
|
- lib/labimotion/models/concerns/generic_klass.rb
|
|
120
121
|
- lib/labimotion/models/concerns/generic_klass_revisions.rb
|
|
121
122
|
- lib/labimotion/models/concerns/generic_revisions.rb
|
|
@@ -126,6 +127,7 @@ files:
|
|
|
126
127
|
- lib/labimotion/models/dataset_klass.rb
|
|
127
128
|
- lib/labimotion/models/dataset_klasses_revision.rb
|
|
128
129
|
- lib/labimotion/models/datasets_revision.rb
|
|
130
|
+
- lib/labimotion/models/device_description.rb
|
|
129
131
|
- lib/labimotion/models/element.rb
|
|
130
132
|
- lib/labimotion/models/element_klass.rb
|
|
131
133
|
- lib/labimotion/models/element_klasses_revision.rb
|
|
@@ -133,6 +135,10 @@ files:
|
|
|
133
135
|
- lib/labimotion/models/elements_revision.rb
|
|
134
136
|
- lib/labimotion/models/elements_sample.rb
|
|
135
137
|
- lib/labimotion/models/hub_log.rb
|
|
138
|
+
- lib/labimotion/models/reaction.rb
|
|
139
|
+
- lib/labimotion/models/research_plan.rb
|
|
140
|
+
- lib/labimotion/models/sample.rb
|
|
141
|
+
- lib/labimotion/models/screen.rb
|
|
136
142
|
- lib/labimotion/models/segment.rb
|
|
137
143
|
- lib/labimotion/models/segment_klass.rb
|
|
138
144
|
- lib/labimotion/models/segment_klasses_revision.rb
|
|
@@ -140,6 +146,7 @@ files:
|
|
|
140
146
|
- lib/labimotion/models/std_layer.rb
|
|
141
147
|
- lib/labimotion/models/std_layers_revision.rb
|
|
142
148
|
- lib/labimotion/models/vocabulary.rb
|
|
149
|
+
- lib/labimotion/models/wellplate.rb
|
|
143
150
|
- lib/labimotion/utils/con_state.rb
|
|
144
151
|
- lib/labimotion/utils/export_utils.rb
|
|
145
152
|
- lib/labimotion/utils/field_type.rb
|