mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-10-28 15:15:34 +08:00
Add no search results page to Global search page [SCI-10481]
This commit is contained in:
parent
50e3311033
commit
d24f3b76a8
15 changed files with 78 additions and 69 deletions
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': total || loading }">
|
||||
<template v-if="total">
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': results.length || loading }">
|
||||
<template v-if="total && results.length">
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-files"></i>
|
||||
|
|
@ -51,19 +51,16 @@
|
|||
</template>
|
||||
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding"
|
||||
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" />
|
||||
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loader from '../loader.vue';
|
||||
import searchMixin from './search_mixin';
|
||||
|
||||
export default {
|
||||
name: 'AssetsComponent',
|
||||
mixins: [searchMixin],
|
||||
components: {
|
||||
Loader
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
group: 'assets'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': total || loading }">
|
||||
<template v-if="total">
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': results.length || loading }">
|
||||
<template v-if="total && results.length">
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-experiment"></i>
|
||||
|
|
@ -44,18 +44,15 @@
|
|||
</template>
|
||||
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding"
|
||||
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" />
|
||||
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loader from '../loader.vue';
|
||||
import searchMixin from './search_mixin';
|
||||
|
||||
export default {
|
||||
name: 'ExperimentsComponent',
|
||||
components: {
|
||||
Loader
|
||||
},
|
||||
mixins: [searchMixin],
|
||||
data() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': total || loading }">
|
||||
<template v-if="total">
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': results.length || loading }">
|
||||
<template v-if="total && results.length">
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-folder"></i>
|
||||
|
|
@ -42,19 +42,16 @@
|
|||
</template>
|
||||
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding"
|
||||
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" />
|
||||
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loader from '../loader.vue';
|
||||
import searchMixin from './search_mixin';
|
||||
|
||||
export default {
|
||||
name: 'FoldersComponent',
|
||||
mixins: [searchMixin],
|
||||
components: {
|
||||
Loader
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
group: 'project_folders'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': total || loading }">
|
||||
<template v-if="!disabled && total">
|
||||
<div v-if="!disabled" ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': results.length || loading }">
|
||||
<template v-if="total && results.length">
|
||||
<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>
|
||||
|
|
@ -45,19 +45,16 @@
|
|||
</template>
|
||||
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding"
|
||||
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" />
|
||||
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loader from '../loader.vue';
|
||||
import searchMixin from './search_mixin';
|
||||
|
||||
export default {
|
||||
name: 'LabelTemplatesComponent',
|
||||
mixins: [searchMixin],
|
||||
components: {
|
||||
Loader
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
group: 'label_templates'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': total || loading }">
|
||||
<template v-if="total">
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': results.length || loading }">
|
||||
<template v-if="total && results.length">
|
||||
<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>
|
||||
|
|
@ -54,19 +54,16 @@
|
|||
</template>
|
||||
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding"
|
||||
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" />
|
||||
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loader from '../loader.vue';
|
||||
import searchMixin from './search_mixin';
|
||||
|
||||
export default {
|
||||
name: 'MyModuleProtocolsComponent',
|
||||
mixins: [searchMixin],
|
||||
components: {
|
||||
Loader
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
group: 'module_protocols'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': total || loading }">
|
||||
<template v-if="total">
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': results.length || loading }">
|
||||
<template v-if="total && results.length">
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-task"></i>
|
||||
|
|
@ -48,18 +48,15 @@
|
|||
</template>
|
||||
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding"
|
||||
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" />
|
||||
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loader from '../loader.vue';
|
||||
import searchMixin from './search_mixin';
|
||||
|
||||
export default {
|
||||
name: 'MyModulesComponent',
|
||||
components: {
|
||||
Loader
|
||||
},
|
||||
mixins: [searchMixin],
|
||||
data() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': total || loading }">
|
||||
<template v-if="total">
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': results.length || loading }">
|
||||
<template v-if="total && results.length">
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-projects"></i>
|
||||
|
|
@ -46,19 +46,16 @@
|
|||
</template>
|
||||
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding"
|
||||
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" />
|
||||
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loader from '../loader.vue';
|
||||
import searchMixin from './search_mixin';
|
||||
|
||||
export default {
|
||||
name: 'ProjectsComponent',
|
||||
mixins: [searchMixin],
|
||||
components: {
|
||||
Loader
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
group: 'projects'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': total || loading }">
|
||||
<template v-if="total">
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': results.length || loading }">
|
||||
<template v-if="total && results.length">
|
||||
<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>
|
||||
|
|
@ -45,19 +45,16 @@
|
|||
</template>
|
||||
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding"
|
||||
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" />
|
||||
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loader from '../loader.vue';
|
||||
import searchMixin from './search_mixin';
|
||||
|
||||
export default {
|
||||
name: 'ProtocolsComponent',
|
||||
mixins: [searchMixin],
|
||||
components: {
|
||||
Loader
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
group: 'protocols'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': total || loading }">
|
||||
<template v-if="total">
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': results.length || loading }">
|
||||
<template v-if="total && results.length">
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-reports"></i>
|
||||
|
|
@ -53,19 +53,16 @@
|
|||
</template>
|
||||
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding"
|
||||
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" />
|
||||
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loader from '../loader.vue';
|
||||
import searchMixin from './search_mixin';
|
||||
|
||||
export default {
|
||||
name: 'ReportsComponent',
|
||||
mixins: [searchMixin],
|
||||
components: {
|
||||
Loader
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
group: 'reports'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': total || loading }">
|
||||
<template v-if="total">
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': results.length || loading }">
|
||||
<template v-if="total && results.length">
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-inventory"></i>
|
||||
|
|
@ -47,19 +47,16 @@
|
|||
</template>
|
||||
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding"
|
||||
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" />
|
||||
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loader from '../loader.vue';
|
||||
import searchMixin from './search_mixin';
|
||||
|
||||
export default {
|
||||
name: 'RepositoryRowsComponent',
|
||||
mixins: [searchMixin],
|
||||
components: {
|
||||
Loader
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
group: 'repository_rows'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': total || loading }">
|
||||
<template v-if="total">
|
||||
<div ref="content" class="bg-white rounded" :class="{ 'p-4 mb-4': results.length || loading }">
|
||||
<template v-if="total && results.length">
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex items-center gap-2 mt-0 mb-4">
|
||||
<i class="sn-icon sn-icon-results"></i>
|
||||
|
|
@ -50,19 +50,16 @@
|
|||
</template>
|
||||
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding"
|
||||
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" />
|
||||
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Loader from '../loader.vue';
|
||||
import searchMixin from './search_mixin';
|
||||
|
||||
export default {
|
||||
name: 'ResultsComponent',
|
||||
mixins: [searchMixin],
|
||||
components: {
|
||||
Loader
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
group: 'results'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import axios from '../../../packs/custom_axios.js';
|
||||
import StringWithEllipsis from '../../shared/string_with_ellipsis.vue';
|
||||
import SortFlyout from './sort_flyout.vue';
|
||||
import Loader from '../loader.vue';
|
||||
import NoSearchResult from '../no_search_result.vue';
|
||||
/* global GLOBAL_CONSTANTS */
|
||||
|
||||
export default {
|
||||
|
|
@ -12,7 +14,9 @@ export default {
|
|||
},
|
||||
components: {
|
||||
StringWithEllipsis,
|
||||
SortFlyout
|
||||
SortFlyout,
|
||||
Loader,
|
||||
NoSearchResult
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -25,7 +29,8 @@ export default {
|
|||
fullDataLoaded: false,
|
||||
loaderHeight: 24,
|
||||
loaderGap: 10,
|
||||
loaderYPadding: 10
|
||||
loaderYPadding: 10,
|
||||
noSearchResultHeight: 0
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
|
@ -78,6 +83,9 @@ export default {
|
|||
},
|
||||
reachedEnd() {
|
||||
return Math.ceil(this.total / GLOBAL_CONSTANTS.SEARCH_LIMIT) === this.page;
|
||||
},
|
||||
showNoSearchResult() {
|
||||
return this.selected && !this.loading && !this.results.length;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -117,6 +125,10 @@ export default {
|
|||
this.disabled = response.data.meta.disabled;
|
||||
this.loading = false;
|
||||
this.page = response.data.meta.next_page;
|
||||
if (this.results.length === 0 && this.selected) {
|
||||
const availableHeight = window.innerHeight - this.$refs.content.getBoundingClientRect().top;
|
||||
this.noSearchResultHeight = availableHeight - 20;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<div :class="`h-[${loaderHeight}px]`" class="w-96 max-w-96 animate-skeleton rounded"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="reachedEnd" class="flex items-center">
|
||||
<div v-if="reachedEnd" class="flex items-center mb-6">
|
||||
<p class="text-sm text-sn-blue flex items-center gap-3 m-auto">
|
||||
<span class="sn-icon sn-icon-flag"></span>
|
||||
<span>{{ i18n.t('search.index.reached_end') }}</span>
|
||||
|
|
|
|||
28
app/javascript/vue/global_search/no_search_result.vue
Normal file
28
app/javascript/vue/global_search/no_search_result.vue
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<template>
|
||||
<div ref="noSearchResult">
|
||||
<div class="flex flex-col gap-6 bg-sn-white text-center relative top-1/4">
|
||||
<div><span class=" inline-block sn-icon sn-icon-search"></span></div>
|
||||
<div class="">
|
||||
<p class="text-sn-black text-2xl font-semibold">
|
||||
{{ i18n.t('search.index.no_results_text') }}
|
||||
</p>
|
||||
<p class="text-sn-dark-grey text-base">
|
||||
{{ i18n.t('search.index.adjust_search_text') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'NoSearchResult',
|
||||
props: {
|
||||
noSearchResultHeight: { type: Number, default: 0 }
|
||||
},
|
||||
mounted() {
|
||||
this.$refs.noSearchResult.style.height = `${this.noSearchResultHeight}px`;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -486,6 +486,8 @@ en:
|
|||
atoz: "Name A to Z"
|
||||
ztoa: "Name Z to A"
|
||||
reached_end: "You’ve reached the end of the list"
|
||||
no_results_text: "No search results found"
|
||||
adjust_search_text: "Try adjusting your search or filter to find what you are looking for."
|
||||
comments:
|
||||
save_changes: "Save changes"
|
||||
empty_state:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue