labimotion 2.1.0.rc13 → 2.1.0.rc15
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 +3 -2
- data/lib/labimotion/apis/labimotion_api.rb +3 -1
- data/lib/labimotion/apis/labimotion_hub_api.rb +83 -10
- data/lib/labimotion/collection/import.rb +3 -3
- data/lib/labimotion/constants.rb +7 -0
- data/lib/labimotion/entities/dataset_entity.rb +1 -0
- data/lib/labimotion/entities/element_entity.rb +1 -0
- data/lib/labimotion/entities/element_revision_entity.rb +1 -1
- data/lib/labimotion/entities/generic_klass_entity.rb +1 -0
- data/lib/labimotion/entities/generic_public_entity.rb +1 -0
- data/lib/labimotion/entities/klass_revision_entity.rb +5 -8
- data/lib/labimotion/entities/segment_entity.rb +1 -0
- data/lib/labimotion/entities/segment_revision_entity.rb +1 -1
- data/lib/labimotion/helpers/dataset_helpers.rb +1 -1
- data/lib/labimotion/helpers/element_helpers.rb +7 -3
- data/lib/labimotion/helpers/generic_helpers.rb +1 -0
- data/lib/labimotion/helpers/param_helpers.rb +6 -0
- data/lib/labimotion/helpers/segment_helpers.rb +1 -1
- data/lib/labimotion/libs/converter.rb +2 -1
- data/lib/labimotion/libs/dataset_builder.rb +2 -1
- data/lib/labimotion/libs/template_hub.rb +28 -10
- data/lib/labimotion/models/concerns/datasetable.rb +10 -6
- data/lib/labimotion/models/concerns/generic_klass_revisions.rb +3 -3
- data/lib/labimotion/models/concerns/generic_revisions.rb +2 -1
- data/lib/labimotion/models/concerns/klass_revision.rb +23 -0
- data/lib/labimotion/models/concerns/metadata_validation.rb +34 -0
- data/lib/labimotion/models/concerns/segmentable.rb +2 -2
- data/lib/labimotion/models/dataset_klass.rb +2 -0
- data/lib/labimotion/models/dataset_klasses_revision.rb +6 -1
- data/lib/labimotion/models/element_klass.rb +2 -0
- data/lib/labimotion/models/element_klasses_revision.rb +5 -2
- data/lib/labimotion/models/segment_klass.rb +2 -0
- data/lib/labimotion/models/segment_klasses_revision.rb +6 -1
- data/lib/labimotion/models/template_submission.rb +52 -0
- data/lib/labimotion/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 00f664a1f81cf5face58aaffb1855e0056643ae6e624ec01a41299e2097d4f78
|
|
4
|
+
data.tar.gz: f2591aee3db2b0de0019f7a85191b1bf0b84f1ee5ebf9ada9861782115fd415c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fcf9e9ee81ce54790ad7005f5b9bb6143052f1c5c0b5fcfe3fb4fd1d88c49603d8b91783dd997f0aa5a2242a22aaa34e77bcd9d7680006d4aab4d945e2b82785
|
|
7
|
+
data.tar.gz: deb0ed0dbf6537d1af22cb89fabae0d1f2c82565c21e5cf4a588be70c2dcc79e1e83c8695aa3188105d7fed2b08e794b03d0511c9819625d064ea7544d76999c
|
|
@@ -378,6 +378,7 @@ module Labimotion
|
|
|
378
378
|
requires :klass, type: String, desc: 'Klass', values: %w[ElementKlass SegmentKlass DatasetKlass]
|
|
379
379
|
requires :id, type: Integer, desc: 'Klass ID'
|
|
380
380
|
requires :properties_template, type: Hash
|
|
381
|
+
optional :metadata, type: Hash, default: {}
|
|
381
382
|
optional :release, type: String, default: 'draft', desc: 'release status', values: %w[draft major minor patch]
|
|
382
383
|
end
|
|
383
384
|
after_validation do
|
|
@@ -473,7 +474,7 @@ module Labimotion
|
|
|
473
474
|
detail_levels: ElementDetailLevelCalculator.new(user: current_user, element: element).detail_levels,
|
|
474
475
|
policy: @element_policy
|
|
475
476
|
),
|
|
476
|
-
attachments:
|
|
477
|
+
attachments: Entities::AttachmentEntity.represent(element&.attachments)
|
|
477
478
|
}
|
|
478
479
|
rescue StandardError => e
|
|
479
480
|
Labimotion.log_exception(e, current_user)
|
|
@@ -516,7 +517,7 @@ module Labimotion
|
|
|
516
517
|
element,
|
|
517
518
|
detail_levels: ElementDetailLevelCalculator.new(user: current_user, element: element).detail_levels,
|
|
518
519
|
),
|
|
519
|
-
attachments:
|
|
520
|
+
attachments: Entities::AttachmentEntity.represent(element&.attachments),
|
|
520
521
|
}
|
|
521
522
|
rescue StandardError => e
|
|
522
523
|
Labimotion.log_exception(e, current_user)
|
|
@@ -11,24 +11,24 @@ module Labimotion
|
|
|
11
11
|
|
|
12
12
|
namespace :labimotion_hub do
|
|
13
13
|
namespace :list do
|
|
14
|
-
desc
|
|
14
|
+
desc 'get active generic templates'
|
|
15
15
|
params do
|
|
16
|
-
requires :klass, type: String, desc: 'Klass', values:
|
|
16
|
+
requires :klass, type: String, desc: 'Klass', values: Labimotion::Constants::Klass::ALL
|
|
17
17
|
optional :with_props, type: Boolean, desc: 'With Properties', default: false
|
|
18
18
|
end
|
|
19
19
|
get do
|
|
20
20
|
list = "Labimotion::#{params[:klass]}".constantize.where(is_active: true).where.not(released_at: nil)
|
|
21
|
-
list = list.where(is_generic: true) if params[:klass] ==
|
|
22
|
-
|
|
21
|
+
list = list.where(is_generic: true) if params[:klass] == Labimotion::Constants::Klass::ELEMENT
|
|
22
|
+
Labimotion::GenericPublicEntity.represent(list, displayed: params[:with_props], root: 'list')
|
|
23
23
|
rescue StandardError => e
|
|
24
24
|
Labimotion.log_exception(e, current_user)
|
|
25
25
|
[]
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
namespace :fetch do
|
|
29
|
-
desc
|
|
29
|
+
desc 'get active generic templates'
|
|
30
30
|
params do
|
|
31
|
-
requires :klass, type: String, desc: 'Klass', values:
|
|
31
|
+
requires :klass, type: String, desc: 'Klass', values: Labimotion::Constants::Klass::ALL
|
|
32
32
|
requires :origin, type: String, desc: 'origin'
|
|
33
33
|
requires :identifier, type: String, desc: 'Identifier'
|
|
34
34
|
end
|
|
@@ -43,13 +43,16 @@ module Labimotion
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
namespace :element_klasses_name do
|
|
46
|
-
desc
|
|
46
|
+
desc 'get klasses'
|
|
47
47
|
params do
|
|
48
|
-
optional :generic_only, type: Boolean, desc:
|
|
48
|
+
optional :generic_only, type: Boolean, desc: 'list generic element only'
|
|
49
49
|
end
|
|
50
50
|
get do
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
if params[:generic_only].present? && params[:generic_only] == true
|
|
52
|
+
list = Labimotion::ElementKlass.where(is_active: true, is_generic: true)
|
|
53
|
+
else
|
|
54
|
+
list = Labimotion::ElementKlass.where(is_active: true)
|
|
55
|
+
end
|
|
53
56
|
list.pluck(:name)
|
|
54
57
|
rescue StandardError => e
|
|
55
58
|
Labimotion.log_exception(e, current_user)
|
|
@@ -57,6 +60,76 @@ module Labimotion
|
|
|
57
60
|
end
|
|
58
61
|
end
|
|
59
62
|
|
|
63
|
+
namespace :submit do
|
|
64
|
+
desc 'submit a template'
|
|
65
|
+
params do
|
|
66
|
+
requires :klass, type: String, desc: 'klass of the template',
|
|
67
|
+
values: Labimotion::Constants::Klass::ALL
|
|
68
|
+
requires :id, type: Integer, desc: 'template revision id'
|
|
69
|
+
requires :contact_email, type: String, desc: 'email of the submitter', regexp: URI::MailTo::EMAIL_REGEXP
|
|
70
|
+
requires :application, type: String, desc: 'application for the template'
|
|
71
|
+
requires :message, type: String, desc: 'message of the submission'
|
|
72
|
+
end
|
|
73
|
+
post do
|
|
74
|
+
klass = params[:klass]
|
|
75
|
+
template = "Labimotion::#{klass}esRevision".constantize.find(params[:id])
|
|
76
|
+
klass_data = "Labimotion::#{klass}Entity".constantize.represent(template.klass, displayed_in_list: true)
|
|
77
|
+
metadata = {
|
|
78
|
+
klass: {
|
|
79
|
+
klass: klass,
|
|
80
|
+
data: klass_data
|
|
81
|
+
},
|
|
82
|
+
submission: {
|
|
83
|
+
last_name: current_user.last_name,
|
|
84
|
+
first_name: current_user.first_name,
|
|
85
|
+
email: current_user.email,
|
|
86
|
+
id: current_user.id,
|
|
87
|
+
contact_email: params[:contact_email],
|
|
88
|
+
application: params[:application],
|
|
89
|
+
message: params[:message]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
# Submit the main template
|
|
94
|
+
result = Labimotion::TemplateHub.send_to_central_hub(klass, template.properties_release, metadata,
|
|
95
|
+
request.headers['Origin'])
|
|
96
|
+
|
|
97
|
+
# Increment submitted counter if submission was successful
|
|
98
|
+
template.increment_submitted! if result[:mc] == 'ss00'
|
|
99
|
+
|
|
100
|
+
# For SegmentKlass, also submit the associated ElementKlass
|
|
101
|
+
if klass == Labimotion::Constants::Klass::SEGMENT && result[:mc] == 'ss00'
|
|
102
|
+
element_klass = template.klass.element_klass
|
|
103
|
+
element_klass_data = Labimotion::ElementKlassEntity.represent(element_klass, displayed_in_list: true)
|
|
104
|
+
element_metadata = {
|
|
105
|
+
klass: {
|
|
106
|
+
klass: Labimotion::Constants::Klass::ELEMENT,
|
|
107
|
+
data: element_klass_data
|
|
108
|
+
},
|
|
109
|
+
submission: metadata[:submission].merge(
|
|
110
|
+
associated_submission_id: result[:data][:id]
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
element_result = Labimotion::TemplateHub.send_to_central_hub(Labimotion::Constants::Klass::ELEMENT,
|
|
115
|
+
element_klass.properties_release,
|
|
116
|
+
element_metadata, request.headers['Origin'])
|
|
117
|
+
|
|
118
|
+
# Increment the ElementKlass revision counter if submission was successful
|
|
119
|
+
if element_result[:mc] == 'ss00'
|
|
120
|
+
# Find the revision that matches the ElementKlass UUID
|
|
121
|
+
element_revision = Labimotion::ElementKlassesRevision.find_by(uuid: element_klass.uuid)
|
|
122
|
+
element_revision&.increment_submitted!
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Only return the main result; TODO: handle element_result as well
|
|
127
|
+
result
|
|
128
|
+
rescue StandardError => e
|
|
129
|
+
Labimotion.log_exception(e, current_user)
|
|
130
|
+
{ mc: 'se00', msg: e.message, data: [] }
|
|
131
|
+
end
|
|
132
|
+
end
|
|
60
133
|
end
|
|
61
134
|
end
|
|
62
135
|
end
|
|
@@ -69,7 +69,7 @@ module Labimotion
|
|
|
69
69
|
|
|
70
70
|
dataset = Labimotion::Dataset.create!(
|
|
71
71
|
fields.slice(
|
|
72
|
-
'properties', 'properties_release'
|
|
72
|
+
'properties', 'properties_release', 'metadata'
|
|
73
73
|
).merge(
|
|
74
74
|
## created_by: current_user_id,
|
|
75
75
|
element: element,
|
|
@@ -112,7 +112,7 @@ module Labimotion
|
|
|
112
112
|
|
|
113
113
|
segment = Labimotion::Segment.create!(
|
|
114
114
|
fields.slice(
|
|
115
|
-
'properties', 'properties_release'
|
|
115
|
+
'properties', 'properties_release', 'metadata'
|
|
116
116
|
).merge(
|
|
117
117
|
created_by: current_user_id,
|
|
118
118
|
element: element,
|
|
@@ -149,7 +149,7 @@ module Labimotion
|
|
|
149
149
|
|
|
150
150
|
element = Labimotion::Element.create!(
|
|
151
151
|
fields.slice(
|
|
152
|
-
'name', 'properties', 'properties_release'
|
|
152
|
+
'name', 'properties', 'properties_release', 'metadata'
|
|
153
153
|
).merge(
|
|
154
154
|
created_by: current_user_id,
|
|
155
155
|
element_klass: element_klass,
|
data/lib/labimotion/constants.rb
CHANGED
|
@@ -21,5 +21,12 @@ module Labimotion
|
|
|
21
21
|
NMR_CONFIG = ::File.join(__dir__, 'libs', 'data', 'mapper', 'Source.json').freeze
|
|
22
22
|
WIKI_CONFIG = ::File.join(__dir__, 'libs', 'data', 'mapper', 'Chemwiki.json').freeze
|
|
23
23
|
end
|
|
24
|
+
|
|
25
|
+
module Klass
|
|
26
|
+
ELEMENT = 'ElementKlass'
|
|
27
|
+
SEGMENT = 'SegmentKlass'
|
|
28
|
+
DATASET = 'DatasetKlass'
|
|
29
|
+
ALL = [ELEMENT, SEGMENT, DATASET].freeze
|
|
30
|
+
end
|
|
24
31
|
end
|
|
25
32
|
end
|
|
@@ -9,6 +9,7 @@ module Labimotion
|
|
|
9
9
|
expose :klass_ols, :klass_label, :klass_uuid
|
|
10
10
|
expose :properties, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
11
11
|
expose :properties_release, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
12
|
+
expose :metadata, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
12
13
|
|
|
13
14
|
def klass_ols
|
|
14
15
|
object&.dataset_klass&.ols_term_id
|
|
@@ -4,7 +4,7 @@ require 'labimotion/entities/application_entity'
|
|
|
4
4
|
module Labimotion
|
|
5
5
|
# ElementRevisionEntity
|
|
6
6
|
class ElementRevisionEntity < Labimotion::ApplicationEntity
|
|
7
|
-
expose :id, :element_id, :uuid, :name, :klass_uuid, :properties, :created_at
|
|
7
|
+
expose :id, :element_id, :uuid, :name, :klass_uuid, :properties, :metadata, :created_at
|
|
8
8
|
def created_at
|
|
9
9
|
object.created_at.strftime('%d.%m.%Y, %H:%M')
|
|
10
10
|
end
|
|
@@ -8,6 +8,7 @@ module Labimotion
|
|
|
8
8
|
|
|
9
9
|
expose :properties_template, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
10
10
|
expose :properties_release, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
11
|
+
expose :metadata, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
11
12
|
expose_timestamps(timestamp_fields: %i[released_at created_at updated_at sync_time])
|
|
12
13
|
end
|
|
13
14
|
end
|
|
@@ -18,6 +18,7 @@ module Labimotion
|
|
|
18
18
|
expose! :version
|
|
19
19
|
expose! :released_at
|
|
20
20
|
expose :properties_release, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
21
|
+
expose :metadata, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
21
22
|
expose :element_klass do |obj|
|
|
22
23
|
if obj[:element_klass_id]
|
|
23
24
|
{ label: obj.element_klass.label, icon_name: obj.element_klass.icon_name, id: obj.element_klass_id }
|
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
require 'labimotion/entities/application_entity'
|
|
4
4
|
module Labimotion
|
|
5
|
-
# KlassRevisionEntity
|
|
6
5
|
class KlassRevisionEntity < Labimotion::ApplicationEntity
|
|
7
|
-
expose :id, :uuid, :
|
|
6
|
+
expose :id, :uuid, :version, :released_at, :klass_id, :submitted
|
|
7
|
+
expose :properties_release, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
8
|
+
expose :metadata, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
klass_id = object.segment_klass_id if object.respond_to? :segment_klass_id
|
|
12
|
-
klass_id = object.dataset_klass_id if object.respond_to? :dataset_klass_id
|
|
13
|
-
klass_id
|
|
10
|
+
def klass_id
|
|
11
|
+
object.klass&.id
|
|
14
12
|
end
|
|
15
13
|
|
|
16
14
|
def released_at
|
|
@@ -18,4 +16,3 @@ module Labimotion
|
|
|
18
16
|
end
|
|
19
17
|
end
|
|
20
18
|
end
|
|
21
|
-
|
|
@@ -8,6 +8,7 @@ module Labimotion
|
|
|
8
8
|
expose :id, :segment_klass_id, :element_type, :element_id, :uuid, :klass_uuid, :klass_label
|
|
9
9
|
expose :properties, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
10
10
|
expose :properties_release, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
11
|
+
expose :metadata, **DISPLAYED_IN_LIST_CONDITION, anonymize_with: {}
|
|
11
12
|
|
|
12
13
|
def klass_label
|
|
13
14
|
object.segment_klass.label
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require 'labimotion/entities/application_entity'
|
|
4
4
|
module Labimotion
|
|
5
5
|
class SegmentRevisionEntity < Labimotion::ApplicationEntity
|
|
6
|
-
expose :id, :segment_id, :uuid, :klass_uuid, :properties, :created_at
|
|
6
|
+
expose :id, :segment_id, :uuid, :klass_uuid, :properties, :metadata, :created_at
|
|
7
7
|
def created_at
|
|
8
8
|
object.created_at.strftime('%d.%m.%Y, %H:%M')
|
|
9
9
|
end
|
|
@@ -17,7 +17,7 @@ module Labimotion
|
|
|
17
17
|
|
|
18
18
|
def create_repo_klass(params, current_user, origin)
|
|
19
19
|
response = Labimotion::TemplateHub.fetch_identifier('DatasetKlass', params[:identifier], origin)
|
|
20
|
-
attributes = response.slice('ols_term_id', 'label', 'desc', 'uuid', 'identifier', 'properties_release', 'version') # .except(:id, :is_active, :place, :created_by, :created_at, :updated_at)
|
|
20
|
+
attributes = response.slice('ols_term_id', 'label', 'desc', 'uuid', 'identifier', 'properties_release', 'version', 'metadata') # .except(:id, :is_active, :place, :created_by, :created_at, :updated_at)
|
|
21
21
|
attributes['properties_release']['identifier'] = attributes['identifier']
|
|
22
22
|
attributes['properties_template'] = attributes['properties_release']
|
|
23
23
|
attributes['place'] = ((Labimotion::DatasetKlass.all.length * 10) || 0) + 10
|
|
@@ -82,7 +82,8 @@ module Labimotion
|
|
|
82
82
|
klass_uuid: klass[:uuid],
|
|
83
83
|
properties: properties,
|
|
84
84
|
properties_release: params[:properties_release],
|
|
85
|
-
|
|
85
|
+
metadata: params[:metadata] || {},
|
|
86
|
+
created_by: current_user.id
|
|
86
87
|
}
|
|
87
88
|
element = Labimotion::Element.new(attributes)
|
|
88
89
|
|
|
@@ -116,7 +117,8 @@ module Labimotion
|
|
|
116
117
|
params.delete(:user_labels)
|
|
117
118
|
attributes = declared(params.except(:segments), include_missing: false)
|
|
118
119
|
properties['pkg'] = Labimotion::Utils.pkg(properties['pkg'])
|
|
119
|
-
|
|
120
|
+
metadata = params[:metadata] || element.metadata || {}
|
|
121
|
+
if element.klass_uuid != properties['klass_uuid'] || element.properties != properties || element.name != params[:name] || element.metadata != metadata
|
|
120
122
|
properties['klass'] = 'Element'
|
|
121
123
|
uuid = SecureRandom.uuid
|
|
122
124
|
properties['uuid'] = uuid
|
|
@@ -128,6 +130,8 @@ module Labimotion
|
|
|
128
130
|
attributes['properties']['uuid'] = uuid
|
|
129
131
|
attributes['uuid'] = uuid
|
|
130
132
|
attributes['klass_uuid'] = properties['klass_uuid']
|
|
133
|
+
attributes['metadata'] = metadata
|
|
134
|
+
attributes['updated_at'] = Time.current
|
|
131
135
|
element.update_columns(attributes)
|
|
132
136
|
end
|
|
133
137
|
# element.save_segments(segments: params[:segments], current_user_id: current_user.id)
|
|
@@ -333,7 +337,7 @@ module Labimotion
|
|
|
333
337
|
|
|
334
338
|
def create_repo_klass(params, current_user, origin)
|
|
335
339
|
response = Labimotion::TemplateHub.fetch_identifier('ElementKlass', params[:identifier], origin)
|
|
336
|
-
attributes = response.slice('name', 'label', 'desc', 'icon_name', 'uuid', 'klass_prefix', 'is_generic', 'identifier', 'properties_release', 'version')
|
|
340
|
+
attributes = response.slice('name', 'label', 'desc', 'icon_name', 'uuid', 'klass_prefix', 'is_generic', 'identifier', 'properties_release', 'version', 'metadata')
|
|
337
341
|
attributes['properties_release']['identifier'] = attributes['identifier']
|
|
338
342
|
attributes['properties_template'] = attributes['properties_release']
|
|
339
343
|
attributes['place'] = ((Labimotion::ElementKlass.all.length * 10) || 0) + 10
|
|
@@ -60,6 +60,7 @@ module Labimotion
|
|
|
60
60
|
properties.delete('eln') if properties['eln'].present?
|
|
61
61
|
klz.updated_by = current_user.id
|
|
62
62
|
klz.properties_template = properties
|
|
63
|
+
klz.metadata = params[:metadata] || {}
|
|
63
64
|
klz.save!
|
|
64
65
|
klz.reload
|
|
65
66
|
klz.create_klasses_revision(current_user) if params[:release] != 'draft'
|
|
@@ -13,6 +13,7 @@ module Labimotion
|
|
|
13
13
|
optional :desc, type: String, desc: 'Klass desc'
|
|
14
14
|
optional :klass_prefix, type: String, desc: 'Klass klass_prefix'
|
|
15
15
|
optional :icon_name, type: String, desc: 'Klass icon_name'
|
|
16
|
+
optional :metadata, type: Hash, desc: 'Klass metadata'
|
|
16
17
|
requires :properties_template, type: Hash, desc: 'Klass template'
|
|
17
18
|
optional :properties_release, type: Hash, desc: 'Klass release'
|
|
18
19
|
optional :released_at, type: DateTime, desc: 'Klass released_at'
|
|
@@ -29,6 +30,7 @@ module Labimotion
|
|
|
29
30
|
requires :klass_prefix, type: String, desc: 'Element Klass Short Label Prefix'
|
|
30
31
|
optional :icon_name, type: String, desc: 'Element Klass Icon Name'
|
|
31
32
|
optional :desc, type: String, desc: 'Element Klass Desc'
|
|
33
|
+
optional :metadata, type: Hash, desc: 'Element Klass metadata'
|
|
32
34
|
optional :properties_template, type: Hash, desc: 'Element Klass properties template'
|
|
33
35
|
end
|
|
34
36
|
|
|
@@ -47,6 +49,7 @@ module Labimotion
|
|
|
47
49
|
requires :name, type: String
|
|
48
50
|
optional :properties, type: Hash
|
|
49
51
|
optional :properties_release, type: Hash
|
|
52
|
+
optional :metadata, type: Hash
|
|
50
53
|
optional :collection_id, type: Integer
|
|
51
54
|
requires :container, type: Hash
|
|
52
55
|
optional :user_labels, type: Array
|
|
@@ -58,6 +61,7 @@ module Labimotion
|
|
|
58
61
|
optional :name, type: String
|
|
59
62
|
requires :properties, type: Hash
|
|
60
63
|
optional :properties_release, type: Hash
|
|
64
|
+
optional :metadata, type: Hash
|
|
61
65
|
requires :container, type: Hash
|
|
62
66
|
optional :user_labels, type: Array
|
|
63
67
|
optional :segments, type: Array, desc: 'Segments'
|
|
@@ -67,6 +71,7 @@ module Labimotion
|
|
|
67
71
|
params :upload_segment_klass_params do
|
|
68
72
|
requires :label, type: String, desc: 'Klass label'
|
|
69
73
|
optional :desc, type: String, desc: 'Klass desc'
|
|
74
|
+
optional :metadata, type: Hash, desc: 'Klass metadata'
|
|
70
75
|
requires :properties_template, type: Hash, desc: 'Klass template'
|
|
71
76
|
optional :properties_release, type: Hash, desc: 'Klass release'
|
|
72
77
|
optional :released_at, type: DateTime, desc: 'Klass released_at'
|
|
@@ -93,6 +98,7 @@ module Labimotion
|
|
|
93
98
|
requires :element_klass, type: Integer, desc: 'Element Klass Id'
|
|
94
99
|
optional :desc, type: String, desc: 'Segment Klass Desc'
|
|
95
100
|
optional :place, type: String, desc: 'Segment Klass Place', default: '100'
|
|
101
|
+
optional :metadata, type: Hash, desc: 'Klass metadata'
|
|
96
102
|
optional :properties_template, type: Hash, desc: 'Element Klass properties template'
|
|
97
103
|
end
|
|
98
104
|
|
|
@@ -99,7 +99,7 @@ module Labimotion
|
|
|
99
99
|
|
|
100
100
|
def create_repo_klass(params, current_user, origin)
|
|
101
101
|
response = Labimotion::TemplateHub.fetch_identifier('SegmentKlass', params[:identifier], origin)
|
|
102
|
-
attributes = response.slice('label', 'desc', 'uuid', 'identifier', 'released_at', 'properties_release', 'version')
|
|
102
|
+
attributes = response.slice('label', 'desc', 'uuid', 'identifier', 'released_at', 'properties_release', 'version', 'metadata')
|
|
103
103
|
attributes['properties_release']['identifier'] = attributes['identifier']
|
|
104
104
|
attributes['properties_template'] = attributes['properties_release']
|
|
105
105
|
attributes['place'] = ((Labimotion::SegmentKlass.all.length * 10) || 0) + 10
|
|
@@ -5,9 +5,6 @@ require 'uri'
|
|
|
5
5
|
require 'json'
|
|
6
6
|
require 'date'
|
|
7
7
|
|
|
8
|
-
# rubocop: disable Metrics/AbcSize
|
|
9
|
-
# rubocop: disable Metrics/MethodLength
|
|
10
|
-
|
|
11
8
|
module Labimotion
|
|
12
9
|
## TemplateHub
|
|
13
10
|
class TemplateHub
|
|
@@ -18,12 +15,11 @@ module Labimotion
|
|
|
18
15
|
"#{url}api/v1/labimotion_hub/#{api_name}"
|
|
19
16
|
end
|
|
20
17
|
|
|
21
|
-
|
|
22
18
|
def self.header(opt = {})
|
|
23
19
|
opt || { timeout: 10, headers: { 'Content-Type' => 'text/json' } }
|
|
24
20
|
end
|
|
25
21
|
|
|
26
|
-
def self.handle_response(oat, response)
|
|
22
|
+
def self.handle_response(oat, response)
|
|
27
23
|
begin
|
|
28
24
|
response&.success? ? 'OK' : 'ERROR'
|
|
29
25
|
rescue StandardError => e
|
|
@@ -56,10 +52,32 @@ module Labimotion
|
|
|
56
52
|
Labimotion.log_exception(e)
|
|
57
53
|
error!('Cannot connect to Chemotion Repository', 401)
|
|
58
54
|
end
|
|
55
|
+
|
|
56
|
+
def self.send_to_central_hub(klass, template, metadata, origin)
|
|
57
|
+
body = {
|
|
58
|
+
template_klass: klass,
|
|
59
|
+
template: template,
|
|
60
|
+
metadata: metadata,
|
|
61
|
+
origin: origin
|
|
62
|
+
}
|
|
63
|
+
response = HTTParty.post(
|
|
64
|
+
Labimotion::TemplateHub.uri('template_submissions'),
|
|
65
|
+
headers: {
|
|
66
|
+
'Content-Type' => 'application/json',
|
|
67
|
+
'X-Origin-URL' => origin
|
|
68
|
+
},
|
|
69
|
+
body: body.to_json,
|
|
70
|
+
timeout: 10
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
if [200, 201].include?(response.code)
|
|
74
|
+
parsed_response = JSON.parse(response.body)
|
|
75
|
+
return { mc: 'ss00', data: { id: parsed_response['id'] } }
|
|
76
|
+
end
|
|
77
|
+
{ mc: 'se00', msg: "HTTP #{response.code}: #{response.message}", data: {} }
|
|
78
|
+
rescue StandardError => e
|
|
79
|
+
Labimotion.log_exception(e)
|
|
80
|
+
{ mc: 'se00', msg: "Connection failure: #{e.message}", data: {} }
|
|
81
|
+
end
|
|
59
82
|
end
|
|
60
83
|
end
|
|
61
|
-
|
|
62
|
-
# rubocop: enable Metrics/AbcSize
|
|
63
|
-
# rubocop: enable Metrics/MethodLength
|
|
64
|
-
# rubocop: enable Metrics/ClassLength
|
|
65
|
-
# rubocop: enable Metrics/CyclomaticComplexity
|
|
@@ -29,29 +29,33 @@ module Labimotion
|
|
|
29
29
|
properties: ods.properties,
|
|
30
30
|
properties_release: ods.properties_release,
|
|
31
31
|
klass_uuid: ods.klass_uuid,
|
|
32
|
+
metadata: ods.metadata || {}
|
|
32
33
|
)
|
|
33
34
|
end
|
|
34
35
|
|
|
35
|
-
def save_dataset(**
|
|
36
|
+
def save_dataset(**dataset_args)
|
|
36
37
|
return if not_dataset?
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
args = dataset_args[:dataset]
|
|
40
|
+
dataset_klass_id = args[:dataset_klass_id]
|
|
41
|
+
klass = Labimotion::DatasetKlass.find_by(id: dataset_klass_id)
|
|
39
42
|
uuid = SecureRandom.uuid
|
|
43
|
+
metadata = args[:metadata] || {}
|
|
40
44
|
props = args[:properties]
|
|
41
45
|
props['pkg'] = Labimotion::Utils.pkg(props['pkg'])
|
|
42
46
|
props['identifier'] = klass.identifier if klass.identifier.present?
|
|
43
47
|
props['uuid'] = uuid
|
|
44
48
|
props['klass'] = 'Dataset'
|
|
45
49
|
props['klass_uuid'] = klass.uuid
|
|
46
|
-
props = Labimotion::VocabularyHandler.update_vocabularies(props,
|
|
50
|
+
props = Labimotion::VocabularyHandler.update_vocabularies(props, dataset_args[:current_user], dataset_args[:element])
|
|
47
51
|
|
|
48
52
|
ds = Labimotion::Dataset.find_by(element_type: self.class.name, element_id: id)
|
|
49
|
-
if ds.present? && (ds.klass_uuid != klass.uuid || ds.properties != props)
|
|
50
|
-
ds.update!(properties_release: klass.properties_release, uuid: uuid, dataset_klass_id:
|
|
53
|
+
if ds.present? && (ds.klass_uuid != klass.uuid || ds.properties != props || ds.metadata != metadata)
|
|
54
|
+
ds.update!(properties_release: klass.properties_release, uuid: uuid, dataset_klass_id: dataset_klass_id, properties: props, klass_uuid: klass.uuid, metadata: metadata)
|
|
51
55
|
end
|
|
52
56
|
return if ds.present?
|
|
53
57
|
|
|
54
|
-
Labimotion::Dataset.create!(properties_release: klass.properties_release, uuid: uuid, dataset_klass_id:
|
|
58
|
+
Labimotion::Dataset.create!(properties_release: klass.properties_release, uuid: uuid, dataset_klass_id: dataset_klass_id, element_type: self.class.name, element_id: id, properties: props, klass_uuid: klass.uuid, metadata: metadata)
|
|
55
59
|
end
|
|
56
60
|
|
|
57
61
|
def destroy_datasetable
|
|
@@ -9,7 +9,6 @@ module Labimotion
|
|
|
9
9
|
before_save :check_identifier
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
|
|
13
12
|
def check_identifier
|
|
14
13
|
self.identifier = identifier || SecureRandom.uuid if self.has_attribute?(:identifier)
|
|
15
14
|
end
|
|
@@ -34,7 +33,7 @@ module Labimotion
|
|
|
34
33
|
properties_release: properties_release,
|
|
35
34
|
released_at: DateTime.now,
|
|
36
35
|
updated_by: current_user&.id,
|
|
37
|
-
released_by: current_user&.id
|
|
36
|
+
released_by: current_user&.id
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
self.update!(klass_attributes)
|
|
@@ -45,7 +44,8 @@ module Labimotion
|
|
|
45
44
|
version: version,
|
|
46
45
|
created_by: updated_by,
|
|
47
46
|
properties_release: properties_release,
|
|
48
|
-
released_at: released_at
|
|
47
|
+
released_at: released_at,
|
|
48
|
+
metadata: metadata || {}
|
|
49
49
|
}
|
|
50
50
|
attributes["#{self.class.name.underscore.split('/').last}_id"] = id
|
|
51
51
|
"#{self.class.name}esRevision".constantize.create(attributes)
|
|
@@ -22,7 +22,8 @@ module Labimotion
|
|
|
22
22
|
klass_uuid: klass_uuid,
|
|
23
23
|
properties: properties,
|
|
24
24
|
## created_by: user_for_revision&.id,
|
|
25
|
-
properties_release: properties_release
|
|
25
|
+
properties_release: properties_release,
|
|
26
|
+
metadata: metadata
|
|
26
27
|
}
|
|
27
28
|
attributes["#{Labimotion::Utils.element_name_dc(self.class.name)}_id"] = id
|
|
28
29
|
attributes['name'] = name if self.class.name == 'Labimotion::Element'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Labimotion
|
|
4
|
+
# Shared concern for all Klass Revision models
|
|
5
|
+
# Provides a unified interface to access the parent klass object
|
|
6
|
+
module KlassRevision
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
# Returns the associated klass object (ElementKlass, SegmentKlass, or DatasetKlass)
|
|
10
|
+
def klass
|
|
11
|
+
return element_klass if respond_to?(:element_klass)
|
|
12
|
+
return segment_klass if respond_to?(:segment_klass)
|
|
13
|
+
return dataset_klass if respond_to?(:dataset_klass)
|
|
14
|
+
|
|
15
|
+
nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Increments the submitted counter and saves the record
|
|
19
|
+
def increment_submitted!
|
|
20
|
+
increment!(:submitted)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Labimotion
|
|
4
|
+
## Metadata Validation Concern
|
|
5
|
+
module MetadataValidation
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
validate :metadata_must_be_hash
|
|
10
|
+
|
|
11
|
+
# Provide default value for metadata to support migrations
|
|
12
|
+
# when the column might not exist yet
|
|
13
|
+
after_initialize :set_metadata_default
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def set_metadata_default
|
|
19
|
+
self.metadata ||= {} if has_attribute?(:metadata)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def metadata_must_be_hash
|
|
23
|
+
# Skip validation if the metadata column doesn't exist yet (during migrations)
|
|
24
|
+
return unless has_attribute?(:metadata)
|
|
25
|
+
|
|
26
|
+
# Set default if nil
|
|
27
|
+
self.metadata ||= {}
|
|
28
|
+
|
|
29
|
+
return if metadata.is_a?(Hash)
|
|
30
|
+
|
|
31
|
+
errors.add(:metadata, 'must be a hash/object, not an array or other type')
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -68,14 +68,14 @@ module Labimotion
|
|
|
68
68
|
# props = Labimotion::VocabularyHandler.update_vocabularies(props, current_user, self)
|
|
69
69
|
segment = Labimotion::Segment.where(element_type: self.class.name, element_id: self.id, segment_klass_id: seg['segment_klass_id']).order(id: :desc).first
|
|
70
70
|
if segment.present? && (segment.klass_uuid != props['klass_uuid'] || segment.properties != props)
|
|
71
|
-
segment.update!(properties_release: klass.properties_release, properties: props, uuid: uuid, klass_uuid: props['klass_uuid'])
|
|
71
|
+
segment.update!(properties_release: klass.properties_release, properties: props, uuid: uuid, klass_uuid: props['klass_uuid'], metadata: seg['metadata'] || {})
|
|
72
72
|
# segments.push(segment)
|
|
73
73
|
Labimotion::Segment.where(element_type: self.class.name, element_id: self.id, segment_klass_id: seg['segment_klass_id']).where.not(id: segment.id).destroy_all
|
|
74
74
|
end
|
|
75
75
|
next if segment.present?
|
|
76
76
|
|
|
77
77
|
props['klass_uuid'] = klass.uuid
|
|
78
|
-
segment = Labimotion::Segment.create!(properties_release: klass.properties_release, segment_klass_id: seg['segment_klass_id'], element_type: self.class.name, element_id: self.id, properties: props, created_by: args[:current_user_id], uuid: uuid, klass_uuid: klass.uuid)
|
|
78
|
+
segment = Labimotion::Segment.create!(properties_release: klass.properties_release, segment_klass_id: seg['segment_klass_id'], element_type: self.class.name, element_id: self.id, properties: props, created_by: args[:current_user_id], uuid: uuid, klass_uuid: klass.uuid, metadata: seg['metadata'] || {})
|
|
79
79
|
# segments.push(segment)
|
|
80
80
|
end
|
|
81
81
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'labimotion/models/concerns/generic_klass_revisions'
|
|
4
4
|
require 'labimotion/models/concerns/generic_klass'
|
|
5
|
+
require 'labimotion/models/concerns/metadata_validation'
|
|
5
6
|
|
|
6
7
|
module Labimotion
|
|
7
8
|
class DatasetKlass < ApplicationRecord
|
|
@@ -9,6 +10,7 @@ module Labimotion
|
|
|
9
10
|
self.table_name = :dataset_klasses
|
|
10
11
|
include GenericKlassRevisions
|
|
11
12
|
include GenericKlass
|
|
13
|
+
include MetadataValidation
|
|
12
14
|
|
|
13
15
|
has_many :datasets, dependent: :destroy, class_name: 'Labimotion::Dataset'
|
|
14
16
|
has_many :dataset_klasses_revisions, dependent: :destroy, class_name: 'Labimotion::DatasetKlassesRevision'
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'labimotion/models/concerns/klass_revision'
|
|
4
|
+
require 'labimotion/models/concerns/metadata_validation'
|
|
5
|
+
|
|
3
6
|
module Labimotion
|
|
4
7
|
class DatasetKlassesRevision < ApplicationRecord
|
|
5
8
|
self.table_name = :dataset_klasses_revisions
|
|
6
9
|
acts_as_paranoid
|
|
7
|
-
|
|
10
|
+
include KlassRevision
|
|
11
|
+
include MetadataValidation
|
|
12
|
+
belongs_to :dataset_klass, class_name: 'Labimotion::DatasetKlass'
|
|
8
13
|
end
|
|
9
14
|
end
|
|
@@ -4,6 +4,7 @@ require 'labimotion/conf'
|
|
|
4
4
|
require 'labimotion/models/concerns/generic_klass_revisions'
|
|
5
5
|
require 'labimotion/models/concerns/generic_klass'
|
|
6
6
|
require 'labimotion/models/concerns/workflow'
|
|
7
|
+
require 'labimotion/models/concerns/metadata_validation'
|
|
7
8
|
|
|
8
9
|
module Labimotion
|
|
9
10
|
class ElementKlass < ApplicationRecord
|
|
@@ -12,6 +13,7 @@ module Labimotion
|
|
|
12
13
|
include GenericKlassRevisions
|
|
13
14
|
include GenericKlass
|
|
14
15
|
include Workflow
|
|
16
|
+
include MetadataValidation
|
|
15
17
|
has_many :elements, dependent: :destroy, class_name: 'Labimotion::Element'
|
|
16
18
|
has_many :segment_klasses, dependent: :destroy, class_name: 'Labimotion::SegmentKlass'
|
|
17
19
|
has_many :element_klasses_revisions, dependent: :destroy, class_name: 'Labimotion::ElementKlassesRevision'
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'labimotion/models/concerns/workflow'
|
|
4
|
+
require 'labimotion/models/concerns/klass_revision'
|
|
5
|
+
require 'labimotion/models/concerns/metadata_validation'
|
|
4
6
|
|
|
5
7
|
module Labimotion
|
|
6
8
|
class ElementKlassesRevision < ApplicationRecord
|
|
7
9
|
acts_as_paranoid
|
|
8
10
|
self.table_name = :element_klasses_revisions
|
|
9
11
|
include Workflow
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
include KlassRevision
|
|
13
|
+
include MetadataValidation
|
|
14
|
+
belongs_to :element_klass, class_name: 'Labimotion::ElementKlass'
|
|
12
15
|
|
|
13
16
|
def migrate_workflow
|
|
14
17
|
return if properties_release.nil? || properties_release['flow'].nil?
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'labimotion/models/concerns/generic_klass_revisions'
|
|
4
4
|
require 'labimotion/models/concerns/generic_klass'
|
|
5
5
|
require 'labimotion/models/concerns/workflow'
|
|
6
|
+
require 'labimotion/models/concerns/metadata_validation'
|
|
6
7
|
|
|
7
8
|
module Labimotion
|
|
8
9
|
class SegmentKlass < ApplicationRecord
|
|
@@ -11,6 +12,7 @@ module Labimotion
|
|
|
11
12
|
include GenericKlassRevisions
|
|
12
13
|
include GenericKlass
|
|
13
14
|
include Workflow
|
|
15
|
+
include MetadataValidation
|
|
14
16
|
belongs_to :element_klass, class_name: 'Labimotion::ElementKlass'
|
|
15
17
|
has_many :segments, dependent: :destroy, class_name: 'Labimotion::Segment'
|
|
16
18
|
has_many :segment_klasses_revisions, dependent: :destroy, class_name: 'Labimotion::SegmentKlassesRevision'
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'labimotion/models/concerns/klass_revision'
|
|
4
|
+
require 'labimotion/models/concerns/metadata_validation'
|
|
5
|
+
|
|
3
6
|
module Labimotion
|
|
4
7
|
class SegmentKlassesRevision < ApplicationRecord
|
|
5
8
|
acts_as_paranoid
|
|
6
9
|
self.table_name = :segment_klasses_revisions
|
|
7
|
-
|
|
10
|
+
include KlassRevision
|
|
11
|
+
include MetadataValidation
|
|
12
|
+
belongs_to :segment_klass, class_name: 'Labimotion::SegmentKlass'
|
|
8
13
|
end
|
|
9
14
|
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# == Schema Information
|
|
4
|
+
#
|
|
5
|
+
# Table name: template_submissions
|
|
6
|
+
#
|
|
7
|
+
# id :bigint not null, primary key
|
|
8
|
+
# template_klass :string not null
|
|
9
|
+
# template :jsonb not null, default: {}
|
|
10
|
+
# metadata :jsonb not null, default: {}
|
|
11
|
+
# origin :string not null
|
|
12
|
+
# state :integer not null, default: 0
|
|
13
|
+
# created_at :datetime not null
|
|
14
|
+
# updated_at :datetime
|
|
15
|
+
# deleted_at :datetime
|
|
16
|
+
#
|
|
17
|
+
# Indexes
|
|
18
|
+
#
|
|
19
|
+
# idx_template_submissions_template (template) USING gin
|
|
20
|
+
# idx_template_submissions_metadata (metadata) USING gin
|
|
21
|
+
#
|
|
22
|
+
|
|
23
|
+
module Labimotion
|
|
24
|
+
class TemplateSubmission < ApplicationRecord
|
|
25
|
+
acts_as_paranoid
|
|
26
|
+
|
|
27
|
+
# State enum
|
|
28
|
+
enum state: {
|
|
29
|
+
pending: 0,
|
|
30
|
+
approved: 1,
|
|
31
|
+
rejected: 2,
|
|
32
|
+
released: 3
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Validations
|
|
36
|
+
validates :template_klass, presence: true
|
|
37
|
+
validates :template, presence: true
|
|
38
|
+
validates :metadata, presence: true
|
|
39
|
+
validates :origin, presence: true
|
|
40
|
+
|
|
41
|
+
# Scopes
|
|
42
|
+
scope :by_template_klass, ->(klass) { where(template_klass: klass) }
|
|
43
|
+
scope :by_state, ->(state) { where(state: state) }
|
|
44
|
+
scope :by_origin, ->(origin) { where(origin: origin) }
|
|
45
|
+
scope :by_email, ->(email) { where("metadata->'submission'->>'email' = ?", email) }
|
|
46
|
+
scope :by_contact_email, ->(email) { where("metadata->'submission'->>'contact_email' = ?", email) }
|
|
47
|
+
scope :by_any_email, lambda { |email|
|
|
48
|
+
where("metadata->'submission'->>'email' = ? OR metadata->'submission'->>'contact_email' = ?", email, email)
|
|
49
|
+
}
|
|
50
|
+
scope :recent, -> { order(created_at: :desc) }
|
|
51
|
+
end
|
|
52
|
+
end
|
data/lib/labimotion/version.rb
CHANGED
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.rc15
|
|
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:
|
|
12
|
+
date: 2026-01-14 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: caxlsx
|
|
@@ -120,7 +120,9 @@ files:
|
|
|
120
120
|
- lib/labimotion/models/concerns/generic_klass.rb
|
|
121
121
|
- lib/labimotion/models/concerns/generic_klass_revisions.rb
|
|
122
122
|
- lib/labimotion/models/concerns/generic_revisions.rb
|
|
123
|
+
- lib/labimotion/models/concerns/klass_revision.rb
|
|
123
124
|
- lib/labimotion/models/concerns/linked_properties.rb
|
|
125
|
+
- lib/labimotion/models/concerns/metadata_validation.rb
|
|
124
126
|
- lib/labimotion/models/concerns/segmentable.rb
|
|
125
127
|
- lib/labimotion/models/concerns/workflow.rb
|
|
126
128
|
- lib/labimotion/models/dataset.rb
|
|
@@ -145,6 +147,7 @@ files:
|
|
|
145
147
|
- lib/labimotion/models/segments_revision.rb
|
|
146
148
|
- lib/labimotion/models/std_layer.rb
|
|
147
149
|
- lib/labimotion/models/std_layers_revision.rb
|
|
150
|
+
- lib/labimotion/models/template_submission.rb
|
|
148
151
|
- lib/labimotion/models/vocabulary.rb
|
|
149
152
|
- lib/labimotion/models/wellplate.rb
|
|
150
153
|
- lib/labimotion/utils/con_state.rb
|