Unify global search page [SCI-10636]

This commit is contained in:
Anton 2024-04-16 13:33:36 +02:00
parent 2ff3477956
commit 57c138f54f
18 changed files with 234 additions and 447 deletions

View file

@ -10,48 +10,24 @@
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout> <SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
</div> </div>
<div class="grid grid-cols-[auto_auto_auto_auto_auto_auto] items-center"> <div class="grid grid-cols-[auto_auto_auto_auto_auto_auto] items-center">
<template v-for="row in preparedResults" :key="row.id"> <div v-for="(row, index) in preparedResults" :key="row.id" class="contents group">
<a target="_blank" :href="row.attributes.parent.url" <hr class="col-span-6 w-full m-0" v-if="index > 0">
class="h-full py-2 px-4 grid grid-cols-[auto_1fr] items-center gap-1 font-bold border-0 border-b border-solid border-sn-light-grey"> <LinkTemplate :url="row.attributes.parent.url" :icon="row.attributes.icon" :value="row.attributes.file_name"/>
<span :class="row.attributes.icon" class="shrink-0"></span> <CellTemplate :label="i18n.t('search.index.created_at')" :value="row.attributes.created_at"/>
<StringWithEllipsis class="w-full" :text="row.attributes.file_name"></StringWithEllipsis> <CellTemplate :label=" i18n.t('search.index.updated_at')" :value="row.attributes.updated_at"/>
</a> <CellTemplate :label="i18n.t('search.index.team')" :url="row.attributes.team.url" :value="row.attributes.team.name"/>
<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"> <CellTemplate :label="i18n.t(`search.index.${row.attributes.parent.type}`)" :url="row.attributes.parent.url" :value="labelName(row.attributes.parent)"/>
<b class="shrink-0">{{ i18n.t('search.index.created_at') }}:</b> <CellTemplate :label="i18n.t(`search.index.${row.attributes.parent.type}`)" :visible="!!row.attributes.experiment.name"
<span class="truncate">{{ row.attributes.created_at }}</span> :url="row.attributes.experiment.url" :value="labelName(row.attributes.experiment)"/>
</div> </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">
<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 target="_blank" :href="row.attributes.team.url" class="shrink-0 overflow-hidden">
<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.${row.attributes.parent.type}`) }}:</b>
<a target="_blank" :href="row.attributes.parent.url" class="shrink-0 overflow-hidden">
<StringWithEllipsis class="w-full" :text="labelName(row.attributes.parent)"></StringWithEllipsis>
</a>
</div>
<div class="s 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"
:class="{ 'invisible': !row.attributes.experiment.name }">
<b class="shrink-0">{{ i18n.t('search.index.experiment') }}:</b>
<a target="_blank" :href="row.attributes.experiment.url" class="shrink-0 overflow-hidden">
<StringWithEllipsis class="w-full" :text="labelName(row.attributes.experiment)"></StringWithEllipsis>
</a>
</div>
</template>
</div> </div>
<div v-if="viewAll" class="mt-4"> <div v-if="viewAll" class="mt-4">
<button class="btn btn-light" @click="$emit('selectGroup', 'AssetsComponent')">View all</button> <button class="btn btn-light" @click="$emit('selectGroup', 'AssetsComponent')">View all</button>
</div> </div>
</template> </template>
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding" <Loader v-if="loading" :loaderRows="loaderRows" />
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" /> <ListEnd v-if="reachedEnd" />
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" /> <NoSearchResult v-else-if="showNoSearchResult" />
</div> </div>
</template> </template>

View file

@ -10,43 +10,22 @@
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout> <SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
</div> </div>
<div class="grid grid-cols-[auto_80px_auto_auto_auto] items-center"> <div class="grid grid-cols-[auto_80px_auto_auto_auto] items-center">
<template v-for="row in preparedResults" :key="row.id"> <div v-for="(row, index) in preparedResults" :key="row.id" class="contents group">
<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"> <hr class="col-span-5 w-full m-0" v-if="index > 0">
<StringWithEllipsis class="w-full" <LinkTemplate :url="row.attributes.url" :value="labelName({ name: row.attributes.name, archived: row.attributes.archived})"/>
:text="labelName({ name: row.attributes.name, archived: row.attributes.archived})"> <CellTemplate :label="i18n.t('search.index.id')" :value="row.attributes.code"/>
</StringWithEllipsis> <CellTemplate :label="i18n.t('search.index.created_at')" :value="row.attributes.created_at"/>
</a> <CellTemplate :label="i18n.t('search.index.team')" :url="row.attributes.team.url" :value="row.attributes.team.name"/>
<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"> <CellTemplate :label="i18n.t('search.index.project')" :url="row.attributes.project.url" :value="labelName(row.attributes.project)"/>
<b class="shrink-0">{{ i18n.t('search.index.id') }}:</b>
<span class="shrink-0">{{ row.attributes.code }}</span>
</div> </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-[220px]">
<b class="shrink-0">{{ i18n.t('search.index.created_at') }}:</b>
<span class="shrink-0">{{ row.attributes.created_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 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.project') }}:</b>
<a :href="row.attributes.project.url" target="_blank" class="shrink-0 overflow-hidden">
<StringWithEllipsis class="w-full" :text="labelName(row.attributes.project)"></StringWithEllipsis>
</a>
</div>
</div>
</template>
</div> </div>
<div v-if="viewAll" class="mt-4"> <div v-if="viewAll" class="mt-4">
<button class="btn btn-light" @click="$emit('selectGroup', 'ExperimentsComponent')">View all</button> <button class="btn btn-light" @click="$emit('selectGroup', 'ExperimentsComponent')">View all</button>
</div> </div>
</template> </template>
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding" <Loader v-if="loading" :loaderRows="loaderRows" />
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" /> <ListEnd v-if="reachedEnd" />
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" /> <NoSearchResult v-else-if="showNoSearchResult" />
</div> </div>
</template> </template>

View file

@ -10,41 +10,22 @@
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout> <SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
</div> </div>
<div class="grid grid-cols-[auto_auto_auto_auto] items-center"> <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"> <div v-for="(row, index) in preparedResults" :key="row.id" class="contents group">
<a target="_blank" :href="row.attributes.url" class="h-full py-2 px-4 overflow-hidden font-bold border-0 border-b border-solid border-sn-light-grey"> <hr class="col-span-4 w-full m-0" v-if="index > 0">
<StringWithEllipsis class="w-full" <LinkTemplate :url="row.attributes.url" :value="labelName({ name: row.attributes.name, archived: row.attributes.archived})"/>
:text="labelName({ name: row.attributes.name, archived: row.attributes.archived})"> <CellTemplate :label="i18n.t('search.index.created_at')" :value="row.attributes.created_at"/>
</StringWithEllipsis> <CellTemplate :label="i18n.t('search.index.team')" :url="row.attributes.team.url" :value="row.attributes.team.name"/>
</a> <CellTemplate :label="i18n.t('search.index.floler')" :visible="row.attributes.parent_folder"
<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"> :url="row.attributes.parent_folder?.url" :value="labelName(row.attributes.parent_folder)"/>
<b class="shrink-0">{{ i18n.t('search.index.created_at') }}:</b>
<span class="shrink-0">{{ row.attributes.created_at }}</span>
</div> </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 border-0 border-b border-solid border-sn-light-grey">
<template v-if="row.attributes.parent_folder">
<div class="grid grid-cols-[auto_1fr] items-center gap-1 text-xs w-full">
<b class="shrink-0">{{ i18n.t('search.index.folder') }}:</b>
<a :href="row.attributes.parent_folder.url" target="_blank" class="shrink-0 overflow-hidden">
<StringWithEllipsis class="w-full" :text="labelName(row.attributes.parent_folder)"></StringWithEllipsis>
</a>
</div>
</template>
</div>
</template>
</div> </div>
<div v-if="viewAll" class="mt-4"> <div v-if="viewAll" class="mt-4">
<button class="btn btn-light" @click="$emit('selectGroup', 'FoldersComponent')">View all</button> <button class="btn btn-light" @click="$emit('selectGroup', 'FoldersComponent')">View all</button>
</div> </div>
</template> </template>
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding" <Loader v-if="loading" :loaderRows="loaderRows" />
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" /> <ListEnd v-if="reachedEnd" />
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" /> <NoSearchResult v-else-if="showNoSearchResult" />
</div> </div>
</template> </template>

View file

@ -0,0 +1,33 @@
<template>
<div class="h-full py-2 px-4 grid grid-cols-[auto_1fr] min-w-[8rem] items-center gap-1 text-xs group-hover:bg-sn-super-light-grey">
<template v-if="visible">
<b class="shrink-0">{{ label }}:</b>
<a v-if="url" :href="url" class="shrink-0 overflow-hidden hover:no-underline">
<img v-if="avatar" :src="avatar" class="w-5 h-5 border border-sn-super-light-grey rounded-full mx-1" />
<StringWithEllipsis class="w-full" :text="value"></StringWithEllipsis>
</a>
<div v-else class="grid grid-cols-[auto_1fr] items-center gap-1 overflow-hidden">
<img v-if="avatar" :src="avatar" class="w-5 h-5 border border-sn-super-light-grey rounded-full mx-1" />
<span class="shrink-0 truncate" :title="value">{{ value }}</span>
</div>
</template>
</div>
</template>
<script>
import StringWithEllipsis from '../../../shared/string_with_ellipsis.vue';
export default {
name: 'CellTemplate',
props: {
label: { type: String, default: '' },
value: { type: String, default: '' },
url: { type: String, default: '' },
avatar: { type: String, default: '' },
visible: { type: Boolean, default: true }
},
components: {
StringWithEllipsis
}
};
</script>

View file

@ -0,0 +1,24 @@
<template>
<a target="_blank" :href="url" class="h-full py-2 px-4 overflow-hidden font-bold flex gap-1 items-center group-hover:bg-sn-super-light-grey hover:no-underline">
<span v-if="icon" :class="icon" class="sn-icon shrink-0"></span>
<StringWithEllipsis class="w-full"
:text="value">
</StringWithEllipsis>
</a>
</template>
<script>
import StringWithEllipsis from '../../../shared/string_with_ellipsis.vue';
export default {
name: 'LinkTemplate',
props: {
value: { type: String, default: '' },
url: { type: String, default: '' },
icon: { type: String, default: '' }
},
components: {
StringWithEllipsis
}
};
</script>

View file

@ -0,0 +1,17 @@
<template>
<div class="flex flex-col gap-6 mt-6">
<div 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>
</p>
</div>
</div>
</template>
<script>
export default {
name: 'ListEnd'
};
</script>

View file

@ -1,5 +1,5 @@
<template> <template>
<div ref="noSearchResult"> <div ref="noSearchResult" class="h-[60vh]">
<div class="flex flex-col gap-6 bg-sn-white text-center relative top-1/4"> <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><span class=" inline-block sn-icon sn-icon-search"></span></div>
<div class=""> <div class="">
@ -17,12 +17,6 @@
<script> <script>
export default { export default {
name: 'NoSearchResult', name: 'NoSearchResult'
props: {
noSearchResultHeight: { type: Number, default: 0 }
},
mounted() {
this.$refs.noSearchResult.style.height = `${this.noSearchResultHeight}px`;
}
}; };
</script> </script>

View file

@ -10,7 +10,7 @@
</template> </template>
<script> <script>
import MenuDropdown from '../../shared/menu_dropdown.vue'; import MenuDropdown from '../../../shared/menu_dropdown.vue';
export default { export default {
name: 'SortFlyout', name: 'SortFlyout',

View file

@ -10,42 +10,23 @@
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout> <SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
</div> </div>
<div class="grid grid-cols-[auto_110px_auto_auto_auto_auto] items-center"> <div class="grid grid-cols-[auto_110px_auto_auto_auto_auto] items-center">
<template v-for="row in preparedResults" :key="row.id"> <div v-for="(row, index) in preparedResults" :key="row.id" class="contents group">
<a :href="row.attributes.url" class="h-full py-2 px-4 overflow-hidden font-bold border-0 border-b border-solid border-sn-light-grey"> <hr class="col-span-6 w-full m-0" v-if="index > 0">
<StringWithEllipsis class="w-full" :text="row.attributes.name"></StringWithEllipsis> <LinkTemplate :url="row.attributes.url" :value="row.attributes.name"/>
</a> <CellTemplate :label="i18n.t('search.index.format')" :value="row.attributes.format"/>
<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"> <CellTemplate :label="i18n.t('search.index.created_at')" :value="row.attributes.created_at"/>
<b class="shrink-0">{{ i18n.t('search.index.format') }}:</b> <CellTemplate :label="i18n.t('search.index.updated_at')" :value="row.attributes.updated_at"/>
<span class="shrink-0">{{ row.attributes.format }}</span> <CellTemplate :label="i18n.t('search.index.created_by')" :avatar="row.attributes.created_by.avatar_url" :value="row.attributes.created_by.name"/>
<CellTemplate :label="i18n.t('search.index.team')" :url="row.attributes.team.url" :value="row.attributes.team.name"/>
</div> </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">
<b class="shrink-0">{{ i18n.t('search.index.created_at') }}:</b>
<span class="shrink-0">{{ 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">
<b class="shrink-0">{{ i18n.t('search.index.updated_at') }}:</b>
<span class="shrink-0">{{ row.attributes.updated_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">
<b class="shrink-0">{{ i18n.t('search.index.created_by') }}:</b>
<img v-if="row.attributes.created_by.avatar_url" :src="row.attributes.created_by.avatar_url" class="w-5 h-5 border border-sn-super-light-grey rounded-full mx-1" />
<span class="shrink-0">{{ row.attributes.created_by.name }}</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">
<StringWithEllipsis class="w-full" :text="row.attributes.team.name"></StringWithEllipsis>
</a>
</div>
</template>
</div> </div>
<div v-if="viewAll" class="mt-4"> <div v-if="viewAll" class="mt-4">
<button class="btn btn-light" @click="$emit('selectGroup', 'LabelTemplatesComponent')">View all</button> <button class="btn btn-light" @click="$emit('selectGroup', 'LabelTemplatesComponent')">View all</button>
</div> </div>
</template> </template>
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding" <Loader v-if="loading" :loaderRows="loaderRows" />
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" /> <ListEnd v-if="reachedEnd" />
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" /> <NoSearchResult v-else-if="showNoSearchResult" />
</div> </div>
</template> </template>

View file

@ -10,53 +10,24 @@
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout> <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"> <div class="grid grid-cols-[auto_80px_auto_auto_auto_auto_auto] items-center">
<template v-for="row in preparedResults" :key="row.id"> <div v-for="(row, index) in preparedResults" :key="row.id" class="contents group">
<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"> <hr class="col-span-7 w-full m-0" v-if="index > 0">
<StringWithEllipsis class="w-full" <LinkTemplate :url="row.attributes.url" :value="labelName({ name: row.attributes.name, archived: row.attributes.archived})"/>
:text="labelName({ name: row.attributes.name, archived: row.attributes.archived})"> <CellTemplate :label="i18n.t('search.index.id')" :value="row.attributes.code"/>
</StringWithEllipsis> <CellTemplate :label="i18n.t('search.index.created_at')" :value="row.attributes.created_at"/>
</a> <CellTemplate :label="i18n.t('search.index.updated_at')" :value="row.attributes.updated_at"/>
<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"> <CellTemplate :label="i18n.t('search.index.team')" :url="row.attributes.team.url" :value="row.attributes.team.name"/>
<b class="shrink-0">{{ i18n.t('search.index.id') }}:</b> <CellTemplate :label="i18n.t('search.index.task')" :url="row.attributes.my_module.url" :value="labelName(row.attributes.my_module)"/>
<span class="shrink-0">{{ row.attributes.code }}</span> <CellTemplate :label="i18n.t('search.index.experiment')" :url="row.attributes.experiment.url" :value="labelName(row.attributes.experiment)"/>
</div> </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.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="labelName(row.attributes.my_module)"></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="labelName(row.attributes.experiment)"></StringWithEllipsis>
</a>
</div>
</div>
</template>
</div> </div>
<div v-if="viewAll" class="mt-4"> <div v-if="viewAll" class="mt-4">
<button class="btn btn-light" @click="$emit('selectGroup', 'MyModuleProtocolsComponent')">View all</button> <button class="btn btn-light" @click="$emit('selectGroup', 'MyModuleProtocolsComponent')">View all</button>
</div> </div>
</template> </template>
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding" <Loader v-if="loading" :loaderRows="loaderRows" />
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" /> <ListEnd v-if="reachedEnd" />
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" /> <NoSearchResult v-else-if="showNoSearchResult" />
</div> </div>
</template> </template>

View file

@ -10,47 +10,23 @@
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout> <SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
</div> </div>
<div class="grid grid-cols-[auto_80px_auto_auto_auto_auto] items-center"> <div class="grid grid-cols-[auto_80px_auto_auto_auto_auto] items-center">
<template v-for="row in preparedResults" :key="row.id"> <div v-for="(row, index) in preparedResults" :key="row.id" class="contents group">
<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"> <hr class="col-span-6 w-full m-0" v-if="index > 0">
<StringWithEllipsis class="w-full" <LinkTemplate :url="row.attributes.url" :value="labelName({ name: row.attributes.name, archived: row.attributes.archived})"/>
:text="labelName({ name: row.attributes.name, archived: row.attributes.archived})"> <CellTemplate :label="i18n.t('search.index.id')" :value="row.attributes.code"/>
</StringWithEllipsis> <CellTemplate :label="i18n.t('search.index.created_at')" :value="row.attributes.created_at"/>
</a> <CellTemplate :label="i18n.t('search.index.updated_at')" :value="row.attributes.updated_at"/>
<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"> <CellTemplate :label="i18n.t('search.index.team')" :url="row.attributes.team.url" :value="row.attributes.team.name"/>
<b class="shrink-0">{{ i18n.t('search.index.id') }}:</b> <CellTemplate :label="i18n.t('search.index.experiment')" :url="row.attributes.experiment.url" :value="labelName(row.attributes.experiment)"/>
<span class="shrink-0">{{ row.attributes.code }}</span>
</div> </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.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 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="labelName(row.attributes.experiment)"></StringWithEllipsis>
</a>
</div>
</div>
</template>
</div> </div>
<div v-if="viewAll" class="mt-4"> <div v-if="viewAll" class="mt-4">
<button class="btn btn-light" @click="$emit('selectGroup', 'MyModulesComponent')">View all</button> <button class="btn btn-light" @click="$emit('selectGroup', 'MyModulesComponent')">View all</button>
</div> </div>
</template> </template>
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding" <Loader v-if="loading" :loaderRows="loaderRows" />
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" /> <ListEnd v-if="reachedEnd" />
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" /> <NoSearchResult v-else-if="showNoSearchResult" />
</div> </div>
</template> </template>

View file

@ -10,45 +10,23 @@
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout> <SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
</div> </div>
<div class="grid grid-cols-[auto_80px_auto_auto_auto] items-center"> <div class="grid grid-cols-[auto_80px_auto_auto_auto] items-center">
<template v-for="row in preparedResults" :key="row.id"> <div v-for="(row, index) in preparedResults" :key="row.id" class="contents group">
<a :href="row.attributes.url" class="h-full py-2 px-4 overflow-hidden font-bold border-0 border-b border-solid border-sn-light-grey"> <hr class="col-span-5 w-full m-0" v-if="index > 0">
<StringWithEllipsis class="w-full" <LinkTemplate :url="row.attributes.url" :value="labelName({ name: row.attributes.name, archived: row.attributes.archived})"/>
:text="labelName({ name: row.attributes.name, archived: row.attributes.archived})"> <CellTemplate :label="i18n.t('search.index.id')" :value="row.attributes.code"/>
</StringWithEllipsis> <CellTemplate :label="i18n.t('search.index.created_at')" :value="row.attributes.created_at"/>
</a> <CellTemplate :label="i18n.t('search.index.team')" :url="row.attributes.team.url" :value="row.attributes.team.name"/>
<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"> <CellTemplate :label="i18n.t('search.index.folder')" :visible="row.attributes.folder"
<b class="shrink-0">{{ i18n.t('search.index.id') }}:</b> :url="row.attributes.folder?.url" :value="labelName(row.attributes.folder)"/>
<span class="shrink-0">{{ row.attributes.code }}</span>
</div> </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">
<b class="shrink-0">{{ i18n.t('search.index.created_at') }}:</b>
<span class="shrink-0">{{ row.attributes.created_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">
<StringWithEllipsis class="w-full" :text="row.attributes.team.name"></StringWithEllipsis>
</a>
</div>
<div class="h-full py-2 px-4 border-0 border-b border-solid border-sn-light-grey">
<template v-if="row.attributes.folder">
<div class="grid grid-cols-[auto_1fr] items-center gap-1 text-xs w-full">
<b class="shrink-0">{{ i18n.t('search.index.folder') }}:</b>
<a :href="row.attributes.folder.url" class="shrink-0 overflow-hidden">
<StringWithEllipsis class="w-full" :text="labelName(row.attributes.folder)"></StringWithEllipsis>
</a>
</div>
</template>
</div>
</template>
</div> </div>
<div v-if="viewAll" class="mt-4"> <div v-if="viewAll" class="mt-4">
<button class="btn btn-light" @click="$emit('selectGroup', 'ProjectsComponent')">View all</button> <button class="btn btn-light" @click="$emit('selectGroup', 'ProjectsComponent')">View all</button>
</div> </div>
</template> </template>
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding" <Loader v-if="loading" :loaderRows="loaderRows" />
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" /> <ListEnd v-if="reachedEnd" />
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" /> <NoSearchResult v-else-if="showNoSearchResult" />
</div> </div>
</template> </template>

View file

@ -10,44 +10,23 @@
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout> <SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
</div> </div>
<div class="grid grid-cols-[auto_110px_auto_auto_auto_auto] items-center"> <div class="grid grid-cols-[auto_110px_auto_auto_auto_auto] items-center">
<template v-for="row in preparedResults" :key="row.id"> <div v-for="(row, index) in preparedResults" :key="row.id" class="contents group">
<a :href="row.attributes.url" class="h-full py-2 px-4 overflow-hidden font-bold border-0 border-b border-solid border-sn-light-grey"> <hr class="col-span-6 w-full m-0" v-if="index > 0">
<StringWithEllipsis class="w-full" <LinkTemplate :url="row.attributes.url" :value="labelName({ name: row.attributes.name, archived: row.attributes.archived})"/>
:text="labelName({ name: row.attributes.name, archived: row.attributes.archived})"> <CellTemplate :label="i18n.t('search.index.id')" :value="row.attributes.code"/>
</StringWithEllipsis> <CellTemplate :label="i18n.t('search.index.created_at')" :value="row.attributes.created_at"/>
</a> <CellTemplate :label="i18n.t('search.index.updated_at')" :value="row.attributes.updated_at"/>
<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"> <CellTemplate :label="i18n.t('search.index.created_by')" :avatar="row.attributes.created_by.avatar_url" :value="row.attributes.created_by.name"/>
<b class="shrink-0">{{ i18n.t('search.index.id') }}:</b> <CellTemplate :label="i18n.t('search.index.team')" :url="row.attributes.team.url" :value="row.attributes.team.name"/>
<span class="shrink-0">{{ row.attributes.code }}</span>
</div> </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">
<b class="shrink-0">{{ i18n.t('search.index.created_at') }}:</b>
<span class="shrink-0">{{ 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">
<b class="shrink-0">{{ i18n.t('search.index.updated_at') }}:</b>
<span class="shrink-0">{{ row.attributes.updated_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">
<b class="shrink-0">{{ i18n.t('search.index.created_by') }}:</b>
<img :src="row.attributes.created_by.avatar_url" class="w-5 h-5 border border-sn-super-light-grey rounded-full mx-1" />
<span class="shrink-0">{{ row.attributes.created_by.name }}</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">
<StringWithEllipsis class="w-full" :text="row.attributes.team.name"></StringWithEllipsis>
</a>
</div>
</template>
</div> </div>
<div v-if="viewAll" class="mt-4"> <div v-if="viewAll" class="mt-4">
<button class="btn btn-light" @click="$emit('selectGroup', 'ProtocolsComponent')">View all</button> <button class="btn btn-light" @click="$emit('selectGroup', 'ProtocolsComponent')">View all</button>
</div> </div>
</template> </template>
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding" <Loader v-if="loading" :loaderRows="loaderRows" />
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" /> <ListEnd v-if="reachedEnd" />
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" /> <NoSearchResult v-else-if="showNoSearchResult" />
</div> </div>
</template> </template>

View file

@ -10,50 +10,24 @@
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout> <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"> <div class="grid grid-cols-[auto_110px_auto_auto_auto_auto_auto] items-center">
<template v-for="row in preparedResults" :key="row.id"> <div v-for="(row, index) in preparedResults" :key="row.id" class="contents group">
<a target="_blank" :href="row.attributes.url" class="h-full py-2 px-4 overflow-hidden font-bold border-0 border-b border-solid border-sn-light-grey"> <hr class="col-span-7 w-full m-0" v-if="index > 0">
<StringWithEllipsis class="w-full" :text="row.attributes.name"></StringWithEllipsis> <LinkTemplate :url="row.attributes.url" :value="row.attributes.name"/>
</a> <CellTemplate :label="i18n.t('search.index.id')" :value="row.attributes.code"/>
<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"> <CellTemplate :label="i18n.t('search.index.created_at')" :value="row.attributes.created_at"/>
<b class="shrink-0">{{ i18n.t('search.index.id') }}:</b> <CellTemplate :label="i18n.t('search.index.updated_at')" :value="row.attributes.updated_at"/>
<span class="shrink-0">{{ row.attributes.code }}</span> <CellTemplate :label="i18n.t('search.index.created_by')" :avatar="row.attributes.created_by.avatar_url" :value="row.attributes.created_by.name"/>
<CellTemplate :label="i18n.t('search.index.team')" :url="row.attributes.team.url" :value="row.attributes.team.name"/>
<CellTemplate :label="i18n.t('search.index.project')" :url="row.attributes.project.url" :value="labelName(row.attributes.project)"/>
</div> </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">
<b class="shrink-0">{{ i18n.t('search.index.created_at') }}:</b>
<span class="shrink-0">{{ 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">
<b class="shrink-0">{{ i18n.t('search.index.updated_at') }}:</b>
<span class="shrink-0">{{ 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.created_by') }}:</b>
<div class="truncate">
<img :src="row.attributes.created_by.avatar_url" class="w-5 h-5 border border-sn-super-light-grey rounded-full mx-1" />
<span class="truncate">{{ row.attributes.created_by.name }}</span>
</div>
</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 target="_blank" :href="row.attributes.team.url" class="shrink-0 overflow-hidden">
<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.project') }}:</b>
<a target="_blank" :href="row.attributes.project.url" class="shrink-0 overflow-hidden">
<StringWithEllipsis class="w-full" :text="labelName(row.attributes.project)"></StringWithEllipsis>
</a>
</div>
</template>
</div> </div>
<div v-if="viewAll" class="mt-4"> <div v-if="viewAll" class="mt-4">
<button class="btn btn-light" @click="$emit('selectGroup', 'ReportsComponent')">View all</button> <button class="btn btn-light" @click="$emit('selectGroup', 'ReportsComponent')">View all</button>
</div> </div>
</template> </template>
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding" <Loader v-if="loading" :loaderRows="loaderRows" />
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" /> <ListEnd v-if="reachedEnd" />
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" /> <NoSearchResult v-else-if="showNoSearchResult" />
</div> </div>
</template> </template>

View file

@ -10,46 +10,23 @@
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout> <SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
</div> </div>
<div class="grid grid-cols-[auto_110px_auto_auto_auto_auto] items-center"> <div class="grid grid-cols-[auto_110px_auto_auto_auto_auto] items-center">
<template v-for="row in preparedResults" :key="row.id"> <div v-for="(row, index) in preparedResults" :key="row.id" class="contents group">
<a :href="row.attributes.url" class="h-full py-2 px-4 overflow-hidden font-bold border-0 border-b border-solid border-sn-light-grey"> <hr class="col-span-6 w-full m-0" v-if="index > 0">
<StringWithEllipsis class="w-full" <LinkTemplate :url="row.attributes.url" :value="labelName({ name: row.attributes.name, archived: row.attributes.archived})"/>
:text="labelName({ name: row.attributes.name, archived: row.attributes.archived})"> <CellTemplate :label="i18n.t('search.index.id')" :value="row.attributes.code"/>
</StringWithEllipsis> <CellTemplate :label="i18n.t('search.index.created_at')" :value="row.attributes.created_at"/>
</a> <CellTemplate :label="i18n.t('search.index.created_by')" :avatar="row.attributes.created_by.avatar_url" :value="row.attributes.created_by.name"/>
<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"> <CellTemplate :label="i18n.t('search.index.team')" :url="row.attributes.team.url" :value="row.attributes.team.name"/>
<b class="shrink-0">{{ i18n.t('search.index.id') }}:</b> <CellTemplate :label="i18n.t('search.index.repository')" :url="row.attributes.repository.url" :value="labelName(row.attributes.repository)"/>
<span class="shrink-0">{{ row.attributes.code }}</span>
</div> </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">
<b class="shrink-0">{{ i18n.t('search.index.created_at') }}:</b>
<span class="shrink-0">{{ 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">
<b class="shrink-0">{{ i18n.t('search.index.created_by') }}:</b>
<img :src="row.attributes.created_by.avatar_url" class="w-5 h-5 border border-sn-super-light-grey rounded-full mx-1" />
<span class="shrink-0">{{ row.attributes.created_by.name }}</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">
<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.repository') }}:</b>
<a :href="row.attributes.repository.url" class="shrink-0 overflow-hidden">
<StringWithEllipsis class="w-full" :text="labelName(row.attributes.repository)"></StringWithEllipsis>
</a>
</div>
</template>
</div> </div>
<div v-if="viewAll" class="mt-4"> <div v-if="viewAll" class="mt-4">
<button class="btn btn-light" @click="$emit('selectGroup', 'RepositoryRowsComponent')">View all</button> <button class="btn btn-light" @click="$emit('selectGroup', 'RepositoryRowsComponent')">View all</button>
</div> </div>
</template> </template>
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding" <Loader v-if="loading" :loaderRows="loaderRows" />
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" /> <ListEnd v-if="reachedEnd" />
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" /> <NoSearchResult v-else-if="showNoSearchResult" />
</div> </div>
</template> </template>

View file

@ -10,49 +10,23 @@
<SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout> <SortFlyout v-if="selected" :sort="sort" @changeSort="changeSort"></SortFlyout>
</div> </div>
<div class="grid grid-cols-[auto_auto_auto_auto_auto_auto] items-center"> <div class="grid grid-cols-[auto_auto_auto_auto_auto_auto] items-center">
<template v-for="row in preparedResults" :key="row.id"> <div v-for="(row, index) in preparedResults" :key="row.id" class="contents group">
<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"> <hr class="col-span-6 w-full m-0" v-if="index > 0">
<StringWithEllipsis class="w-full" <LinkTemplate :url="row.attributes.url" :value="labelName({ name: row.attributes.name, archived: row.attributes.archived})"/>
:text="labelName({ name: row.attributes.name, archived: row.attributes.archived})"> <CellTemplate :label="i18n.t('search.index.created_at')" :value="row.attributes.created_at"/>
</StringWithEllipsis> <CellTemplate :label="i18n.t('search.index.updated_at')" :value="row.attributes.updated_at"/>
</a> <CellTemplate :label="i18n.t('search.index.team')" :url="row.attributes.team.url" :value="row.attributes.team.name"/>
<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]"> <CellTemplate :label="i18n.t('search.index.task')" :url="row.attributes.my_module.url" :value="labelName(row.attributes.my_module)"/>
<b class="shrink-0">{{ i18n.t('search.index.created_at') }}:</b> <CellTemplate :label="i18n.t('search.index.experiment')" :url="row.attributes.experiment.url" :value="labelName(row.attributes.experiment)"/>
<span class="truncate">{{ row.attributes.created_at }}</span>
</div> </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="labelName(row.attributes.my_module)"></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="labelName(row.attributes.experiment)"></StringWithEllipsis>
</a>
</div>
</div>
</template>
</div> </div>
<div v-if="viewAll" class="mt-4"> <div v-if="viewAll" class="mt-4">
<button class="btn btn-light" @click="$emit('selectGroup', 'ResultsComponent')">View all</button> <button class="btn btn-light" @click="$emit('selectGroup', 'ResultsComponent')">View all</button>
</div> </div>
</template> </template>
<Loader v-if="loading" :total="total" :loaderRows="loaderRows" :loaderYPadding="loaderYPadding" <Loader v-if="loading" :loaderRows="loaderRows" />
:loaderHeight="loaderHeight" :loaderGap="loaderGap" :reachedEnd="reachedEnd" /> <ListEnd v-if="reachedEnd" />
<NoSearchResult v-else-if="showNoSearchResult" :noSearchResultHeight="noSearchResultHeight" /> <NoSearchResult v-else-if="showNoSearchResult" />
</div> </div>
</template> </template>

View file

@ -1,8 +1,11 @@
import axios from '../../../packs/custom_axios.js'; import axios from '../../../packs/custom_axios.js';
import StringWithEllipsis from '../../shared/string_with_ellipsis.vue'; import StringWithEllipsis from '../../shared/string_with_ellipsis.vue';
import SortFlyout from './sort_flyout.vue'; import SortFlyout from './helpers/sort_flyout.vue';
import Loader from '../loader.vue'; import Loader from '../loader.vue';
import NoSearchResult from '../no_search_result.vue'; import ListEnd from './helpers/list_end.vue';
import NoSearchResult from './helpers/no_search_result.vue';
import CellTemplate from './helpers/cell_template.vue';
import LinkTemplate from './helpers/link_template.vue';
/* global GLOBAL_CONSTANTS I18n */ /* global GLOBAL_CONSTANTS I18n */
export default { export default {
@ -16,7 +19,10 @@ export default {
StringWithEllipsis, StringWithEllipsis,
SortFlyout, SortFlyout,
Loader, Loader,
NoSearchResult NoSearchResult,
ListEnd,
CellTemplate,
LinkTemplate
}, },
data() { data() {
return { return {
@ -27,10 +33,6 @@ export default {
page: 1, page: 1,
disabled: false, disabled: false,
fullDataLoaded: false, fullDataLoaded: false,
loaderHeight: 24,
loaderGap: 10,
loaderYPadding: 10,
noSearchResultHeight: 0
}; };
}, },
watch: { watch: {
@ -69,20 +71,10 @@ export default {
return !this.selected && this.total > GLOBAL_CONSTANTS.GLOBAL_SEARCH_PREVIEW_LIMIT; return !this.selected && this.total > GLOBAL_CONSTANTS.GLOBAL_SEARCH_PREVIEW_LIMIT;
}, },
loaderRows() { loaderRows() {
// h-[24px] gap-y-[10px] py-[10px] return !this.selected ? 4 : 20;
if (this.loading && (!this.selected || this.total)) return GLOBAL_CONSTANTS.GLOBAL_SEARCH_PREVIEW_LIMIT;
if (this.selected && this.loading) {
const availableHeight = window.innerHeight - this.$refs.content.getBoundingClientRect().top;
// loaderHeight + loaderGap + headerLoaderHeight + headerContentGap
const offSet = this.loaderHeight + this.loaderGap + 32 + 20;
return Math.floor((availableHeight - offSet) / (this.loaderHeight + this.loaderGap + (2 * this.loaderYPadding)));
}
return 0;
}, },
reachedEnd() { reachedEnd() {
return Math.ceil(this.total / GLOBAL_CONSTANTS.SEARCH_LIMIT) === this.page; return !this.page && this.selected;
}, },
showNoSearchResult() { showNoSearchResult() {
return this.selected && !this.loading && !this.results.length; return this.selected && !this.loading && !this.results.length;
@ -90,6 +82,8 @@ export default {
}, },
methods: { methods: {
labelName(object) { labelName(object) {
if (!object) return '';
if (!object.archived) return object.name; if (!object.archived) return object.name;
return `${I18n.t('labels.archived')} ${object.name}`; return `${I18n.t('labels.archived')} ${object.name}`;
@ -130,10 +124,6 @@ export default {
this.disabled = response.data.meta.disabled; this.disabled = response.data.meta.disabled;
this.loading = false; this.loading = false;
this.page = response.data.meta.next_page; 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(() => { .finally(() => {
this.loading = false; this.loading = false;

View file

@ -1,28 +1,16 @@
<template> <template>
<div class="flex flex-col gap-6"> <div class="flex flex-col">
<div v-if="!total" class="grid grid-cols-[32px_auto] gap-2.5">
<div class="h-8 w-8 animate-skeleton rounded"></div>
<div class="h-8 w-40 animate-skeleton rounded"></div>
</div>
<div class="flex flex-col" :class="[`gap-[${loaderGap}px]`]">
<div v-for="_count in loaderRows" <div v-for="_count in loaderRows"
class="flex items-center no-wrap border-0 border-b border-solid border-sn-light-grey gap-x-8" class="flex items-center no-wrap border-0 gap-2 py-2 border-b border-solid border-sn-light-grey gap-x-8"
:class="[`gap-y-[${loaderGap}px]`, `py-[${loaderYPadding}px]`, { 'first:border-t': total }]"> >
<div class="w-[500px] grow-1" :class="`h-[${loaderHeight}px]`"> <div class="w-[500px] grow-1 h-6">
<div class="h-full w-80 animate-skeleton rounded mr-auto"></div> <div class="h-full w-80 animate-skeleton rounded mr-auto"></div>
</div> </div>
<div :class="`h-[${loaderHeight}px]`" class="w-24 max-w-24 animate-skeleton rounded"></div> <div class="w-24 max-w-24 animate-skeleton rounded h-6"></div>
<div :class="`h-[${loaderHeight}px]`" class="w-44 max-w-44 animate-skeleton rounded"></div> <div class="w-44 max-w-44 animate-skeleton rounded h-6"></div>
<div :class="`h-[${loaderHeight}px]`" class="w-44 max-w-44 animate-skeleton rounded"></div> <div class="w-44 max-w-44 animate-skeleton rounded h-6"></div>
<div :class="`h-[${loaderHeight}px]`" class="w-56 max-w-56 animate-skeleton rounded"></div> <div class="w-56 max-w-56 animate-skeleton rounded h-6"></div>
<div :class="`h-[${loaderHeight}px]`" class="w-96 max-w-96 animate-skeleton rounded"></div> <div class="w-96 max-w-96 animate-skeleton rounded h-6"></div>
</div>
</div>
<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>
</p>
</div> </div>
</div> </div>
</template> </template>
@ -32,12 +20,7 @@
export default { export default {
name: 'Loader', name: 'Loader',
props: { props: {
total: { type: Number, default: 0 },
loaderRows: { type: Number, default: 0 }, loaderRows: { type: Number, default: 0 },
loaderHeight: { type: Number, required: true },
loaderGap: { type: Number, required: true },
loaderYPadding: { type: Number, required: true },
reachedEnd: { type: Boolean }
} }
}; };
</script> </script>