labimotion 2.2.0.rc10 → 2.2.0.rc12
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 +1 -0
- data/lib/labimotion/apis/labimotion_api.rb +2 -0
- data/lib/labimotion/apis/labimotion_doi_api.rb +170 -0
- data/lib/labimotion/apis/labimotion_template_browse_api.rb +120 -0
- data/lib/labimotion/entities/labimotion_template_doi_entity.rb +30 -0
- data/lib/labimotion/helpers/element_helpers.rb +21 -15
- data/lib/labimotion/models/concerns/element_fetchable.rb +2 -2
- data/lib/labimotion/models/element.rb +2 -2
- data/lib/labimotion/utils/search.rb +2 -2
- data/lib/labimotion/version.rb +1 -1
- data/lib/labimotion.rb +3 -0
- 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: 407197c03e88402882b081d31dc92999629ec43c25b8c056c6f6ba3ca40135fc
|
|
4
|
+
data.tar.gz: d331368ce985ae7ff32a98f0747e9b06233eb5ac3b9b1a0c17e76a3ecbeeab7a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 275089d4170573e9961387dfe2274e9c5c8d1f9ccfe02b854aec3b1a5bfb237f5535915fd73205fc1efa564102ef33605a4f5de148fec8244b76ee2ca9fa5b48
|
|
7
|
+
data.tar.gz: 75b3433050aab3b9a76c9442643b0c5dcb87b508672d4b3b1c57b8ca52bbb75e1045cf429c25c4cfa64616df2482baa15062ccc45f515173012f31ca6cbcacef
|
|
@@ -432,6 +432,7 @@ module Labimotion
|
|
|
432
432
|
desc 'Return serialized elements of current user'
|
|
433
433
|
params do
|
|
434
434
|
optional :collection_id, type: Integer, desc: 'Collection id'
|
|
435
|
+
optional :sync_collection_id, type: Integer, desc: 'SyncCollectionsUser id'
|
|
435
436
|
optional :el_type, type: String, desc: 'element klass name'
|
|
436
437
|
optional :from_date, type: Integer, desc: 'created_date from in ms'
|
|
437
438
|
optional :to_date, type: Integer, desc: 'created_date to in ms'
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Labimotion
|
|
4
|
+
# DOI lifecycle (reserve + release) and publication metadata for
|
|
5
|
+
# LabIMotion templates: ElementKlass / SegmentKlass / DatasetKlass.
|
|
6
|
+
class LabimotionDoiAPI < Grape::API
|
|
7
|
+
# rubocop:disable Metrics/BlockLength
|
|
8
|
+
# Grape route and helper DSL blocks are necessarily large.
|
|
9
|
+
KLASS_TYPES = ::Usecases::Labimotion::TemplateDoiHelpers::KLASS_BY_TYPE.keys.freeze
|
|
10
|
+
|
|
11
|
+
helpers do
|
|
12
|
+
def resolve_klass!(type, id)
|
|
13
|
+
model = ::Usecases::Labimotion::TemplateDoiHelpers::KLASS_BY_TYPE[type]
|
|
14
|
+
error!('unknown template type', 404) unless model
|
|
15
|
+
|
|
16
|
+
record = model.find_by(id: id)
|
|
17
|
+
error!('template not found', 404) unless record
|
|
18
|
+
|
|
19
|
+
record
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def render_template_doi(record)
|
|
23
|
+
type = ::Usecases::Labimotion::TemplateDoiHelpers.klass_type_for(record)
|
|
24
|
+
dois = ::Doi.labimotion_dois(record)
|
|
25
|
+
# `doi` is the current (most recently reserved) DOI; `released_doi` is the
|
|
26
|
+
# latest released (minted) one. They differ once a new version has been
|
|
27
|
+
# reserved on top of a released one, so the modal can show both at once.
|
|
28
|
+
doi = dois.last
|
|
29
|
+
released_doi = dois.reverse.find(&:minted)
|
|
30
|
+
Labimotion::LabimotionTemplateDoiEntity.represent(
|
|
31
|
+
type: type,
|
|
32
|
+
klass_id: record.id,
|
|
33
|
+
doi: doi,
|
|
34
|
+
released_doi_version: released_doi && ::Doi.labimotion_doi_version(released_doi),
|
|
35
|
+
publication: (record.properties_template || {})['publication'],
|
|
36
|
+
released_at: record.released_at,
|
|
37
|
+
released_by: record.released_by,
|
|
38
|
+
new_version_available: ::Usecases::Labimotion::TemplateDoiHelpers.new_version_available?(record),
|
|
39
|
+
next_doi_version: ::Doi.labimotion_version_segment(record),
|
|
40
|
+
template_url: ::Usecases::Labimotion::TemplateDoiHelpers.template_url(record)
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Public, read-only view of one released DOI version.
|
|
45
|
+
def released_doi_version(doi)
|
|
46
|
+
full = doi.full_doi
|
|
47
|
+
{
|
|
48
|
+
doi: full,
|
|
49
|
+
doi_url: "https://dx.doi.org/#{full}",
|
|
50
|
+
version: ::Doi.labimotion_doi_version(doi),
|
|
51
|
+
minted_at: doi.minted_at
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Public payload for a template that has at least one released DOI: the
|
|
56
|
+
# latest released DOI promoted to the top level, plus its publication
|
|
57
|
+
# metadata, hub deep-link and every released version. `record_id` matches
|
|
58
|
+
# the hub grid's row id (identifier || uuid) so the frontend can merge it.
|
|
59
|
+
def released_template_doi(record, dois)
|
|
60
|
+
versions = dois.sort_by(&:id).map { |doi| released_doi_version(doi) }
|
|
61
|
+
publication = (record.properties_template || {})['publication']
|
|
62
|
+
publication = publication.is_a?(Hash) ? publication.slice('title', 'description', 'authors', 'license') : {}
|
|
63
|
+
versions.last.merge(
|
|
64
|
+
record_id: record.try(:identifier).presence || record.try(:uuid).presence || record.id,
|
|
65
|
+
identifier: record.try(:identifier),
|
|
66
|
+
uuid: record.try(:uuid),
|
|
67
|
+
label: record.try(:label),
|
|
68
|
+
template_version: record.try(:version),
|
|
69
|
+
next_doi_version: ::Doi.labimotion_version_segment(record),
|
|
70
|
+
template_url: ::Usecases::Labimotion::TemplateDoiHelpers.template_url(record),
|
|
71
|
+
publication: publication,
|
|
72
|
+
versions: versions
|
|
73
|
+
)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
namespace :labimotion_doi do
|
|
78
|
+
# Public, anonymous read-only DOI info for the LabIMotion Template Hub.
|
|
79
|
+
# Whitelisted in RepoAPI::PUBLIC_URLS so it bypasses authenticate!; only
|
|
80
|
+
# released (minted) DOIs and their public publication metadata are exposed.
|
|
81
|
+
namespace :public do
|
|
82
|
+
route_param :type, type: String, values: KLASS_TYPES do
|
|
83
|
+
desc 'Released DOIs + publication metadata for every released template of a type'
|
|
84
|
+
get :released do
|
|
85
|
+
model = ::Usecases::Labimotion::TemplateDoiHelpers::KLASS_BY_TYPE[params[:type]]
|
|
86
|
+
grouped = ::Doi.where(doiable_type: model.name).where.not(minted_at: nil)
|
|
87
|
+
.order(:id).group_by(&:doiable_id)
|
|
88
|
+
records = model.where(id: grouped.keys).index_by(&:id)
|
|
89
|
+
released = grouped.filter_map do |klass_id, dois|
|
|
90
|
+
record = records[klass_id]
|
|
91
|
+
record && released_template_doi(record, dois)
|
|
92
|
+
end
|
|
93
|
+
{ released_dois: released }
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
route_param :type, type: String, values: KLASS_TYPES do
|
|
99
|
+
desc "DOI state (reserved / released) per template of a type, for the designer grid's DOI icon"
|
|
100
|
+
get :states do
|
|
101
|
+
model = ::Usecases::Labimotion::TemplateDoiHelpers::KLASS_BY_TYPE[params[:type]]
|
|
102
|
+
grouped = ::Doi.where(doiable_type: model.name).order(:id).group_by(&:doiable_id)
|
|
103
|
+
states = grouped.transform_values do |list|
|
|
104
|
+
released = list.last.minted == true
|
|
105
|
+
{ reserved: !released, released: released }
|
|
106
|
+
end
|
|
107
|
+
{ states: states }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
route_param :id, type: Integer do
|
|
111
|
+
desc 'Returns the current DOI/publication state for a template'
|
|
112
|
+
get do
|
|
113
|
+
record = resolve_klass!(params[:type], params[:id])
|
|
114
|
+
render_template_doi(record)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
desc "Returns the DataCite metadata XML for every one of the template's DOI versions"
|
|
118
|
+
get :metadata_xml do
|
|
119
|
+
record = resolve_klass!(params[:type], params[:id])
|
|
120
|
+
dois = ::Doi.labimotion_dois(record)
|
|
121
|
+
error!('no DOI reserved', 404) if dois.empty?
|
|
122
|
+
|
|
123
|
+
versions = dois.map do |doi|
|
|
124
|
+
{
|
|
125
|
+
version: ::Doi.labimotion_doi_version(doi),
|
|
126
|
+
full_doi: doi.full_doi,
|
|
127
|
+
minted: doi.minted == true,
|
|
128
|
+
xml: ::Usecases::Labimotion::BuildTemplateDoiXml.new(record, doi, current_user).call
|
|
129
|
+
}
|
|
130
|
+
end
|
|
131
|
+
{ versions: versions }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
desc 'Updates the publication metadata of a template'
|
|
135
|
+
params do
|
|
136
|
+
requires :publication, type: Hash
|
|
137
|
+
end
|
|
138
|
+
put :publication_metadata do
|
|
139
|
+
record = resolve_klass!(params[:type], params[:id])
|
|
140
|
+
uc = ::Usecases::Labimotion::UpdateTemplatePublicationMetadata.new(
|
|
141
|
+
record, current_user, params[:publication]
|
|
142
|
+
).call
|
|
143
|
+
error!(uc.error, 422) unless uc.success?
|
|
144
|
+
|
|
145
|
+
render_template_doi(record.reload)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
desc 'Reserves a DataCite DOI for a template'
|
|
149
|
+
post :reserve_doi do
|
|
150
|
+
record = resolve_klass!(params[:type], params[:id])
|
|
151
|
+
uc = ::Usecases::Labimotion::ReserveTemplateDoi.new(record, current_user).call
|
|
152
|
+
error!(uc.error, 422) unless uc.success?
|
|
153
|
+
|
|
154
|
+
render_template_doi(record.reload)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
desc 'Releases (mints) the reserved DOI for a template'
|
|
158
|
+
post :release_doi do
|
|
159
|
+
record = resolve_klass!(params[:type], params[:id])
|
|
160
|
+
uc = ::Usecases::Labimotion::ReleaseTemplateDoi.new(record, current_user).call
|
|
161
|
+
error!(uc.error, 422) unless uc.success?
|
|
162
|
+
|
|
163
|
+
render_template_doi(record.reload)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
# rubocop:enable Metrics/BlockLength
|
|
169
|
+
end
|
|
170
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Labimotion
|
|
4
|
+
# Public, read-only browsing of released LabIMotion templates for the Template
|
|
5
|
+
# Hub "Find a Template" tab: pick a type, a template, then a release version.
|
|
6
|
+
# Returns every released version (revision) of one template, each with its own
|
|
7
|
+
# properties_release so the frontend can render the example inline.
|
|
8
|
+
# Whitelisted in RepoAPI::PUBLIC_URLS so anonymous hub visitors can use it.
|
|
9
|
+
class LabimotionTemplateBrowseAPI < Grape::API
|
|
10
|
+
KLASS_BY_TYPE = ::Usecases::Labimotion::TemplateDoiHelpers::KLASS_BY_TYPE
|
|
11
|
+
KLASS_TYPES = KLASS_BY_TYPE.keys.freeze
|
|
12
|
+
# type => [revision model, foreign key to the klass]
|
|
13
|
+
REVISION_BY_TYPE = {
|
|
14
|
+
'element' => [::Labimotion::ElementKlassesRevision, :element_klass_id],
|
|
15
|
+
'segment' => [::Labimotion::SegmentKlassesRevision, :segment_klass_id],
|
|
16
|
+
'dataset' => [::Labimotion::DatasetKlassesRevision, :dataset_klass_id]
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
# rubocop:disable Metrics/BlockLength
|
|
20
|
+
# The helpers block is large due to the many template/version/DOI shaping helpers.
|
|
21
|
+
helpers do
|
|
22
|
+
def find_template(model, identifier)
|
|
23
|
+
model.find_by(identifier: identifier) || model.find_by(uuid: identifier)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Numeric sort key for a "major.minor" version string.
|
|
27
|
+
def version_sort_key(version)
|
|
28
|
+
version.to_s.split('.').map(&:to_i)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def template_summary(record, type)
|
|
32
|
+
element_klass = record.try(:element_klass)
|
|
33
|
+
{
|
|
34
|
+
type: type,
|
|
35
|
+
identifier: record.try(:identifier),
|
|
36
|
+
uuid: record.try(:uuid),
|
|
37
|
+
name: record.try(:name),
|
|
38
|
+
label: record.try(:label),
|
|
39
|
+
desc: record.try(:desc),
|
|
40
|
+
klass_prefix: record.try(:klass_prefix),
|
|
41
|
+
icon_name: record.try(:icon_name),
|
|
42
|
+
current_version: record.try(:version),
|
|
43
|
+
element_klass: element_klass && { label: element_klass.label, icon_name: element_klass.icon_name }
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def version_entry(version, released_at, uuid, properties_release)
|
|
48
|
+
{ version: version, released_at: released_at, uuid: uuid, properties_release: properties_release }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# The current klass's released version is appended only when no revision
|
|
52
|
+
# already captures it, so the latest is always selectable.
|
|
53
|
+
def append_current?(record, versions)
|
|
54
|
+
record.try(:released_at).present? && versions.none? { |v| v[:version] == record.try(:version) }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Drops blank-version entries and orders newest-first.
|
|
58
|
+
def sort_versions(versions)
|
|
59
|
+
versions.reject { |v| v[:version].to_s.strip.empty? }
|
|
60
|
+
.sort_by { |v| version_sort_key(v[:version]) }.reverse
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# All released versions of a template, newest first. Built from the
|
|
64
|
+
# revision snapshots, plus the current klass (see append_current?).
|
|
65
|
+
def released_versions(record, type)
|
|
66
|
+
rev_model, foreign_key = REVISION_BY_TYPE[type]
|
|
67
|
+
scope = rev_model.where(foreign_key => record.id).where.not(released_at: nil)
|
|
68
|
+
versions = scope.map { |rev| version_entry(rev.version, rev.released_at, rev.uuid, rev.properties_release) }
|
|
69
|
+
if append_current?(record, versions)
|
|
70
|
+
versions << version_entry(record.try(:version), record.released_at,
|
|
71
|
+
record.try(:uuid), record.try(:properties_release))
|
|
72
|
+
end
|
|
73
|
+
sort_versions(versions)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# The template's DOI publication metadata (shown alongside the DOI).
|
|
77
|
+
def template_publication(record)
|
|
78
|
+
pub = (record.properties_template || {})['publication']
|
|
79
|
+
pub.is_a?(Hash) ? pub.slice('title', 'description', 'authors', 'license') : {}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Released (minted) DOIs of the template, each tagged with its DOI version
|
|
83
|
+
# and its DataCite (kernel-4) metadata XML (the downloadable DOI metadata).
|
|
84
|
+
# The frontend maps a chosen template version to the applicable DOI version
|
|
85
|
+
# and shows/downloads the matching entry.
|
|
86
|
+
def released_dois(record)
|
|
87
|
+
::Doi.labimotion_dois(record).select(&:minted).map do |doi|
|
|
88
|
+
full = doi.full_doi
|
|
89
|
+
{ version: ::Doi.labimotion_doi_version(doi), doi: full,
|
|
90
|
+
doi_url: "https://dx.doi.org/#{full}", minted_at: doi.minted_at,
|
|
91
|
+
xml: ::Usecases::Labimotion::BuildTemplateDoiXml.new(record, doi).call }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
# rubocop:enable Metrics/BlockLength
|
|
96
|
+
|
|
97
|
+
namespace :labimotion_template_browse do
|
|
98
|
+
route_param :type, type: String, values: KLASS_TYPES do
|
|
99
|
+
desc 'Released versions (revisions) of one template, each with properties_release'
|
|
100
|
+
params do
|
|
101
|
+
requires :identifier, type: String, desc: 'template identifier or uuid'
|
|
102
|
+
end
|
|
103
|
+
get :versions do
|
|
104
|
+
model = KLASS_BY_TYPE[params[:type]]
|
|
105
|
+
error!('unknown template type', 404) unless model
|
|
106
|
+
|
|
107
|
+
record = find_template(model, params[:identifier])
|
|
108
|
+
error!('template not found', 404) unless record
|
|
109
|
+
|
|
110
|
+
{
|
|
111
|
+
template: template_summary(record, params[:type]),
|
|
112
|
+
versions: released_versions(record, params[:type]),
|
|
113
|
+
dois: released_dois(record),
|
|
114
|
+
publication: template_publication(record)
|
|
115
|
+
}
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Labimotion
|
|
4
|
+
# Serializes the DOI + publication state for a LabIMotion template
|
|
5
|
+
# (ElementKlass / SegmentKlass / DatasetKlass). Built ad-hoc by
|
|
6
|
+
# Labimotion::LabimotionDoiAPI; not a direct AR record entity.
|
|
7
|
+
class LabimotionTemplateDoiEntity < Grape::Entity
|
|
8
|
+
expose :type
|
|
9
|
+
expose :klass_id
|
|
10
|
+
expose :doi do |obj|
|
|
11
|
+
next nil unless obj[:doi]
|
|
12
|
+
|
|
13
|
+
{
|
|
14
|
+
id: obj[:doi].id,
|
|
15
|
+
suffix: obj[:doi].suffix,
|
|
16
|
+
full_doi: obj[:doi].full_doi,
|
|
17
|
+
version: ::Doi.labimotion_doi_version(obj[:doi]),
|
|
18
|
+
minted: obj[:doi].minted == true,
|
|
19
|
+
minted_at: obj[:doi].minted_at
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
expose :released_doi_version
|
|
23
|
+
expose :publication
|
|
24
|
+
expose :released_at
|
|
25
|
+
expose :released_by
|
|
26
|
+
expose :new_version_available
|
|
27
|
+
expose :next_doi_version
|
|
28
|
+
expose :template_url
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -215,7 +215,7 @@ module Labimotion
|
|
|
215
215
|
layer, field = params[:sort_column].split('.')
|
|
216
216
|
|
|
217
217
|
element_klass = Labimotion::ElementKlass.find_by(name: params[:el_type])
|
|
218
|
-
allowed_fields = element_klass
|
|
218
|
+
allowed_fields = element_klass.properties_release.dig(Labimotion::Prop::LAYERS, layer, Labimotion::Prop::FIELDS)&.pluck('field') || []
|
|
219
219
|
|
|
220
220
|
if field.in?(allowed_fields)
|
|
221
221
|
query = ActiveRecord::Base.sanitize_sql(
|
|
@@ -247,21 +247,27 @@ module Labimotion
|
|
|
247
247
|
end
|
|
248
248
|
|
|
249
249
|
def list_serialized_elements(params, current_user)
|
|
250
|
-
|
|
251
|
-
|
|
250
|
+
collection_id =
|
|
252
251
|
if params[:collection_id]
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
252
|
+
Collection
|
|
253
|
+
.belongs_to_or_shared_by(current_user.id, current_user.group_ids)
|
|
254
|
+
.find_by(id: params[:collection_id])&.id
|
|
255
|
+
elsif params[:sync_collection_id]
|
|
256
|
+
current_user
|
|
257
|
+
.all_sync_in_collections_users
|
|
258
|
+
.find_by(id: params[:sync_collection_id])&.collection&.id
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
scope =
|
|
262
|
+
if collection_id
|
|
263
|
+
Labimotion::Element
|
|
264
|
+
.joins(:element_klass, :collections_elements)
|
|
265
|
+
.where(
|
|
266
|
+
element_klasses: { name: params[:el_type] },
|
|
267
|
+
collections_elements: { collection_id: collection_id },
|
|
268
|
+
).includes(:tag, collections: :sync_collections_users)
|
|
262
269
|
else
|
|
263
|
-
|
|
264
|
-
scope = Labimotion::Element.for_user(current_user.id)
|
|
270
|
+
Labimotion::Element.none
|
|
265
271
|
end
|
|
266
272
|
|
|
267
273
|
## TO DO: refactor labimotion
|
|
@@ -272,7 +278,7 @@ module Labimotion
|
|
|
272
278
|
layer, field = params[:sort_column].split('.')
|
|
273
279
|
|
|
274
280
|
element_klass = Labimotion::ElementKlass.find_by(name: params[:el_type])
|
|
275
|
-
allowed_fields = element_klass
|
|
281
|
+
allowed_fields = element_klass.properties_release.dig(Labimotion::Prop::LAYERS, layer, Labimotion::Prop::FIELDS)&.pluck('field') || []
|
|
276
282
|
|
|
277
283
|
if field.in?(allowed_fields)
|
|
278
284
|
query = ActiveRecord::Base.sanitize_sql(
|
|
@@ -26,9 +26,9 @@ module Labimotion
|
|
|
26
26
|
joins(collections: :user).where(collections: { user_id: user_id })
|
|
27
27
|
)
|
|
28
28
|
|
|
29
|
-
# Shared records
|
|
29
|
+
# Shared (synced) records
|
|
30
30
|
shared = apply_filters.call(
|
|
31
|
-
|
|
31
|
+
joins(collections: :sync_collections_users).where(sync_collections_users: { user_id: user_id })
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
# Combine (remove duplicates), order, and limit
|
|
@@ -141,9 +141,9 @@ module Labimotion
|
|
|
141
141
|
joins(collections: :user).where(collections: { user_id: user_id })
|
|
142
142
|
)
|
|
143
143
|
|
|
144
|
-
# Shared elements
|
|
144
|
+
# Shared (synced) elements
|
|
145
145
|
shared = apply_filters.call(
|
|
146
|
-
|
|
146
|
+
joins(collections: :sync_collections_users).where(sync_collections_users: { user_id: user_id })
|
|
147
147
|
)
|
|
148
148
|
|
|
149
149
|
# Combine (remove duplicates), order, and limit
|
|
@@ -12,7 +12,7 @@ module Labimotion
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def self.elements_search(params, current_user, c_id, dl)
|
|
15
|
-
collection = Collection.
|
|
15
|
+
collection = Collection.belongs_to_or_shared_by(current_user.id, current_user.group_ids).find(c_id)
|
|
16
16
|
element_scope = Labimotion::Element.joins(:collections_elements).where('collections_elements.collection_id = ?', collection.id).joins(:element_klass).where('element_klasses.id = elements.element_klass_id AND element_klasses.name = ?', params[:selection][:genericElName])
|
|
17
17
|
element_scope = element_scope.where('elements.name like (?)', "%#{params[:selection][:searchName]}%") if params[:selection][:searchName].present?
|
|
18
18
|
element_scope = element_scope.where('elements.short_label like (?)', "%#{params[:selection][:searchShowLabel]}%") if params[:selection][:searchShowLabel].present?
|
|
@@ -97,7 +97,7 @@ module Labimotion
|
|
|
97
97
|
def self.samples_search(c_id = @c_id)
|
|
98
98
|
sqls = []
|
|
99
99
|
sps = params[:selection][:searchProperties]
|
|
100
|
-
collection = Collection.
|
|
100
|
+
collection = Collection.belongs_to_or_shared_by(current_user.id, current_user.group_ids).find(c_id)
|
|
101
101
|
element_scope = Sample.joins(:collections_samples).where('collections_samples.collection_id = ?', collection.id)
|
|
102
102
|
return element_scope if sps.empty?
|
|
103
103
|
|
data/lib/labimotion/version.rb
CHANGED
data/lib/labimotion.rb
CHANGED
|
@@ -31,6 +31,8 @@ module Labimotion
|
|
|
31
31
|
autoload :MttAPI, 'labimotion/apis/mtt_api'
|
|
32
32
|
autoload :DoseRespRequestAPI, 'labimotion/apis/dose_resp_request_api'
|
|
33
33
|
autoload :ElementVariationAPI, 'labimotion/apis/element_variation_api'
|
|
34
|
+
autoload :LabimotionDoiAPI, 'labimotion/apis/labimotion_doi_api'
|
|
35
|
+
autoload :LabimotionTemplateBrowseAPI, 'labimotion/apis/labimotion_template_browse_api'
|
|
34
36
|
|
|
35
37
|
######## Entities
|
|
36
38
|
autoload :PropertiesEntity, 'labimotion/entities/properties_entity'
|
|
@@ -55,6 +57,7 @@ module Labimotion
|
|
|
55
57
|
autoload :VocabularyEntity, 'labimotion/entities/vocabulary_entity'
|
|
56
58
|
autoload :UserEntity, 'labimotion/entities/user_entity'
|
|
57
59
|
autoload :ElementVariationEntity, 'labimotion/entities/element_variation_entity'
|
|
60
|
+
autoload :LabimotionTemplateDoiEntity, 'labimotion/entities/labimotion_template_doi_entity'
|
|
58
61
|
|
|
59
62
|
######## Helpers
|
|
60
63
|
autoload :GenericHelpers, 'labimotion/helpers/generic_helpers'
|
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.2.0.
|
|
4
|
+
version: 2.2.0.rc12
|
|
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: 2026-06-
|
|
12
|
+
date: 2026-06-22 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: caxlsx
|
|
@@ -65,7 +65,9 @@ files:
|
|
|
65
65
|
- lib/labimotion/apis/generic_element_api.rb
|
|
66
66
|
- lib/labimotion/apis/generic_klass_api.rb
|
|
67
67
|
- lib/labimotion/apis/labimotion_api.rb
|
|
68
|
+
- lib/labimotion/apis/labimotion_doi_api.rb
|
|
68
69
|
- lib/labimotion/apis/labimotion_hub_api.rb
|
|
70
|
+
- lib/labimotion/apis/labimotion_template_browse_api.rb
|
|
69
71
|
- lib/labimotion/apis/mtt_api.rb
|
|
70
72
|
- lib/labimotion/apis/segment_api.rb
|
|
71
73
|
- lib/labimotion/apis/standard_api.rb
|
|
@@ -88,6 +90,7 @@ files:
|
|
|
88
90
|
- lib/labimotion/entities/generic_klass_entity.rb
|
|
89
91
|
- lib/labimotion/entities/generic_public_entity.rb
|
|
90
92
|
- lib/labimotion/entities/klass_revision_entity.rb
|
|
93
|
+
- lib/labimotion/entities/labimotion_template_doi_entity.rb
|
|
91
94
|
- lib/labimotion/entities/properties_entity.rb
|
|
92
95
|
- lib/labimotion/entities/segment_entity.rb
|
|
93
96
|
- lib/labimotion/entities/segment_klass_entity.rb
|