Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/commit/image_file.js3
-rw-r--r--app/assets/javascripts/due_date_select.js4
-rw-r--r--app/assets/javascripts/error_tracking/components/error_tracking_list.vue238
-rw-r--r--app/assets/javascripts/filterable_list.js2
-rw-r--r--app/assets/javascripts/labels_select.js5
-rw-r--r--app/assets/javascripts/main.js1
-rw-r--r--app/assets/javascripts/milestone_select.js7
-rw-r--r--app/assets/javascripts/notes/components/comment_form.vue1
-rw-r--r--app/assets/javascripts/users_select.js3
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/field.vue20
-rw-r--r--app/assets/stylesheets/pages/error_list.scss69
11 files changed, 253 insertions, 100 deletions
diff --git a/app/assets/javascripts/commit/image_file.js b/app/assets/javascripts/commit/image_file.js
index a28e17f7a56..fb8b1c17407 100644
--- a/app/assets/javascripts/commit/image_file.js
+++ b/app/assets/javascripts/commit/image_file.js
@@ -40,7 +40,10 @@ export default class ImageFile {
.removeClass('active')
.filter(`.${viewMode}`)
.addClass('active');
+
+ // eslint-disable-next-line no-jquery/no-fade
return $(`.view:visible:not(.${viewMode})`, this.file).fadeOut(200, () => {
+ // eslint-disable-next-line no-jquery/no-fade
$(`.view.${viewMode}`, this.file).fadeIn(200);
return this.initView(viewMode);
});
diff --git a/app/assets/javascripts/due_date_select.js b/app/assets/javascripts/due_date_select.js
index 3c650397a19..b973316b3b9 100644
--- a/app/assets/javascripts/due_date_select.js
+++ b/app/assets/javascripts/due_date_select.js
@@ -116,11 +116,13 @@ class DueDateSelect {
}
updateIssueBoardIssue() {
+ // eslint-disable-next-line no-jquery/no-fade
this.$loading.fadeIn();
this.$dropdown.trigger('loading.gl.dropdown');
this.$selectbox.hide();
this.$value.css('display', '');
const fadeOutLoader = () => {
+ // eslint-disable-next-line no-jquery/no-fade
this.$loading.fadeOut();
};
@@ -135,6 +137,7 @@ class DueDateSelect {
const hasDueDate = this.displayedDate !== __('None');
const displayedDateStyle = hasDueDate ? 'bold' : 'no-value';
+ // eslint-disable-next-line no-jquery/no-fade
this.$loading.removeClass('hidden').fadeIn();
if (isDropdown) {
@@ -158,6 +161,7 @@ class DueDateSelect {
}
this.$sidebarCollapsedValue.attr('data-original-title', tooltipText);
+ // eslint-disable-next-line no-jquery/no-fade
return this.$loading.fadeOut();
});
}
diff --git a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
index 8e2128ac713..1042029b6db 100644
--- a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
+++ b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
@@ -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,61 +172,63 @@ 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">
- <gl-dropdown
- :text="__('Recent searches')"
- class="filtered-search-history-dropdown-wrapper d-none d-md-block"
- toggle-class="filtered-search-history-dropdown-toggle-button"
- :disabled="loading"
- >
- <div v-if="!$options.hasLocalStorage" class="px-3">
- {{ __('This feature requires local storage to be enabled') }}
- </div>
- <template v-else-if="recentSearches.length > 0">
- <gl-dropdown-item
- v-for="searchQuery in recentSearches"
- :key="searchQuery"
- @click="setSearchText(searchQuery)"
- >{{ searchQuery }}</gl-dropdown-item
- >
- <gl-dropdown-divider />
- <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>
- <div class="filtered-search-input-container flex-fill">
- <gl-form-input
- v-model="errorSearchQuery"
- class="pl-2 filtered-search"
+ <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"
+ toggle-class="filtered-search-history-dropdown-toggle-button"
:disabled="loading"
- :placeholder="__('Search or filter results…')"
- autofocus
- @keyup.enter.native="searchByQuery(errorSearchQuery)"
- />
- </div>
- <div class="gl-search-box-by-type-right-icons">
- <gl-button
- v-if="errorSearchQuery.length > 0"
- v-gl-tooltip.hover
- :title="__('Clear')"
- class="clear-search text-secondary"
- name="clear"
- @click="errorSearchQuery = ''"
>
- <gl-icon name="close" :size="12" />
- </gl-button>
+ <div v-if="!$options.hasLocalStorage" class="px-3">
+ {{ __('This feature requires local storage to be enabled') }}
+ </div>
+ <template v-else-if="recentSearches.length > 0">
+ <gl-dropdown-item
+ v-for="searchQuery in recentSearches"
+ :key="searchQuery"
+ @click="setSearchText(searchQuery)"
+ >{{ searchQuery }}
+ </gl-dropdown-item>
+ <gl-dropdown-divider />
+ <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>
+ <div class="filtered-search-input-container flex-fill">
+ <gl-form-input
+ v-model="errorSearchQuery"
+ class="pl-2 filtered-search"
+ :disabled="loading"
+ :placeholder="__('Search or filter results…')"
+ autofocus
+ @keyup.enter.native="searchByQuery(errorSearchQuery)"
+ />
+ </div>
+ <div class="gl-search-box-by-type-right-icons">
+ <gl-button
+ v-if="errorSearchQuery.length > 0"
+ v-gl-tooltip.hover
+ :title="__('Clear')"
+ class="clear-search text-secondary"
+ name="clear"
+ @click="errorSearchQuery = ''"
+ >
+ <gl-icon name="close" :size="12" />
+ </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,62 +252,77 @@ export default {
<gl-loading-icon size="md" />
</div>
- <gl-table
- v-else
- class="mt-3"
- :items="errors"
- :fields="$options.fields"
- :show-empty="true"
- fixed
- stacked="sm"
- >
- <template slot="HEAD_events" slot-scope="data">
- <div class="text-md-right">{{ data.label }}</div>
- </template>
- <template slot="HEAD_users" slot-scope="data">
- <div class="text-md-right">{{ data.label }}</div>
- </template>
- <template slot="error" slot-scope="errors">
- <div class="d-flex flex-column">
- <gl-link class="d-flex text-dark" :href="getDetailsLink(errors.item.id)">
- <strong class="text-truncate">{{ errors.item.title.trim() }}</strong>
- </gl-link>
- <span class="text-secondary text-truncate">
- {{ errors.item.culprit }}
- </span>
- </div>
- </template>
- <template slot="events" slot-scope="errors">
- <div class="text-md-right">{{ errors.item.count }}</div>
- </template>
+ <template v-else>
+ <h4 class="d-block d-sm-none my-3">{{ __('Open errors') }}</h4>
- <template slot="users" slot-scope="errors">
- <div class="text-md-right">{{ errors.item.userCount }}</div>
- </template>
+ <gl-table
+ class="mt-3"
+ :items="errors"
+ :fields="$options.fields"
+ :show-empty="true"
+ fixed
+ stacked="sm"
+ tbody-tr-class="table-row mb-4"
+ >
+ <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 v-slot:head(users)="data">
+ <div class="text-sm-right">{{ data.label }}</div>
+ </template>
- <template slot="lastSeen" slot-scope="errors">
- <div class="d-flex align-items-center">
- <time-ago :time="errors.item.lastSeen" class="text-secondary" />
- </div>
- </template>
- <template slot="empty">
- <div ref="empty">
+ <template v-slot:error="errors">
+ <div class="d-flex flex-column">
+ <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 mw-100">
+ {{ errors.item.culprit }}
+ </span>
+ </div>
+ </template>
+ <template v-slot:events="errors">
+ <div class="text-right">{{ errors.item.count }}</div>
+ </template>
+
+ <template v-slot:users="errors">
+ <div class="text-right">{{ errors.item.userCount }}</div>
+ </template>
+
+ <template v-slot:lastSeen="errors">
+ <div class="text-md-left text-right">
+ <time-ago :time="errors.item.lastSeen" class="text-secondary" />
+ </div>
+ </template>
+ <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
- v-show="!loading"
- v-if="paginationRequired"
- :prev-page="$options.PREV_PAGE"
- :next-page="$options.NEXT_PAGE"
- :value="pageValue"
- align="center"
- @input="goToPage"
- />
+ </template>
+ </gl-table>
+ <gl-pagination
+ v-show="!loading"
+ v-if="paginationRequired"
+ :prev-page="$options.PREV_PAGE"
+ :next-page="$options.NEXT_PAGE"
+ :value="pageValue"
+ align="center"
+ @input="goToPage"
+ />
+ </template>
</div>
<div v-else-if="userCanEnableErrorTracking">
<gl-empty-state
diff --git a/app/assets/javascripts/filterable_list.js b/app/assets/javascripts/filterable_list.js
index c21fba06d42..be2eee828ff 100644
--- a/app/assets/javascripts/filterable_list.js
+++ b/app/assets/javascripts/filterable_list.js
@@ -64,6 +64,7 @@ export default class FilterableList {
return false;
}
+ // eslint-disable-next-line no-jquery/no-fade
$(this.listHolderElement).fadeTo(250, 0.5);
this.isBusy = true;
@@ -98,6 +99,7 @@ export default class FilterableList {
onFilterComplete() {
this.isBusy = false;
+ // eslint-disable-next-line no-jquery/no-fade
$(this.listHolderElement).fadeTo(250, 1);
}
}
diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js
index 6abf723be9a..f57febbda37 100644
--- a/app/assets/javascripts/labels_select.js
+++ b/app/assets/javascripts/labels_select.js
@@ -45,6 +45,7 @@ export default class LabelsSelect {
const $sidebarLabelTooltip = $block.find('.js-sidebar-labels-tooltip');
const $value = $block.find('.value');
const $dropdownMenu = $dropdown.parent().find('.dropdown-menu');
+ // eslint-disable-next-line no-jquery/no-fade
const $loading = $block.find('.block-loading').fadeOut();
const fieldName = $dropdown.data('fieldName');
let initialSelected = $selectbox
@@ -84,6 +85,7 @@ export default class LabelsSelect {
if (!selected.length) {
data[abilityName].label_ids = [''];
}
+ // eslint-disable-next-line no-jquery/no-fade
$loading.removeClass('hidden').fadeIn();
$dropdown.trigger('loading.gl.dropdown');
axios
@@ -91,6 +93,7 @@ export default class LabelsSelect {
.then(({ data }) => {
let labelTooltipTitle;
let template;
+ // eslint-disable-next-line no-jquery/no-fade
$loading.fadeOut();
$dropdown.trigger('loaded.gl.dropdown');
$selectbox.hide();
@@ -361,6 +364,7 @@ export default class LabelsSelect {
const label = clickEvent.selectedObj;
const fadeOutLoader = () => {
+ // eslint-disable-next-line no-jquery/no-fade
$loading.fadeOut();
};
@@ -422,6 +426,7 @@ export default class LabelsSelect {
boardsStore.detail.issue.labels = labels;
}
+ // eslint-disable-next-line no-jquery/no-fade
$loading.fadeIn();
const oldLabels = boardsStore.detail.issue.labels;
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 674415c9d01..8373ddd7a43 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -113,6 +113,7 @@ function deferredInitialisation() {
});
$('.js-remove-tr').on('ajax:success', function removeTRAjaxSuccessCallback() {
+ // eslint-disable-next-line no-jquery/no-fade
$(this)
.closest('tr')
.fadeOut();
diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js
index 1738dbe439c..d15e4ecb537 100644
--- a/app/assets/javascripts/milestone_select.js
+++ b/app/assets/javascripts/milestone_select.js
@@ -52,6 +52,7 @@ export default class MilestoneSelect {
const $block = $selectBox.closest('.block');
const $sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon');
const $value = $block.find('.value');
+ // eslint-disable-next-line no-jquery/no-fade
const $loading = $block.find('.block-loading').fadeOut();
selectedMilestoneDefault = showAny ? '' : null;
selectedMilestoneDefault =
@@ -202,15 +203,18 @@ export default class MilestoneSelect {
}
$dropdown.trigger('loading.gl.dropdown');
+ // eslint-disable-next-line no-jquery/no-fade
$loading.removeClass('hidden').fadeIn();
boardsStore.detail.issue
.update($dropdown.attr('data-issue-update'))
.then(() => {
$dropdown.trigger('loaded.gl.dropdown');
+ // eslint-disable-next-line no-jquery/no-fade
$loading.fadeOut();
})
.catch(() => {
+ // eslint-disable-next-line no-jquery/no-fade
$loading.fadeOut();
});
} else {
@@ -218,12 +222,14 @@ export default class MilestoneSelect {
data = {};
data[abilityName] = {};
data[abilityName].milestone_id = selected != null ? selected : null;
+ // eslint-disable-next-line no-jquery/no-fade
$loading.removeClass('hidden').fadeIn();
$dropdown.trigger('loading.gl.dropdown');
return axios
.put(issueUpdateURL, data)
.then(({ data }) => {
$dropdown.trigger('loaded.gl.dropdown');
+ // eslint-disable-next-line no-jquery/no-fade
$loading.fadeOut();
$selectBox.hide();
$value.css('display', '');
@@ -247,6 +253,7 @@ export default class MilestoneSelect {
}
})
.catch(() => {
+ // eslint-disable-next-line no-jquery/no-fade
$loading.fadeOut();
});
}
diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue
index 492d8de3802..4ca32b9b005 100644
--- a/app/assets/javascripts/notes/components/comment_form.vue
+++ b/app/assets/javascripts/notes/components/comment_form.vue
@@ -336,6 +336,7 @@ export default {
<markdown-field
ref="markdownField"
+ :is-submitting="isSubmitting"
:markdown-preview-path="markdownPreviewPath"
:markdown-docs-path="markdownDocsPath"
:quick-actions-docs-path="quickActionsDocsPath"
diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js
index bf2880aca9c..6d7d863f273 100644
--- a/app/assets/javascripts/users_select.js
+++ b/app/assets/javascripts/users_select.js
@@ -53,6 +53,7 @@ function UsersSelect(currentUser, els, options = {}) {
const abilityName = $dropdown.data('abilityName');
let $value = $block.find('.value');
const $collapsedSidebar = $block.find('.sidebar-collapsed-user');
+ // eslint-disable-next-line no-jquery/no-fade
const $loading = $block.find('.block-loading').fadeOut();
const selectedIdDefault = defaultNullUser && showNullUser ? 0 : null;
let selectedId = $dropdown.data('selected');
@@ -188,6 +189,7 @@ function UsersSelect(currentUser, els, options = {}) {
const data = {};
data[abilityName] = {};
data[abilityName].assignee_id = selected != null ? selected : null;
+ // eslint-disable-next-line no-jquery/no-fade
$loading.removeClass('hidden').fadeIn();
$dropdown.trigger('loading.gl.dropdown');
@@ -195,6 +197,7 @@ function UsersSelect(currentUser, els, options = {}) {
let user = {};
let tooltipTitle = user.name;
$dropdown.trigger('loaded.gl.dropdown');
+ // eslint-disable-next-line no-jquery/no-fade
$loading.fadeOut();
if (data.assignee) {
user = {
diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue
index 326440f5013..4f5f3ee5cf9 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/field.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue
@@ -20,6 +20,11 @@ export default {
Suggestions,
},
props: {
+ isSubmitting: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
markdownPreviewPath: {
type: String,
required: false,
@@ -133,6 +138,20 @@ export default {
);
},
},
+ watch: {
+ isSubmitting(isSubmitting) {
+ if (!isSubmitting || !this.$refs['markdown-preview'].querySelectorAll) {
+ return;
+ }
+ const mediaInPreview = this.$refs['markdown-preview'].querySelectorAll('video, audio');
+
+ if (mediaInPreview) {
+ mediaInPreview.forEach(media => {
+ media.pause();
+ });
+ }
+ },
+ },
mounted() {
/*
GLForm class handles all the toolbar buttons
@@ -177,7 +196,6 @@ export default {
this.renderMarkdown();
}
},
-
showWriteTab() {
this.markdownPreview = '';
this.previewMarkdown = false;
diff --git a/app/assets/stylesheets/pages/error_list.scss b/app/assets/stylesheets/pages/error_list.scss
new file mode 100644
index 00000000000..f97953ce824
--- /dev/null
+++ b/app/assets/stylesheets/pages/error_list.scss
@@ -0,0 +1,69 @@
+$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;
+ }
+ }
+ }
+ }
+ }
+}