diff --git a/app/assets/stylesheets/experiments.scss b/app/assets/stylesheets/experiments.scss index 17c3889e6..43bd32618 100644 --- a/app/assets/stylesheets/experiments.scss +++ b/app/assets/stylesheets/experiments.scss @@ -47,11 +47,14 @@ .cards-wrapper { --card-min-width: 350px; - --list-columns-number: 7; + --list-columns-number: 8; .card { - grid-row: span 6; + grid-row: span 7; + .experiment-code-cell { + display: none; + } &.experiment-card { border-radius: 4px; @@ -174,7 +177,7 @@ &.list { grid-auto-rows: 1px 5em; - grid-template-columns: max-content repeat(calc(var(--list-columns-number) - 2), minmax(100px, auto)) max-content; + grid-template-columns: max-content minmax(100px, auto) minmax(80px, max-content) repeat(calc(var(--list-columns-number) - 4), minmax(100px, auto)) max-content; grid-template-rows: 3em; .card { @@ -230,20 +233,25 @@ } } - .start-date-cell { + .experiment-code-cell { + display: block; grid-column: 3; } - .modified-date-cell { + .start-date-cell { grid-column: 4; } - .completed-task-cell { + .modified-date-cell { grid-column: 5; } - .description-cell { + .completed-task-cell { grid-column: 6; + } + + .description-cell { + grid-column: 7; position: relative; .description-text { @@ -262,7 +270,7 @@ } .actions-cell { - grid-column: 7; + grid-column: 8; padding-top: 3px; position: initial; } diff --git a/app/assets/stylesheets/shared_styles/elements/dropdown.scss b/app/assets/stylesheets/shared_styles/elements/dropdown.scss index c76aa898a..4be60fc47 100644 --- a/app/assets/stylesheets/shared_styles/elements/dropdown.scss +++ b/app/assets/stylesheets/shared_styles/elements/dropdown.scss @@ -40,17 +40,30 @@ } .dropdown-menu { + .form-dropdown-break hr { + margin-bottom: 8px; + margin-top: 0; + } + .form-dropdown-item { padding: 0 !important; - button { + button, + .form-dropdown-item-info { border-radius: 0; - color: $color-black !important; padding-left: .9em; text-align: left; width: 100%; } + button { + color: $color-black !important; + } + + .form-dropdown-item-info { + color: $color-silver-chalice !important; + } + .project-archive-restore-form { .button-to { &:hover { diff --git a/app/models/concerns/searchable_model.rb b/app/models/concerns/searchable_model.rb index f01c9e620..2502c2ce4 100644 --- a/app/models/concerns/searchable_model.rb +++ b/app/models/concerns/searchable_model.rb @@ -43,6 +43,8 @@ module SearchableModel (attrs.map.with_index do |a, i| if %w(repository_rows.id repository_number_values.data).include?(a) "((#{a})::text) #{like} :t#{i} OR " + elsif a == Experiment::EXPERIMENT_CODE_SQL + "#{Experiment::EXPERIMENT_CODE_SQL} #{like} :t#{i} OR " else col = options[:at_search].to_s == 'true' ? "lower(#{a})": a "(trim_html_tags(#{col})) #{like} :t#{i} OR " @@ -67,6 +69,8 @@ module SearchableModel (attrs.map.with_index do |a, i| if %w(repository_rows.id repository_number_values.data).include?(a) "((#{a})::text) #{like} ANY (array[:t#{i}]) OR " + elsif a == Experiment::EXPERIMENT_CODE_SQL + "#{Experiment::EXPERIMENT_CODE_SQL} #{like} ANY (array[:t#{i}]) OR " else "(trim_html_tags(#{a})) #{like} ANY (array[:t#{i}]) OR " end @@ -86,6 +90,8 @@ module SearchableModel (attrs.map.with_index do |a, i| if %w(repository_rows.id repository_number_values.data).include?(a) "((#{a})::text) #{like} :t#{i} OR " + elsif a == Experiment::EXPERIMENT_CODE_SQL + "#{Experiment::EXPERIMENT_CODE_SQL} #{like} :t#{i} OR " else "(trim_html_tags(#{a})) #{like} :t#{i} OR " end diff --git a/app/models/experiment.rb b/app/models/experiment.rb index 2f5a884b6..5ad42ff6e 100644 --- a/app/models/experiment.rb +++ b/app/models/experiment.rb @@ -3,6 +3,8 @@ class Experiment < ApplicationRecord include SearchableModel include SearchableByNameModel + EXPERIMENT_CODE_SQL = "('EX' || id)".freeze + before_save -> { report_elements.destroy_all }, if: -> { !new_record? && project_id_changed? } belongs_to :project, inverse_of: :experiments, touch: true @@ -70,19 +72,25 @@ class Experiment < ApplicationRecord new_query = Experiment .where('experiments.project_id IN (?)', projects_ids) - .where_attributes_like([:name, :description], query, options) + .where_attributes_like( + [:name, :description, EXPERIMENT_CODE_SQL], query, options + ) return include_archived ? new_query : new_query.active elsif include_archived new_query = Experiment .where(project: project_ids) - .where_attributes_like([:name, :description], query, options) + .where_attributes_like( + [:name, :description, EXPERIMENT_CODE_SQL], query, options + ) else new_query = Experiment .active .where(project: project_ids) - .where_attributes_like([:name, :description], query, options) + .where_attributes_like( + [:name, :description, EXPERIMENT_CODE_SQL], query, options + ) end # Show all results if needed @@ -99,6 +107,10 @@ class Experiment < ApplicationRecord where(project: Project.viewable_by_user(user, teams)) end + def code + "EX#{id}" + end + def archived_branch? archived? || project.archived? end diff --git a/app/services/experiments_overview_service.rb b/app/services/experiments_overview_service.rb index 98f9ae8b7..b27e1fd61 100644 --- a/app/services/experiments_overview_service.rb +++ b/app/services/experiments_overview_service.rb @@ -49,7 +49,10 @@ class ExperimentsOverviewService records = records.archived if @view_mode == 'archived' && @project.active? records = records.active if @view_mode == 'active' if @params[:search].present? - records = records.where_attributes_like(%w(experiments.name experiments.description), @params[:search]) + records = records.where_attributes_like( + ['experiments.name', 'experiments.description', "('EX' || experiments.id)"], + @params[:search] + ) end if @params[:created_on_from].present? records = records.where('experiments.created_at > ?', @params[:created_on_from]) diff --git a/app/services/reports/docx/draw_experiment.rb b/app/services/reports/docx/draw_experiment.rb index de91d5c3a..cc9a671b5 100644 --- a/app/services/reports/docx/draw_experiment.rb +++ b/app/services/reports/docx/draw_experiment.rb @@ -11,7 +11,7 @@ module Reports::Docx::DrawExperiment @docx.h2 experiment.name, size: Constants::REPORT_DOCX_EXPERIMENT_TITLE_SIZE @docx.p do text I18n.t('projects.reports.elements.experiment.user_time', - timestamp: I18n.l(experiment.created_at, format: :full)), color: color[:gray] + code: experiment.code, timestamp: I18n.l(experiment.created_at, format: :full)), color: color[:gray] if experiment.archived? text ' | ' text I18n.t('search.index.archived'), color: color[:gray] diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb index 7651dd66e..a53f43e3b 100644 --- a/app/views/projects/show.html.erb +++ b/app/views/projects/show.html.erb @@ -25,6 +25,7 @@ <% end %>
<%= t('experiments.card.name') %>
+
<%= t('experiments.id') %>
<%= t('experiments.card.start_date') %>
<%= t('experiments.card.modified_date') %>
<%= t('experiments.card.archived_date') %>
diff --git a/app/views/projects/show/_experiment_actions_dropdown.html.erb b/app/views/projects/show/_experiment_actions_dropdown.html.erb index f57add79e..6ba1e488f 100644 --- a/app/views/projects/show/_experiment_actions_dropdown.html.erb +++ b/app/views/projects/show/_experiment_actions_dropdown.html.erb @@ -63,6 +63,14 @@ <% end %> <% end %> +
  • +
    +
  • +
  • +
    + <%= "#{t('experiments.experiment_id')}: #{experiment.code}" %> +
    +
  • <% end %> diff --git a/app/views/projects/show/_experiment_card.html.erb b/app/views/projects/show/_experiment_card.html.erb index 83de8c23a..8383b4f4f 100644 --- a/app/views/projects/show/_experiment_card.html.erb +++ b/app/views/projects/show/_experiment_card.html.erb @@ -25,11 +25,14 @@ <%= link_to experiment.name, canvas_experiment_path(experiment), title: experiment.name, class: 'name-link' %> <% end %> -
    - <% if can_manage_experiments?(experiment.project) %> - <%= render partial: 'projects/show/experiment_actions_dropdown.html.erb', locals: { experiment: experiment } %> - <% end %> -
    +
    + <%= experiment.code %> +
    +
    + <% if can_manage_experiments?(experiment.project) %> + <%= render partial: 'projects/show/experiment_actions_dropdown.html.erb', locals: { experiment: experiment } %> + <% end %> +
    diff --git a/app/views/reports/elements/_experiment_element.html.erb b/app/views/reports/elements/_experiment_element.html.erb index f75635068..dc90adf49 100644 --- a/app/views/reports/elements/_experiment_element.html.erb +++ b/app/views/reports/elements/_experiment_element.html.erb @@ -5,7 +5,7 @@
    - <%= t('projects.reports.elements.experiment.user_time', timestamp: l(timestamp, format: :full)) %> + <%= t('projects.reports.elements.experiment.user_time', code: experiment.code, timestamp: l(timestamp, format: :full)) %> <%= link_to t('projects.reports.elements.all.scinote_link'),canvas_experiment_url(experiment), target: :_blank %>
    diff --git a/config/locales/en.yml b/config/locales/en.yml index c31c7455f..3b6214450 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -677,7 +677,7 @@ en: protocol: user_time: "Protocol created on %{timestamp}." experiment: - user_time: "Experiment created on %{timestamp}." + user_time: "Experiment %{code} created on %{timestamp}." no_description: "No description" no_tags: "No tags" module_activity: @@ -1001,6 +1001,8 @@ en: body_html: This inventory has been unshared with your team by the inventory’s owner. To view the item/s that are assigned to your task/s contact the %{team_name} team administrator %{admin_name} (%{admin_email}). open_mobile_app: "Open mobile app" experiments: + id: "ID" + experiment_id: "Experiment ID" header: cards: "Cards" table: "Table" diff --git a/db/migrate/20210622101238_fix_experiment_indices.rb b/db/migrate/20210622101238_fix_experiment_indices.rb new file mode 100644 index 000000000..e33d7cd6b --- /dev/null +++ b/db/migrate/20210622101238_fix_experiment_indices.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require File.expand_path('app/helpers/database_helper') + +class FixExperimentIndices < ActiveRecord::Migration[6.1] + include DatabaseHelper + + def up + remove_index :experiments, name: 'index_experiments_on_name', column: 'name' + + add_gin_index_without_tags(:experiments, :name) + add_gin_index_without_tags(:experiments, :description) + + ActiveRecord::Base.connection.execute( + "CREATE INDEX index_experiments_on_experiment_code ON experiments using gin (('EX'::text || id) gin_trgm_ops);" + ) + end + + def down + remove_index :experiments, name: 'index_experiments_on_experiment_code' + remove_index :experiments, name: 'index_experiments_on_description' + remove_index :experiments, name: 'index_experiments_on_name' + + add_index :experiments, :name + end +end diff --git a/db/structure.sql b/db/structure.sql index 4fa9d13bb..8e83ef5dc 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -4349,6 +4349,20 @@ CREATE INDEX index_experiments_on_archived_by_id ON public.experiments USING btr CREATE INDEX index_experiments_on_created_by_id ON public.experiments USING btree (created_by_id); +-- +-- Name: index_experiments_on_description; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_experiments_on_description ON public.experiments USING gin (public.trim_html_tags(description) public.gin_trgm_ops); + + +-- +-- Name: index_experiments_on_experiment_code; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_experiments_on_experiment_code ON public.experiments USING gin ((('EX'::text || id)) public.gin_trgm_ops); + + -- -- Name: index_experiments_on_last_modified_by_id; Type: INDEX; Schema: public; Owner: - -- @@ -4360,7 +4374,7 @@ CREATE INDEX index_experiments_on_last_modified_by_id ON public.experiments USIN -- Name: index_experiments_on_name; Type: INDEX; Schema: public; Owner: - -- -CREATE INDEX index_experiments_on_name ON public.experiments USING btree (name); +CREATE INDEX index_experiments_on_name ON public.experiments USING gin (public.trim_html_tags((name)::text) public.gin_trgm_ops); -- @@ -7235,6 +7249,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20210325152257'), ('20210407143303'), ('20210410100006'), -('20210506125657'); +('20210506125657'), +('20210622101238');