Commit e40a1608 authored by Olena Horal-Koretska's avatar Olena Horal-Koretska Committed by Natalia Tepluhina

Improve error list UI on mobile viewports

Create adaptive layout for xs viewport
parent 383ead5d
......@@ -25,10 +25,33 @@ export default {
PREV_PAGE: 1,
NEXT_PAGE: 2,
fields: [
{ key: 'error', label: __('Open errors'), thClass: 'w-70p' },
{ key: 'events', label: __('Events') },
{ key: 'users', label: __('Users') },
{ key: 'lastSeen', label: __('Last seen'), thClass: 'w-15p' },
{
key: 'error',
label: __('Error'),
thClass: 'w-70p',
tdClass: 'table-col d-flex align-items-center d-sm-table-cell',
},
{
key: 'events',
label: __('Events'),
tdClass: 'table-col d-flex align-items-center d-sm-table-cell',
},
{
key: 'users',
label: __('Users'),
tdClass: 'table-col d-flex align-items-center d-sm-table-cell',
},
{
key: 'lastSeen',
label: __('Last seen'),
thClass: 'w-15p',
tdClass: 'table-col d-flex align-items-center d-sm-table-cell',
},
{
key: 'details',
tdClass: 'table-col d-sm-none d-flex align-items-center',
thClass: 'invisible w-0',
},
],
sortFields: {
last_seen: __('Last Seen'),
......@@ -149,12 +172,13 @@ export default {
<div class="error-list">
<div v-if="errorTrackingEnabled">
<div
class="d-flex flex-row justify-content-around align-items-center bg-secondary border mt-2"
class="row flex-column flex-sm-row align-items-sm-center row-top m-0 mt-sm-2 mx-sm-1 p-0 p-sm-3"
>
<div class="filtered-search-box flex-grow-1 my-3 ml-3 mr-2">
<div class="search-box flex-fill mr-sm-2 my-3 m-sm-0 p-3 p-sm-0">
<div class="filtered-search-box mb-0">
<gl-dropdown
:text="__('Recent searches')"
class="filtered-search-history-dropdown-wrapper d-none d-md-block"
class="filtered-search-history-dropdown-wrapper"
toggle-class="filtered-search-history-dropdown-toggle-button"
:disabled="loading"
>
......@@ -166,12 +190,12 @@ export default {
v-for="searchQuery in recentSearches"
:key="searchQuery"
@click="setSearchText(searchQuery)"
>{{ searchQuery }}</gl-dropdown-item
>
>{{ searchQuery }}
</gl-dropdown-item>
<gl-dropdown-divider />
<gl-dropdown-item ref="clearRecentSearches" @click="clearRecentSearches">{{
__('Clear recent searches')
}}</gl-dropdown-item>
<gl-dropdown-item ref="clearRecentSearches" @click="clearRecentSearches"
>{{ __('Clear recent searches') }}
</gl-dropdown-item>
</template>
<div v-else class="px-3">{{ __("You don't have any recent searches") }}</div>
</gl-dropdown>
......@@ -198,12 +222,13 @@ export default {
</gl-button>
</div>
</div>
</div>
<gl-dropdown
class="sort-control"
:text="$options.sortFields[sortField]"
left
:disabled="loading"
class="mr-3"
menu-class="sort-dropdown"
>
<gl-dropdown-item
......@@ -227,51 +252,65 @@ export default {
<gl-loading-icon size="md" />
</div>
<template v-else>
<h4 class="d-block d-sm-none my-3">{{ __('Open errors') }}</h4>
<gl-table
v-else
class="mt-3"
:items="errors"
:fields="$options.fields"
:show-empty="true"
fixed
stacked="sm"
tbody-tr-class="table-row mb-4"
>
<template slot="HEAD_events" slot-scope="data">
<div class="text-md-right">{{ data.label }}</div>
<template v-slot:head(error)>
<div class="d-none d-sm-block">{{ __('Open errors') }}</div>
</template>
<template v-slot:head(events)="data">
<div class="text-sm-right">{{ data.label }}</div>
</template>
<template slot="HEAD_users" slot-scope="data">
<div class="text-md-right">{{ data.label }}</div>
<template v-slot:head(users)="data">
<div class="text-sm-right">{{ data.label }}</div>
</template>
<template slot="error" slot-scope="errors">
<template v-slot:error="errors">
<div class="d-flex flex-column">
<gl-link class="d-flex text-dark" :href="getDetailsLink(errors.item.id)">
<gl-link class="d-flex mw-100 text-dark" :href="getDetailsLink(errors.item.id)">
<strong class="text-truncate">{{ errors.item.title.trim() }}</strong>
</gl-link>
<span class="text-secondary text-truncate">
<span class="text-secondary text-truncate mw-100">
{{ errors.item.culprit }}
</span>
</div>
</template>
<template slot="events" slot-scope="errors">
<div class="text-md-right">{{ errors.item.count }}</div>
<template v-slot:events="errors">
<div class="text-right">{{ errors.item.count }}</div>
</template>
<template slot="users" slot-scope="errors">
<div class="text-md-right">{{ errors.item.userCount }}</div>
<template v-slot:users="errors">
<div class="text-right">{{ errors.item.userCount }}</div>
</template>
<template slot="lastSeen" slot-scope="errors">
<div class="d-flex align-items-center">
<template v-slot:lastSeen="errors">
<div class="text-md-left text-right">
<time-ago :time="errors.item.lastSeen" class="text-secondary" />
</div>
</template>
<template slot="empty">
<div ref="empty">
<template v-slot:details="errors">
<gl-button
:href="getDetailsLink(errors.item.id)"
variant="outline-info"
class="d-block"
>
{{ __('More details') }}
</gl-button>
</template>
<template v-slot:empty>
{{ __('No errors to display.') }}
<gl-link class="js-try-again" @click="restartPolling">
{{ __('Check again') }}
</gl-link>
</div>
</template>
</gl-table>
<gl-pagination
......@@ -283,6 +322,7 @@ export default {
align="center"
@input="goToPage"
/>
</template>
</div>
<div v-else-if="userCanEnableErrorTracking">
<gl-empty-state
......
$gray-border: 1px solid $border-color;
.error-list {
.sort-control {
.btn {
padding-right: 2rem;
}
.gl-dropdown-caret {
position: absolute;
right: 0.5rem;
top: 0.5rem;
}
}
@include media-breakpoint-up(sm) {
.row-top {
border: $gray-border;
background-color: $gray-50;
}
}
@include media-breakpoint-down(xs) {
.table-row {
border: $gray-border;
border-radius: 4px;
}
.search-box {
border-top: $gray-border;
border-bottom: $gray-border;
background-color: $gray-50;
}
.table-col {
min-height: 68px;
&::before {
text-align: left !important;
}
&:first-child {
div {
padding: 0 !important;
align-items: flex-end;
}
}
&:last-child {
height: 64px;
background-color: $gray-normal;
&::before {
content: none !important;
}
div {
width: 100% !important;
padding: 0 !important;
a {
color: $blue-500;
border-color: $blue-500;
}
}
}
}
}
}
---
title: Improve error list UI on mobile viewports
merge_request: 21192
author:
type: added
......@@ -11548,6 +11548,9 @@ msgstr ""
msgid "More actions"
msgstr ""
msgid "More details"
msgstr ""
msgid "More info"
msgstr ""
......
......@@ -272,6 +272,7 @@ describe('ErrorTrackingList', () => {
describe('When pagination is not required', () => {
beforeEach(() => {
store.state.list.loading = false;
store.state.list.pagination = {};
mountComponent();
});
......@@ -284,6 +285,7 @@ describe('ErrorTrackingList', () => {
describe('When pagination is required', () => {
describe('and the user is on the first page', () => {
beforeEach(() => {
store.state.list.loading = false;
mountComponent({ sync: false });
});
......@@ -295,6 +297,7 @@ describe('ErrorTrackingList', () => {
describe('and the user is not on the first page', () => {
describe('and the previous button is clicked', () => {
beforeEach(() => {
store.state.list.loading = false;
mountComponent({ sync: false });
wrapper.setData({ pageValue: 2 });
});
......@@ -313,6 +316,7 @@ describe('ErrorTrackingList', () => {
describe('and the next page button is clicked', () => {
beforeEach(() => {
store.state.list.loading = false;
mountComponent({ sync: false });
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment