mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-11-01 00:56:05 +08:00
Add general layout for global search [SCI-10468]
This commit is contained in:
parent
63c0c554e6
commit
fe1aee4f23
19 changed files with 341 additions and 422 deletions
|
|
@ -4,38 +4,45 @@ class SearchController < ApplicationController
|
|||
before_action :load_vars, only: :index
|
||||
|
||||
def index
|
||||
redirect_to new_search_path unless @search_query
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to new_search_path unless @search_query
|
||||
end
|
||||
format.json do
|
||||
redirect_to new_search_path unless @search_query
|
||||
|
||||
@search_id = params[:search_id] ? params[:search_id] : generate_search_id
|
||||
@search_id = params[:search_id] ? params[:search_id] : generate_search_id
|
||||
|
||||
count_search_results
|
||||
count_search_results
|
||||
|
||||
search_projects if @search_category == :projects
|
||||
search_project_folders if @search_category == :project_folders
|
||||
search_experiments if @search_category == :experiments
|
||||
search_modules if @search_category == :modules
|
||||
search_results if @search_category == :results
|
||||
search_tags if @search_category == :tags
|
||||
search_reports if @search_category == :reports
|
||||
search_protocols if @search_category == :protocols
|
||||
search_steps if @search_category == :steps
|
||||
search_checklists if @search_category == :checklists
|
||||
if @search_category == :repositories && params[:repository]
|
||||
search_repository
|
||||
end
|
||||
search_assets if @search_category == :assets
|
||||
search_tables if @search_category == :tables
|
||||
search_comments if @search_category == :comments
|
||||
search_projects if @search_category == :projects
|
||||
search_project_folders if @search_category == :project_folders
|
||||
search_experiments if @search_category == :experiments
|
||||
search_modules if @search_category == :modules
|
||||
search_results if @search_category == :results
|
||||
search_tags if @search_category == :tags
|
||||
search_reports if @search_category == :reports
|
||||
search_protocols if @search_category == :protocols
|
||||
search_steps if @search_category == :steps
|
||||
search_checklists if @search_category == :checklists
|
||||
if @search_category == :repositories && params[:repository]
|
||||
search_repository
|
||||
end
|
||||
search_assets if @search_category == :assets
|
||||
search_tables if @search_category == :tables
|
||||
search_comments if @search_category == :comments
|
||||
|
||||
@search_pages = (@search_count.to_f / Constants::SEARCH_LIMIT.to_f).ceil
|
||||
@start_page = @search_page - 2
|
||||
@start_page = 1 if @start_page < 1
|
||||
@end_page = @start_page + 4
|
||||
@search_pages = (@search_count.to_f / Constants::SEARCH_LIMIT.to_f).ceil
|
||||
@start_page = @search_page - 2
|
||||
@start_page = 1 if @start_page < 1
|
||||
@end_page = @start_page + 4
|
||||
|
||||
if @end_page > @search_pages
|
||||
@end_page = @search_pages
|
||||
@start_page = @end_page - 4
|
||||
@start_page = 1 if @start_page < 1
|
||||
if @end_page > @search_pages
|
||||
@end_page = @search_pages
|
||||
@start_page = @end_page - 4
|
||||
@start_page = 1 if @start_page < 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
10
app/javascript/packs/vue/global_search.js
Normal file
10
app/javascript/packs/vue/global_search.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import PerfectScrollbar from 'vue3-perfect-scrollbar';
|
||||
import GlobalSearch from '../../vue/global_search/container.vue';
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
const app = createApp();
|
||||
app.component('global_search', GlobalSearch);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
app.use(PerfectScrollbar);
|
||||
mountWithTurbolinks(app, '#GlobalSearch');
|
||||
114
app/javascript/vue/global_search/container.vue
Normal file
114
app/javascript/vue/global_search/container.vue
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
<template>
|
||||
<div class="content-pane flexible with-grey-background">
|
||||
<div class="content-header">
|
||||
<div class="title-row">
|
||||
<h1 class="mt-0">
|
||||
{{ i18n.t('search.index.results_title_html', { query: localQuery }) }}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded p-4 flex gap-2.5 items-center mb-4">
|
||||
<div class="left-icon sci-input-container-v2 w-72 input-sm" :title="i18n.t('nav.search')">
|
||||
<input ref="searchField" type="text" class="!pr-9" v-model="localQuery" :placeholder="i18n.t('nav.search')" @keyup.enter="saveQuery"/>
|
||||
<i class="sn-icon sn-icon-search"></i>
|
||||
<i v-if="localQuery.length > 0" class="sn-icon cursor-pointer sn-icon-close absolute right-0 -top-0.5" @click="localQuery = ''"></i>
|
||||
</div>
|
||||
<div class="flex items-center gap-2.5">
|
||||
<button class="btn btn-secondary btn-sm" :class="{'active': activeGroup == 'ExperimentsComponent'}" @click="setActiveGroup('ExperimentsComponent')">
|
||||
{{ i18n.t('search.index.experiments') }}
|
||||
</button>
|
||||
<button class="btn btn-secondary btn-sm" :class="{'active': activeGroup == 'MyModulesComponent'}" @click="setActiveGroup('MyModulesComponent')">
|
||||
{{ i18n.t('search.index.tasks') }}
|
||||
</button>
|
||||
<button class="btn btn-secondary btn-sm" :class="{'active': activeGroup == 'ResultsComponent'}" @click="setActiveGroup('ResultsComponent')">
|
||||
{{ i18n.t('search.index.task_results') }}
|
||||
</button>
|
||||
</div>
|
||||
<button class="btn btn-light btn-sm">
|
||||
<i class="sn-icon sn-icon-search-options"></i>
|
||||
{{ i18n.t('search.index.more_search_options') }}
|
||||
</button>
|
||||
<template v-if="activeGroup">
|
||||
<div class="h-4 w-[1px] bg-sn-grey"></div>
|
||||
<button class="btn btn-light btn-sm" @click="activeGroup = null">
|
||||
<i class="sn-icon sn-icon-close"></i>
|
||||
{{ i18n.t('search.index.clear_filters') }}
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
<template v-for="group in searchGroups">
|
||||
<component
|
||||
:key="group"
|
||||
:is="group"
|
||||
v-if="activeGroup === group || !activeGroup"
|
||||
:selected="activeGroup === group"
|
||||
:query="localQuery"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FoldersComponent from './groups/folders.vue';
|
||||
import ProjectsComponent from './groups/projects.vue';
|
||||
import ExperimentsComponent from './groups/experiments.vue';
|
||||
import MyModulesComponent from './groups/my_modules.vue';
|
||||
import MyModuleProtocolsComponent from './groups/my_module_protocols.vue';
|
||||
import ResultsComponent from './groups/results.vue';
|
||||
import AssetsComponent from './groups/assets.vue';
|
||||
import RepositoryRowsComponent from './groups/repository_rows.vue';
|
||||
import ProtocolsComponent from './groups/protocols.vue';
|
||||
import LabelTemplatesComponent from './groups/label_templates.vue';
|
||||
import ReportsComponent from './groups/reports.vue';
|
||||
|
||||
export default {
|
||||
name: 'GlobalSearch',
|
||||
props: {
|
||||
query: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
FoldersComponent,
|
||||
ProjectsComponent,
|
||||
ExperimentsComponent,
|
||||
MyModulesComponent,
|
||||
MyModuleProtocolsComponent,
|
||||
ResultsComponent,
|
||||
AssetsComponent,
|
||||
RepositoryRowsComponent,
|
||||
ProtocolsComponent,
|
||||
LabelTemplatesComponent,
|
||||
ReportsComponent
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
localQuery: this.query,
|
||||
activeGroup: null,
|
||||
searchGroups: [
|
||||
'FoldersComponent',
|
||||
'ProjectsComponent',
|
||||
'ExperimentsComponent',
|
||||
'MyModulesComponent',
|
||||
'MyModuleProtocolsComponent',
|
||||
'ResultsComponent',
|
||||
'AssetsComponent',
|
||||
'RepositoryRowsComponent',
|
||||
'ProtocolsComponent',
|
||||
'LabelTemplatesComponent',
|
||||
'ReportsComponent'
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
setActiveGroup(group) {
|
||||
if (group === this.activeGroup) {
|
||||
this.activeGroup = null;
|
||||
} else {
|
||||
this.activeGroup = group;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
14
app/javascript/vue/global_search/groups/assets.vue
Normal file
14
app/javascript/vue/global_search/groups/assets.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-files"></i>
|
||||
{{ i18n.t('search.index.files') }}
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AssetsComponent'
|
||||
};
|
||||
</script>
|
||||
14
app/javascript/vue/global_search/groups/experiments.vue
Normal file
14
app/javascript/vue/global_search/groups/experiments.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-experiment"></i>
|
||||
{{ i18n.t('search.index.experiments') }}
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ExperimentsComponent'
|
||||
};
|
||||
</script>
|
||||
14
app/javascript/vue/global_search/groups/folders.vue
Normal file
14
app/javascript/vue/global_search/groups/folders.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-folder"></i>
|
||||
{{ i18n.t('search.index.folders') }}
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FoldersComponent'
|
||||
};
|
||||
</script>
|
||||
14
app/javascript/vue/global_search/groups/label_templates.vue
Normal file
14
app/javascript/vue/global_search/groups/label_templates.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-label-templates"></i>
|
||||
{{ i18n.t('search.index.label_templates') }}
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'LabelTemplatesComponent'
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-protocols-templates"></i>
|
||||
{{ i18n.t('search.index.task_protocols') }}
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MyModuleProtocolsComponent'
|
||||
};
|
||||
</script>
|
||||
14
app/javascript/vue/global_search/groups/my_modules.vue
Normal file
14
app/javascript/vue/global_search/groups/my_modules.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-task"></i>
|
||||
{{ i18n.t('search.index.tasks') }}
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MyModulesComponent'
|
||||
};
|
||||
</script>
|
||||
14
app/javascript/vue/global_search/groups/projects.vue
Normal file
14
app/javascript/vue/global_search/groups/projects.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-projects"></i>
|
||||
{{ i18n.t('search.index.projects') }}
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ProjectsComponent'
|
||||
};
|
||||
</script>
|
||||
14
app/javascript/vue/global_search/groups/protocols.vue
Normal file
14
app/javascript/vue/global_search/groups/protocols.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-protocols-templates"></i>
|
||||
{{ i18n.t('search.index.protocol_templates') }}
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ProtocolsComponent'
|
||||
};
|
||||
</script>
|
||||
14
app/javascript/vue/global_search/groups/reports.vue
Normal file
14
app/javascript/vue/global_search/groups/reports.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-reports"></i>
|
||||
{{ i18n.t('search.index.reports') }}
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ReportsComponent'
|
||||
};
|
||||
</script>
|
||||
14
app/javascript/vue/global_search/groups/repository_rows.vue
Normal file
14
app/javascript/vue/global_search/groups/repository_rows.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-inventory"></i>
|
||||
{{ i18n.t('search.index.inventory_items') }}
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'RepositoryRowsComponent'
|
||||
};
|
||||
</script>
|
||||
14
app/javascript/vue/global_search/groups/results.vue
Normal file
14
app/javascript/vue/global_search/groups/results.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-results"></i>
|
||||
{{ i18n.t('search.index.task_results') }}
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ResultsComponent'
|
||||
};
|
||||
</script>
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
<template>
|
||||
<div class="sci--navigation--top-menu-container">
|
||||
<QuickSearch v-if="user" :quickSearchUrl="quickSearchUrl" :searchUrl="searchUrl" :currentTeam="currentTeam"></QuickSearch>
|
||||
<div v-if="currentTeam" class="w-64">
|
||||
<SelectDropdown
|
||||
:value="currentTeam"
|
||||
|
|
@ -8,6 +7,7 @@
|
|||
@change="switchTeam"
|
||||
></SelectDropdown>
|
||||
</div>
|
||||
<QuickSearch v-if="user && !hideSearch" :quickSearchUrl="quickSearchUrl" :searchUrl="searchUrl" :currentTeam="currentTeam"></QuickSearch>
|
||||
<MenuDropdown
|
||||
class="ml-auto"
|
||||
v-if="settingsMenu && settingsMenu.length > 0"
|
||||
|
|
@ -97,7 +97,8 @@ export default {
|
|||
helpMenu: null,
|
||||
settingsMenu: null,
|
||||
userMenu: null,
|
||||
unseenNotificationsCount: 0
|
||||
unseenNotificationsCount: 0,
|
||||
hideSearch: false,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
|
@ -108,11 +109,15 @@ export default {
|
|||
this.notificationsOpened = false;
|
||||
this.checkUnseenNotifications();
|
||||
this.refreshCurrentTeam();
|
||||
this.hideSearch = !!document.getElementById('GlobalSearch');
|
||||
});
|
||||
|
||||
// Track name update in user profile settings
|
||||
$(document).on('inlineEditing::updated', '.inline-editing-container[data-field-to-update="full_name"]', this.fetchData);
|
||||
},
|
||||
mounted() {
|
||||
this.hideSearch = !!document.getElementById('GlobalSearch');
|
||||
},
|
||||
beforeUnmount() {
|
||||
clearTimeout(this.unseenNotificationsTimeout);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,354 +1,9 @@
|
|||
<% provide(:head_title, t("search.index.head_title")) %>
|
||||
<div class="content-pane">
|
||||
<div class="page-header">
|
||||
<h1><%= t('search.index.results_title_html', query: @display_query) %></h1>
|
||||
<br>
|
||||
<!-- search form -->
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-8 col-md-6">
|
||||
<%= form_tag search_path,
|
||||
method: :get,
|
||||
role: 'search' do %>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<input class="form-control min-h-[2.5rem]"
|
||||
type="text"
|
||||
name="q"
|
||||
placeholder="<%= t('nav.search') %>"
|
||||
value="<%= @display_query %>">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-secondary" type="submit">
|
||||
<span class="sn-icon sn-icon-search"></span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<label class="checkbox-inline">
|
||||
<input id="search_whole_word" type="checkbox" name="whole_word" value="true" <%= 'checked' if @search_whole_word %>><%= I18n.t('search.whole_word') %>
|
||||
</label>
|
||||
<label class="checkbox-inline">
|
||||
<input id="search_whole_phrase" type="checkbox" name="whole_phrase" value="true" <%= 'checked' if @search_whole_phrase %>><%= I18n.t('search.whole_phrase') %>
|
||||
</label>
|
||||
<label class="checkbox-inline">
|
||||
<input id="search_match_case" type="checkbox" name="match_case" value="true" <%= 'checked' if @search_case %>><%= I18n.t('search.match_case') %>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= form_tag search_path, method: :get do %>
|
||||
<%= hidden_field_tag :q, @search_query %>
|
||||
<%= hidden_field_tag :category, @search_category %>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-3 col-md-3" id="search-menu">
|
||||
<ul class="nav nav-pills nav-stacked nav-stacked-arrow nav-search">
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :projects %>
|
||||
<%= "disabled" if @project_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'projects', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @project_search_count %></span>
|
||||
<span class="sn-icon sn-icon-projects"></span>
|
||||
<%= t'Projects' %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :project_folders %>
|
||||
<%= "disabled" if @project_folder_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= { category: 'project_folders', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id }.to_query %>">
|
||||
<span class="badge pull-right"><%= @project_folder_search_count %></span>
|
||||
<span class="sn-icon sn-icon-folder"></span>
|
||||
<%= t('ProjectFolders') %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :experiments %>
|
||||
<%= "disabled" if @experiment_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'experiments', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @experiment_search_count %></span>
|
||||
<i class="sn-icon sn-icon-experiment"></i>
|
||||
<%= t'Experiments' %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :modules %>
|
||||
<%= "disabled" if @module_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'modules', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @module_search_count %></span>
|
||||
<span class="sn-icon sn-icon-task"></span>
|
||||
<%= t'Modules' %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :results %>
|
||||
<%= "disabled" if @result_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'results', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @result_search_count %></span>
|
||||
<span class="sn-icon sn-icon sn-icon-reports"></span>
|
||||
<%= t'Results' %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :tags %>
|
||||
<%= "disabled" if @tag_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'tags', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @tag_search_count %></span>
|
||||
<span class="sn-icon sn-icon-tag"></span>
|
||||
<%= t'Tags' %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :reports %>
|
||||
<%= "disabled" if @report_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'reports', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @report_search_count %></span>
|
||||
<span class="sn-icon sn-icon-reports"></span>
|
||||
<%= t'Reports' %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :protocols %>
|
||||
<%= "disabled" if @protocol_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'protocols', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @protocol_search_count %></span>
|
||||
<span class="sn-icon sn-icon-protocols-templates"></span>
|
||||
<%= t'Protocols' %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :steps %>
|
||||
<%= "disabled" if @step_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'steps', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @step_search_count %></span>
|
||||
<span class="sn-icon sn-icon-steps"></span>
|
||||
<%= t'Steps' %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :checklists %>
|
||||
<%= "disabled" if @checklist_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'checklists', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @checklist_search_count %></span>
|
||||
<span class="sn-icon sn-icon-checkllist"></span>
|
||||
<%= t'Checklists' %>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :assets %>
|
||||
<%= "disabled" if @asset_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'assets', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @asset_search_count %></span>
|
||||
<span class="sn-icon sn-icon-files"></span>
|
||||
<%= t'Assets' %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :tables %>
|
||||
<%= "disabled" if @table_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'tables', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @table_search_count %></span>
|
||||
<span class="sn-icon sn-icon-tables"></span>
|
||||
<%= t'Tables' %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :comments %>
|
||||
<%= "disabled" if @comment_search_count == 0 %>"
|
||||
>
|
||||
<a href="?<%= {category: 'comments', q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @comment_search_count %></span>
|
||||
<span class="sn-icon sn-icon-comments"></span>
|
||||
<%= t'Comments' %>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<% @repository_search_count.each do |team, results| %>
|
||||
<li class="repositories-team <%= 'active' if results[:count].positive? %>">
|
||||
<i class="sn-icon sn-icon-inventory"></i>
|
||||
<%= t('Repositories_team', team: team) %>
|
||||
</li>
|
||||
<% results[:repositories].each do |repository, values| %>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category == :repositories && @repository.id == values[:id] %>
|
||||
<%= "disabled" if values[:count] == 0 %> repository-search"
|
||||
>
|
||||
<a href="?<%= {category: 'repositories',
|
||||
repository: values[:id], q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= values[:count] %></span>
|
||||
<%= repository %>
|
||||
<%= inventory_shared_status_icon(values[:repository], results[:team]) %>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<% if not @search_category.blank? %>
|
||||
<div class="col-xs-12 col-sm-9" id="search-content">
|
||||
|
||||
<div class="container-fluid" id="search-container">
|
||||
<% if @search_results_count == 0 %>
|
||||
<p><%= t'search.index.error.no_results', q: @search_query %></p>
|
||||
<% end %>
|
||||
|
||||
<hr class="visible-xs">
|
||||
|
||||
<% if @search_category == :projects and @project_search_count.positive? %>
|
||||
<%= render 'search/results/projects', search_query: @search_query, results: @project_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :project_folders and @project_folder_search_count.positive? %>
|
||||
<%= render 'search/results/project_folders', search_query: @search_query, results: @project_folder_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :experiments and @experiment_search_count.positive? %>
|
||||
<%= render 'search/results/experiments', search_query: @search_query, results: @experiment_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :modules and @module_search_count.positive? %>
|
||||
<%= render 'search/results/modules', search_query: @search_query, results: @module_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :results and @result_search_count.positive? %>
|
||||
<%= render 'search/results/results', search_query: @search_query, results: @result_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :tags and @tag_search_count.positive? %>
|
||||
<%= render 'search/results/tags', search_query: @search_query, results: @tag_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :reports and @report_search_count.positive? %>
|
||||
<%= render 'search/results/reports', search_query: @search_query, results: @report_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :protocols and @protocol_search_count.positive? %>
|
||||
<%= render 'search/results/protocols', search_query: @search_query, results: @protocol_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :steps and @step_search_count.positive? %>
|
||||
<%= render 'search/results/steps', search_query: @search_query, results: @step_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :checklists and @checklist_search_count.positive? %>
|
||||
<%= render 'search/results/checklists', search_query: @search_query, results: @checklist_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :repositories and @repository_search_count_total.positive? %>
|
||||
<%= render 'search/results/repositories', search_query: @search_query, results: @repository_results, repository: @repository %>
|
||||
<% end %>
|
||||
<% if @search_category == :assets and @asset_search_count.positive? %>
|
||||
<%= render 'search/results/assets', search_query: @search_query, results: @asset_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :tables and @table_search_count.positive? %>
|
||||
<%= render 'search/results/tables', search_query: @search_query, results: @table_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :comments and @comment_search_count.positive? %>
|
||||
<%= render 'search/results/comments', search_query: @search_query, results: @comment_results %>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
||||
<% if @search_pages > 1 %>
|
||||
<% params = { q: @search_query,
|
||||
category: @search_category,
|
||||
utf8: '✓',
|
||||
search_id: @search_id } %>
|
||||
<% if @search_category == :repositories %>
|
||||
<% params[:repository] = @repository.id %>
|
||||
<% end %>
|
||||
<nav class="text-center">
|
||||
<ul class="pagination">
|
||||
<% if @search_page > 1 %>
|
||||
<% params[:page] = @search_page - 1 %>
|
||||
<li>
|
||||
<a href="?<%= params.to_query %>" aria-label="Previous">
|
||||
<span aria-hidden="true">«</span>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% (@start_page..@end_page).each do |page_i| %>
|
||||
<% params[:page] = page_i %>
|
||||
<li <% if @search_page == page_i %>class="active"<% end %>>
|
||||
<a href="?<%= params.to_query %>"><%= page_i %></a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if @search_page < @search_pages %>
|
||||
<% params[:page] = @search_page + 1 %>
|
||||
<li>
|
||||
<a href="?<%= params.to_query %>" aria-label="Next">
|
||||
<span aria-hidden="true">»</span>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</nav>
|
||||
<% end %>
|
||||
<div id="GlobalSearch" class="contents">
|
||||
<global_search
|
||||
:query="'<%= @display_query %>'"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<%= javascript_include_tag('search') %>
|
||||
<%= javascript_include_tag "vue_global_search" %>
|
||||
|
|
|
|||
|
|
@ -615,6 +615,7 @@ class Extends
|
|||
protocols/show
|
||||
preferences/index
|
||||
addons/index
|
||||
search/index
|
||||
)
|
||||
|
||||
DEFAULT_USER_NOTIFICATION_SETTINGS = {
|
||||
|
|
|
|||
|
|
@ -441,48 +441,20 @@ en:
|
|||
index:
|
||||
head_title: "Search"
|
||||
page_title: "Search"
|
||||
results_title_html: "Search Results for '<em>%{query}</em>'"
|
||||
public: "Public"
|
||||
private: "Private"
|
||||
archived: "Archived"
|
||||
in_repository: "Protocol templates"
|
||||
created_by: "Created by: "
|
||||
created_at: "Created at: "
|
||||
last_modified_by: "Last modified by: "
|
||||
last_modified_at: "Last modified at: "
|
||||
keywords: "Keywords: "
|
||||
authors: "Authors: "
|
||||
description: "Description: "
|
||||
no_description: "No description"
|
||||
text: "Text"
|
||||
team: "Team: "
|
||||
folder: "Folders: "
|
||||
repository: "Inventory: "
|
||||
repository_row: "Inventory item: "
|
||||
project: "Project: "
|
||||
experiment: "Experiment: "
|
||||
protocol: "Protocol: "
|
||||
modules: "Tasks: "
|
||||
tag_no_modules: "not added to any tasks"
|
||||
module: "Task: "
|
||||
step: "Step: "
|
||||
result: "Result: "
|
||||
report: "Report: "
|
||||
no_name: "(no name)"
|
||||
error:
|
||||
no_results: "No results for %{q}."
|
||||
repositories:
|
||||
repository_row: "Inventory item: "
|
||||
added_on: "Added on: "
|
||||
added_by: "Added by: "
|
||||
custom_column: "%{column}: "
|
||||
no_modules: "not assigned to any task"
|
||||
comments:
|
||||
project: "Project comment"
|
||||
my_module: "Task comment"
|
||||
step: "Step comment"
|
||||
result: "Result comment"
|
||||
|
||||
results_title_html: "Search Results for '%{query}'"
|
||||
experiments: "Experiments"
|
||||
tasks: "Tasks"
|
||||
task_results: "Task results"
|
||||
folders: "Folders"
|
||||
projects: "Projects"
|
||||
task_protocols: "Task protocols"
|
||||
files: "Files"
|
||||
inventory_items: "Inventory items"
|
||||
protocol_templates: "Protocol templates"
|
||||
label_templates: "Label templates"
|
||||
reports: "Reports"
|
||||
more_search_options: "More search options"
|
||||
clear_filters: "Clear filters"
|
||||
comments:
|
||||
save_changes: "Save changes"
|
||||
empty_state:
|
||||
|
|
|
|||
|
|
@ -59,9 +59,10 @@ const entryList = {
|
|||
vue_open_locally_menu: './app/javascript/packs/vue/open_locally_menu.js',
|
||||
vue_scinote_edit_download: './app/javascript/packs/vue/scinote_edit_download.js',
|
||||
vue_design_system_modals: './app/javascript/packs/vue/design_system/modals.js',
|
||||
vue_global_search: './app/javascript/packs/vue/global_search.js',
|
||||
vue_legacy_tags_modal: './app/javascript/packs/vue/legacy/tags_modal.js',
|
||||
vue_legacy_access_modal: './app/javascript/packs/vue/legacy/access_modal.js',
|
||||
vue_legacy_repository_menu_dropdown: './app/javascript/packs/vue/legacy/repository_menu_dropdown.js'
|
||||
vue_legacy_repository_menu_dropdown: './app/javascript/packs/vue/legacy/repository_menu_dropdown.js',
|
||||
};
|
||||
|
||||
// Engine pack loading based on https://github.com/rails/webpacker/issues/348#issuecomment-635480949
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue