mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-12-16 05:42:13 +08:00
Add sorting to global search [SCI-10528]
This commit is contained in:
parent
1e7bb69763
commit
c2da52a6bb
14 changed files with 186 additions and 98 deletions
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<div v-if="total" 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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-files"></i>
|
||||
{{ i18n.t('search.index.files') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-[auto_auto_auto_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<div v-if="total" 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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-experiment"></i>
|
||||
{{ i18n.t('search.index.experiments') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-[auto_80px_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<div v-if="total" 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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-folder"></i>
|
||||
{{ i18n.t('search.index.folders') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-[auto_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id" class="hover:bg-sn-super-light-grey">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<div class="bg-white rounded p-4 mb-4" v-if="!disabled">
|
||||
<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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<div class="bg-white rounded p-4 mb-4" v-if="total">
|
||||
<div class="flex items-center">
|
||||
<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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-[auto_110px_auto_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<div v-if="total" 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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<div class="flex items-center">
|
||||
<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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-[auto_80px_auto_auto_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<div v-if="total" 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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-task"></i>
|
||||
{{ i18n.t('search.index.tasks') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-[auto_80px_auto_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<div v-if="total" 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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-projects"></i>
|
||||
{{ i18n.t('search.index.projects') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-[auto_80px_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<div v-if="total" class="bg-white rounded p-4 mb-4">
|
||||
<div class="flex items-center">
|
||||
<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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-[auto_110px_auto_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<template>
|
||||
<div v-if="total" 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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-reports"></i>
|
||||
{{ i18n.t('search.index.reports') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-[auto_110px_auto_auto_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id">
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<div class="flex items-center">
|
||||
<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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-[auto_110px_auto_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id">
|
||||
|
|
|
|||
|
|
@ -1,51 +1,52 @@
|
|||
<template>
|
||||
<div v-if="total" 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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-[auto_auto_auto_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id">
|
||||
<a :href="row.attributes.url" target="_blank" class="h-full py-2 px-4 overflow-hidden font-bold border-0 border-b border-solid border-sn-light-grey">
|
||||
<StringWithEllipsis class="w-full" :text="row.attributes.name"></StringWithEllipsis>
|
||||
</a>
|
||||
<div class="h-full py-2 px-4 flex items-center gap-1 text-xs border-0 border-b border-solid border-sn-light-grey max-w-[200px]">
|
||||
<b class="shrink-0">{{ i18n.t('search.index.created_at') }}:</b>
|
||||
<span class="truncate">{{ row.attributes.created_at }}</span>
|
||||
</div>
|
||||
<div class="h-full py-2 px-4 flex items-center gap-1 text-xs border-0 border-b border-solid border-sn-light-grey max-w-[200px]">
|
||||
<b class="shrink-0">{{ i18n.t('search.index.updated_at') }}:</b>
|
||||
<span class="truncate">{{ row.attributes.updated_at }}</span>
|
||||
</div>
|
||||
<div class="h-full py-2 px-4 grid grid-cols-[auto_1fr] items-center gap-1 text-xs border-0 border-b border-solid border-sn-light-grey">
|
||||
<b class="shrink-0">{{ i18n.t('search.index.team') }}:</b>
|
||||
<a :href="row.attributes.team.url" class="shrink-0 overflow-hidden" target="_blank">
|
||||
<StringWithEllipsis class="w-full" :text="row.attributes.team.name"></StringWithEllipsis>
|
||||
</a>
|
||||
</div>
|
||||
<div class="h-full py-2 px-4 grid grid-cols-[auto_1fr] items-center gap-1 text-xs border-0 border-b border-solid border-sn-light-grey">
|
||||
<b class="shrink-0">{{ i18n.t('search.index.task') }}:</b>
|
||||
<a :href="row.attributes.my_module.url" class="shrink-0 overflow-hidden" target="_blank">
|
||||
<StringWithEllipsis class="w-full" :text="row.attributes.my_module.name"></StringWithEllipsis>
|
||||
</a>
|
||||
</div>
|
||||
<div class="h-full py-2 px-4 border-0 border-b border-solid border-sn-light-grey">
|
||||
<div class="grid grid-cols-[auto_1fr] items-center gap-1 text-xs w-full">
|
||||
<b class="shrink-0">{{ i18n.t('search.index.experiment') }}:</b>
|
||||
<a :href="row.attributes.experiment.url" class="shrink-0 overflow-hidden" target="_blank">
|
||||
<StringWithEllipsis class="w-full" :text="row.attributes.experiment.name"></StringWithEllipsis>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div v-if="viewAll" class="mt-4">
|
||||
<button class="btn btn-light" @click="$emit('selectGroup', 'ResultsComponent')">View all</button>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<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') }}
|
||||
[{{ total }}]
|
||||
</h2>
|
||||
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
|
||||
</div>
|
||||
<div class="grid grid-cols-[auto_auto_auto_auto_auto_auto] items-center">
|
||||
<template v-for="row in preparedResults" :key="row.id">
|
||||
<a :href="row.attributes.url" target="_blank" class="h-full py-2 px-4 overflow-hidden font-bold border-0 border-b border-solid border-sn-light-grey">
|
||||
<StringWithEllipsis class="w-full" :text="row.attributes.name"></StringWithEllipsis>
|
||||
</a>
|
||||
<div class="h-full py-2 px-4 flex items-center gap-1 text-xs border-0 border-b border-solid border-sn-light-grey max-w-[200px]">
|
||||
<b class="shrink-0">{{ i18n.t('search.index.created_at') }}:</b>
|
||||
<span class="truncate">{{ row.attributes.created_at }}</span>
|
||||
</div>
|
||||
<div class="h-full py-2 px-4 flex items-center gap-1 text-xs border-0 border-b border-solid border-sn-light-grey max-w-[200px]">
|
||||
<b class="shrink-0">{{ i18n.t('search.index.updated_at') }}:</b>
|
||||
<span class="truncate">{{ row.attributes.updated_at }}</span>
|
||||
</div>
|
||||
<div class="h-full py-2 px-4 grid grid-cols-[auto_1fr] items-center gap-1 text-xs border-0 border-b border-solid border-sn-light-grey">
|
||||
<b class="shrink-0">{{ i18n.t('search.index.team') }}:</b>
|
||||
<a :href="row.attributes.team.url" class="shrink-0 overflow-hidden" target="_blank">
|
||||
<StringWithEllipsis class="w-full" :text="row.attributes.team.name"></StringWithEllipsis>
|
||||
</a>
|
||||
</div>
|
||||
<div class="h-full py-2 px-4 grid grid-cols-[auto_1fr] items-center gap-1 text-xs border-0 border-b border-solid border-sn-light-grey">
|
||||
<b class="shrink-0">{{ i18n.t('search.index.task') }}:</b>
|
||||
<a :href="row.attributes.my_module.url" class="shrink-0 overflow-hidden" target="_blank">
|
||||
<StringWithEllipsis class="w-full" :text="row.attributes.my_module.name"></StringWithEllipsis>
|
||||
</a>
|
||||
</div>
|
||||
<div class="h-full py-2 px-4 border-0 border-b border-solid border-sn-light-grey">
|
||||
<div class="grid grid-cols-[auto_1fr] items-center gap-1 text-xs w-full">
|
||||
<b class="shrink-0">{{ i18n.t('search.index.experiment') }}:</b>
|
||||
<a :href="row.attributes.experiment.url" class="shrink-0 overflow-hidden" target="_blank">
|
||||
<StringWithEllipsis class="w-full" :text="row.attributes.experiment.name"></StringWithEllipsis>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div v-if="viewAll" class="mt-4">
|
||||
<button class="btn btn-light" @click="$emit('selectGroup', 'ResultsComponent')">View all</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import axios from '../../../packs/custom_axios.js';
|
||||
import StringWithEllipsis from '../../shared/string_with_ellipsis.vue';
|
||||
import SortFlyout from './sort_flyout.vue';
|
||||
/* global GLOBAL_CONSTANTS */
|
||||
|
||||
export default {
|
||||
|
|
@ -10,10 +11,12 @@ export default {
|
|||
filters: Object
|
||||
},
|
||||
components: {
|
||||
StringWithEllipsis
|
||||
StringWithEllipsis,
|
||||
SortFlyout
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sort: 'created_desc',
|
||||
results: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
|
|
@ -66,6 +69,12 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
changeSort(sort) {
|
||||
this.sort = sort;
|
||||
this.results = [];
|
||||
this.page = 1;
|
||||
this.loadData();
|
||||
},
|
||||
loadData() {
|
||||
if (this.loading && this.page) return;
|
||||
|
||||
|
|
@ -73,6 +82,7 @@ export default {
|
|||
axios.get(this.searchUrl, {
|
||||
params: {
|
||||
q: this.query,
|
||||
sort: this.sort,
|
||||
filters: this.filters,
|
||||
group: this.group,
|
||||
preview: !this.selected,
|
||||
|
|
|
|||
43
app/javascript/vue/global_search/groups/sort_flyout.vue
Normal file
43
app/javascript/vue/global_search/groups/sort_flyout.vue
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<template>
|
||||
<MenuDropdown
|
||||
class="ml-auto"
|
||||
:listItems="sortOptions"
|
||||
btnClasses="btn btn-light icon-btn btn-black"
|
||||
position="right"
|
||||
@dtEvent="changeSort"
|
||||
btnIcon="sn-icon sn-icon-sort-down"
|
||||
></MenuDropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MenuDropdown from '../../shared/menu_dropdown.vue';
|
||||
|
||||
export default {
|
||||
name: 'SortFlyout',
|
||||
props: {
|
||||
sort: {
|
||||
type: String,
|
||||
default: 'created_desc'
|
||||
}
|
||||
},
|
||||
components: {
|
||||
MenuDropdown
|
||||
},
|
||||
computed: {
|
||||
sortOptions() {
|
||||
return ['created_desc', 'created_asc', 'atoz', 'ztoa'].map((sort) => (
|
||||
{
|
||||
emit: sort,
|
||||
text: this.i18n.t(`search.index.${sort}`),
|
||||
active: this.sort === sort
|
||||
}
|
||||
));
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeSort(value) {
|
||||
this.$emit('changeSort', value);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -481,6 +481,10 @@ en:
|
|||
untitled_protocol: 'Untitled protocol'
|
||||
protocol_template: "Protocol template"
|
||||
inventory_item: "Inventory item"
|
||||
created_desc: "Created last"
|
||||
created_asc: "Created first"
|
||||
atoz: "Name A to Z"
|
||||
ztoa: "Name Z to A"
|
||||
comments:
|
||||
save_changes: "Save changes"
|
||||
empty_state:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue