summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/api.js14
-rw-r--r--app/assets/javascripts/awards_handler.js8
-rw-r--r--app/assets/javascripts/badges/components/badge.vue6
-rw-r--r--app/assets/javascripts/badges/components/badge_form.vue4
-rw-r--r--app/assets/javascripts/badges/components/badge_list.vue10
-rw-r--r--app/assets/javascripts/behaviors/copy_to_clipboard.js4
-rw-r--r--app/assets/javascripts/behaviors/quick_submit.js2
-rw-r--r--app/assets/javascripts/behaviors/requires_input.js4
-rw-r--r--app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js6
-rw-r--r--app/assets/javascripts/blob/sketch/index.js2
-rw-r--r--app/assets/javascripts/blob/viewer/index.js2
-rw-r--r--app/assets/javascripts/boards/components/board_card.vue2
-rw-r--r--app/assets/javascripts/boards/components/board_new_issue.vue6
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.js12
-rw-r--r--app/assets/javascripts/boards/components/modal/empty_state.js4
-rw-r--r--app/assets/javascripts/boards/components/modal/footer.js4
-rw-r--r--app/assets/javascripts/boards/components/modal/list.js13
-rw-r--r--app/assets/javascripts/boards/components/modal/tabs.js4
-rw-r--r--app/assets/javascripts/boards/components/project_select.vue112
-rw-r--r--app/assets/javascripts/boards/index.js2
-rw-r--r--app/assets/javascripts/ci_variable_list/ci_variable_list.js5
-rw-r--r--app/assets/javascripts/clusters/components/applications.vue4
-rw-r--r--app/assets/javascripts/commons/bootstrap.js10
-rw-r--r--app/assets/javascripts/compare_autocomplete.js4
-rw-r--r--app/assets/javascripts/create_merge_request_dropdown.js10
-rw-r--r--app/assets/javascripts/cycle_analytics/components/limit_warning_component.vue2
-rw-r--r--app/assets/javascripts/diff_notes/components/diff_note_avatars.js4
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_btn.js2
-rw-r--r--app/assets/javascripts/environments/components/environment_actions.vue2
-rw-r--r--app/assets/javascripts/environments/components/environment_item.vue6
-rw-r--r--app/assets/javascripts/environments/components/environment_monitoring.vue2
-rw-r--r--app/assets/javascripts/environments/components/environment_rollback.vue2
-rw-r--r--app/assets/javascripts/environments/components/environment_stop.vue4
-rw-r--r--app/assets/javascripts/environments/components/environment_terminal_button.vue2
-rw-r--r--app/assets/javascripts/feature_highlight/feature_highlight.js2
-rw-r--r--app/assets/javascripts/gl_dropdown.js4
-rw-r--r--app/assets/javascripts/gl_field_error.js10
-rw-r--r--app/assets/javascripts/groups/components/group_item.vue2
-rw-r--r--app/assets/javascripts/ide/components/changed_file_icon.vue2
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/form.vue6
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/list.vue2
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/message_field.vue2
-rw-r--r--app/assets/javascripts/ide/components/external_link.vue41
-rw-r--r--app/assets/javascripts/ide/components/ide.vue8
-rw-r--r--app/assets/javascripts/ide/components/ide_file_buttons.vue84
-rw-r--r--app/assets/javascripts/ide/components/ide_status_bar.vue37
-rw-r--r--app/assets/javascripts/ide/components/new_dropdown/index.vue6
-rw-r--r--app/assets/javascripts/ide/components/new_dropdown/modal.vue26
-rw-r--r--app/assets/javascripts/ide/components/repo_editor.vue8
-rw-r--r--app/assets/javascripts/ide/components/repo_file.vue6
-rw-r--r--app/assets/javascripts/ide/components/repo_loading_file.vue4
-rw-r--r--app/assets/javascripts/ide/lib/common/model.js1
-rw-r--r--app/assets/javascripts/ide/services/index.js4
-rw-r--r--app/assets/javascripts/ide/stores/actions/file.js6
-rw-r--r--app/assets/javascripts/ide/stores/actions/merge_request.js6
-rw-r--r--app/assets/javascripts/ide/stores/actions/project.js106
-rw-r--r--app/assets/javascripts/ide/stores/actions/tree.js6
-rw-r--r--app/assets/javascripts/ide/stores/modules/commit/actions.js11
-rw-r--r--app/assets/javascripts/ide/stores/mutation_types.js1
-rw-r--r--app/assets/javascripts/ide/stores/mutations/branch.js9
-rw-r--r--app/assets/javascripts/issuable_form.js2
-rw-r--r--app/assets/javascripts/issue_show/components/edit_actions.vue6
-rw-r--r--app/assets/javascripts/issue_show/components/form.vue2
-rw-r--r--app/assets/javascripts/job.js13
-rw-r--r--app/assets/javascripts/jobs/components/header.vue2
-rw-r--r--app/assets/javascripts/jobs/components/sidebar_detail_row.vue2
-rw-r--r--app/assets/javascripts/jobs/components/sidebar_details_block.vue10
-rw-r--r--app/assets/javascripts/jobs/job_details_mediator.js5
-rw-r--r--app/assets/javascripts/label_manager.js2
-rw-r--r--app/assets/javascripts/labels_select.js2
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js2
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js3
-rw-r--r--app/assets/javascripts/locale/index.js6
-rw-r--r--app/assets/javascripts/locale/sprintf.js2
-rw-r--r--app/assets/javascripts/main.js10
-rw-r--r--app/assets/javascripts/merge_request_tabs.js4
-rw-r--r--app/assets/javascripts/monitoring/components/graph_group.vue6
-rw-r--r--app/assets/javascripts/notes.js8
-rw-r--r--app/assets/javascripts/notes/components/comment_form.vue5
-rw-r--r--app/assets/javascripts/notes/components/noteable_discussion.vue4
-rw-r--r--app/assets/javascripts/notes/stores/actions.js69
-rw-r--r--app/assets/javascripts/notifications_form.js2
-rw-r--r--app/assets/javascripts/pages/admin/admin.js2
-rw-r--r--app/assets/javascripts/pages/groups/edit/index.js6
-rw-r--r--app/assets/javascripts/pages/profiles/two_factor_auths/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/clusters/gcp/new/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/project_setting_row.vue2
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue2
-rw-r--r--app/assets/javascripts/pages/projects/wikis/wikis.js9
-rw-r--r--app/assets/javascripts/pages/sessions/new/oauth_remember_me.js2
-rw-r--r--app/assets/javascripts/pages/users/user_tabs.js33
-rw-r--r--app/assets/javascripts/performance_bar/components/request_selector.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/blank_state.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/empty_state.vue6
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_component.vue1
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_url.vue12
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_actions.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_artifacts.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_table_row.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/time_ago.vue2
-rw-r--r--app/assets/javascripts/profile/account/components/update_username.vue8
-rw-r--r--app/assets/javascripts/project_fork.js2
-rw-r--r--app/assets/javascripts/project_label_subscription.js2
-rw-r--r--app/assets/javascripts/project_visibility.js2
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_dropdown_mixin.js71
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown.vue142
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown.vue201
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown.vue116
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/constants.js11
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/index.js88
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/store/actions.js95
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/store/getters.js3
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/store/index.js18
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/store/mutation_types.js8
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/store/mutations.js28
-rw-r--r--app/assets/javascripts/projects/gke_cluster_dropdowns/store/state.js13
-rw-r--r--app/assets/javascripts/projects/project_new.js4
-rw-r--r--app/assets/javascripts/projects_dropdown/components/search.vue2
-rw-r--r--app/assets/javascripts/prometheus_metrics/prometheus_metrics.js2
-rw-r--r--app/assets/javascripts/raven/raven_config.js2
-rw-r--r--app/assets/javascripts/registry/components/collapsible_container.vue2
-rw-r--r--app/assets/javascripts/registry/components/table_registry.vue2
-rw-r--r--app/assets/javascripts/registry/stores/actions.js20
-rw-r--r--app/assets/javascripts/right_sidebar.js2
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/assignee_title.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/assignees.vue1
-rw-r--r--app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/confidential/edit_form.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/lock/edit_form.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/participants/participants.vue1
-rw-r--r--app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue5
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue1
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue4
-rw-r--r--app/assets/javascripts/users_select.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/deployment.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue12
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue74
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue21
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js5
-rw-r--r--app/assets/javascripts/vue_shared/components/content_viewer/viewers/download_viewer.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/deprecated_modal.vue8
-rw-r--r--app/assets/javascripts/vue_shared/components/dropdown/dropdown_button.vue55
-rw-r--r--app/assets/javascripts/vue_shared/components/dropdown/dropdown_hidden_input.vue (renamed from app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_hidden_input.vue)6
-rw-r--r--app/assets/javascripts/vue_shared/components/dropdown/dropdown_search_input.vue46
-rw-r--r--app/assets/javascripts/vue_shared/components/gl_modal.vue10
-rw-r--r--app/assets/javascripts/vue_shared/components/header_ci_component.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/toolbar.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/navigation_tabs.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title.vue2
-rw-r--r--app/assets/javascripts/vue_shared/directives/popover.js2
-rw-r--r--app/assets/javascripts/vue_shared/directives/tooltip.js4
-rw-r--r--app/assets/javascripts/vue_shared/translate.js6
-rw-r--r--app/assets/stylesheets/bootstrap_migration.scss163
-rw-r--r--app/assets/stylesheets/framework.scss4
-rw-r--r--app/assets/stylesheets/framework/avatar.scss2
-rw-r--r--app/assets/stylesheets/framework/badges.scss2
-rw-r--r--app/assets/stylesheets/framework/banner.scss2
-rw-r--r--app/assets/stylesheets/framework/blank.scss8
-rw-r--r--app/assets/stylesheets/framework/blocks.scss8
-rw-r--r--app/assets/stylesheets/framework/broadcast_messages.scss6
-rw-r--r--app/assets/stylesheets/framework/buttons.scss5
-rw-r--r--app/assets/stylesheets/framework/calendar.scss2
-rw-r--r--app/assets/stylesheets/framework/ci_variable_list.scss12
-rw-r--r--app/assets/stylesheets/framework/common.scss10
-rw-r--r--app/assets/stylesheets/framework/contextual_sidebar.scss30
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss32
-rw-r--r--app/assets/stylesheets/framework/feature_highlight.scss2
-rw-r--r--app/assets/stylesheets/framework/files.scss6
-rw-r--r--app/assets/stylesheets/framework/filters.scss20
-rw-r--r--app/assets/stylesheets/framework/flash.scss14
-rw-r--r--app/assets/stylesheets/framework/forms.scss35
-rw-r--r--app/assets/stylesheets/framework/gitlab_theme.scss23
-rw-r--r--app/assets/stylesheets/framework/header.scss37
-rw-r--r--app/assets/stylesheets/framework/issue_box.scss2
-rw-r--r--app/assets/stylesheets/framework/layout.scss4
-rw-r--r--app/assets/stylesheets/framework/lists.scss12
-rw-r--r--app/assets/stylesheets/framework/markdown_area.scss8
-rw-r--r--app/assets/stylesheets/framework/mobile.scss6
-rw-r--r--app/assets/stylesheets/framework/modal.scss12
-rw-r--r--app/assets/stylesheets/framework/page_header.scss6
-rw-r--r--app/assets/stylesheets/framework/pagination.scss13
-rw-r--r--app/assets/stylesheets/framework/panels.scss17
-rw-r--r--app/assets/stylesheets/framework/responsive_tables.scss22
-rw-r--r--app/assets/stylesheets/framework/secondary_navigation_elements.scss23
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss6
-rw-r--r--app/assets/stylesheets/framework/snippets.scss2
-rw-r--r--app/assets/stylesheets/framework/tables.scss2
-rw-r--r--app/assets/stylesheets/framework/tabs.scss1
-rw-r--r--app/assets/stylesheets/framework/timeline.scss4
-rw-r--r--app/assets/stylesheets/framework/toggle.scss2
-rw-r--r--app/assets/stylesheets/framework/tw_bootstrap.scss201
-rw-r--r--app/assets/stylesheets/framework/tw_bootstrap_variables.scss199
-rw-r--r--app/assets/stylesheets/framework/typography.scss18
-rw-r--r--app/assets/stylesheets/framework/variables.scss12
-rw-r--r--app/assets/stylesheets/framework/wells.scss6
-rw-r--r--app/assets/stylesheets/mailers/highlighted_diff_email.scss2
-rw-r--r--app/assets/stylesheets/pages/boards.scss42
-rw-r--r--app/assets/stylesheets/pages/builds.scss10
-rw-r--r--app/assets/stylesheets/pages/clusters.scss2
-rw-r--r--app/assets/stylesheets/pages/commits.scss8
-rw-r--r--app/assets/stylesheets/pages/convdev_index.scss28
-rw-r--r--app/assets/stylesheets/pages/cycle_analytics.scss16
-rw-r--r--app/assets/stylesheets/pages/detail_page.scss6
-rw-r--r--app/assets/stylesheets/pages/diff.scss42
-rw-r--r--app/assets/stylesheets/pages/editor.scss24
-rw-r--r--app/assets/stylesheets/pages/environments.scss8
-rw-r--r--app/assets/stylesheets/pages/events.scss4
-rw-r--r--app/assets/stylesheets/pages/groups.scss14
-rw-r--r--app/assets/stylesheets/pages/help.scss4
-rw-r--r--app/assets/stylesheets/pages/issuable.scss14
-rw-r--r--app/assets/stylesheets/pages/issues.scss10
-rw-r--r--app/assets/stylesheets/pages/labels.scss19
-rw-r--r--app/assets/stylesheets/pages/login.scss6
-rw-r--r--app/assets/stylesheets/pages/members.scss44
-rw-r--r--app/assets/stylesheets/pages/merge_conflicts.scss2
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss26
-rw-r--r--app/assets/stylesheets/pages/milestone.scss8
-rw-r--r--app/assets/stylesheets/pages/note_form.scss22
-rw-r--r--app/assets/stylesheets/pages/notes.scss26
-rw-r--r--app/assets/stylesheets/pages/notifications.scss2
-rw-r--r--app/assets/stylesheets/pages/pipeline_schedules.scss2
-rw-r--r--app/assets/stylesheets/pages/pipelines.scss120
-rw-r--r--app/assets/stylesheets/pages/profile.scss14
-rw-r--r--app/assets/stylesheets/pages/projects.scss72
-rw-r--r--app/assets/stylesheets/pages/repo.scss22
-rw-r--r--app/assets/stylesheets/pages/runners.scss2
-rw-r--r--app/assets/stylesheets/pages/search.scss11
-rw-r--r--app/assets/stylesheets/pages/settings.scss26
-rw-r--r--app/assets/stylesheets/pages/stat_graph.scss13
-rw-r--r--app/assets/stylesheets/pages/status.scss2
-rw-r--r--app/assets/stylesheets/pages/todos.scss12
-rw-r--r--app/assets/stylesheets/pages/tree.scss11
-rw-r--r--app/assets/stylesheets/pages/wiki.scss4
246 files changed, 2328 insertions, 1487 deletions
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js
index eb919241318..ce1069276ab 100644
--- a/app/assets/javascripts/api.js
+++ b/app/assets/javascripts/api.js
@@ -21,6 +21,7 @@ const Api = {
issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key',
usersPath: '/api/:version/users.json',
commitPath: '/api/:version/projects/:id/repository/commits',
+ commitPipelinesPath: '/:project_id/commit/:sha/pipelines',
branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch',
createBranchPath: '/api/:version/projects/:id/repository/branches',
pipelinesPath: '/api/:version/projects/:id/pipelines',
@@ -166,6 +167,19 @@ const Api = {
});
},
+ commitPipelines(projectId, sha) {
+ const encodedProjectId = projectId
+ .split('/')
+ .map(fragment => encodeURIComponent(fragment))
+ .join('/');
+
+ const url = Api.buildUrl(Api.commitPipelinesPath)
+ .replace(':project_id', encodedProjectId)
+ .replace(':sha', encodeURIComponent(sha));
+
+ return axios.get(url);
+ },
+
branchSingle(id, branch) {
const url = Api.buildUrl(Api.branchSinglePath)
.replace(':id', encodeURIComponent(id))
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
index 976d32abe9b..eb0f06efab4 100644
--- a/app/assets/javascripts/awards_handler.js
+++ b/app/assets/javascripts/awards_handler.js
@@ -345,7 +345,7 @@ class AwardsHandler {
counter.text(counterNumber - 1);
this.removeYouFromUserList($emojiButton);
} else if (emoji === 'thumbsup' || emoji === 'thumbsdown') {
- $emojiButton.tooltip('destroy');
+ $emojiButton.tooltip('dispose');
counter.text('0');
this.removeYouFromUserList($emojiButton);
if ($emojiButton.parents('.note').length) {
@@ -358,7 +358,7 @@ class AwardsHandler {
}
removeEmoji($emojiButton) {
- $emojiButton.tooltip('destroy');
+ $emojiButton.tooltip('dispose');
$emojiButton.remove();
const $votesBlock = this.getVotesBlock();
if ($votesBlock.find('.js-emoji-btn').length === 0) {
@@ -392,7 +392,7 @@ class AwardsHandler {
.removeAttr('data-title')
.removeAttr('data-original-title')
.attr('title', this.toSentence(authors))
- .tooltip('fixTitle');
+ .tooltip('_fixTitle');
}
addYouToUserList(votesBlock, emoji) {
@@ -405,7 +405,7 @@ class AwardsHandler {
users.unshift('You');
return awardBlock
.attr('title', this.toSentence(users))
- .tooltip('fixTitle');
+ .tooltip('_fixTitle');
}
createAwardButtonForVotesBlock(votesBlock, emojiName) {
diff --git a/app/assets/javascripts/badges/components/badge.vue b/app/assets/javascripts/badges/components/badge.vue
index 6e6cb31e3ac..d0f60e1d4cb 100644
--- a/app/assets/javascripts/badges/components/badge.vue
+++ b/app/assets/javascripts/badges/components/badge.vue
@@ -89,7 +89,7 @@ export default {
v-show="hasError"
class="btn-group"
>
- <div class="btn btn-default btn-xs disabled">
+ <div class="btn btn-default btn-sm disabled">
<icon
class="prepend-left-8 append-right-8"
name="doc_image"
@@ -98,7 +98,7 @@ export default {
/>
</div>
<div
- class="btn btn-default btn-xs disabled"
+ class="btn btn-default btn-sm disabled"
>
<span class="prepend-left-8 append-right-8">{{ s__('Badges|No badge image') }}</span>
</div>
@@ -106,7 +106,7 @@ export default {
<button
v-show="hasError"
- class="btn btn-transparent btn-xs text-primary"
+ class="btn btn-transparent btn-sm text-primary"
type="button"
v-tooltip
:title="s__('Badges|Reload badge image')"
diff --git a/app/assets/javascripts/badges/components/badge_form.vue b/app/assets/javascripts/badges/components/badge_form.vue
index ae942b2c1a7..5975cb9669e 100644
--- a/app/assets/javascripts/badges/components/badge_form.vue
+++ b/app/assets/javascripts/badges/components/badge_form.vue
@@ -160,7 +160,7 @@ export default {
@input="debouncedPreview"
/>
<span
- class="help-block"
+ class="form-text text-muted"
v-html="helpText"
></span>
</div>
@@ -176,7 +176,7 @@ export default {
@input="debouncedPreview"
/>
<span
- class="help-block"
+ class="form-text text-muted"
v-html="helpText"
></span>
</div>
diff --git a/app/assets/javascripts/badges/components/badge_list.vue b/app/assets/javascripts/badges/components/badge_list.vue
index ca7197e1e0f..268968b63b3 100644
--- a/app/assets/javascripts/badges/components/badge_list.vue
+++ b/app/assets/javascripts/badges/components/badge_list.vue
@@ -23,8 +23,8 @@ export default {
</script>
<template>
- <div class="panel panel-default">
- <div class="panel-heading">
+ <div class="card">
+ <div class="card-header">
{{ s__('Badges|Your badges') }}
<span
v-show="!isLoading"
@@ -33,19 +33,19 @@ export default {
</div>
<loading-icon
v-show="isLoading"
- class="panel-body"
+ class="card-body"
size="2"
/>
<div
v-if="hasNoBadges"
- class="panel-body"
+ class="card-body"
>
<span v-if="isGroupBadge">{{ s__('Badges|This group has no badges') }}</span>
<span v-else>{{ s__('Badges|This project has no badges') }}</span>
</div>
<div
v-else
- class="panel-body"
+ class="card-body"
>
<badge-list-row
v-for="badge in badges"
diff --git a/app/assets/javascripts/behaviors/copy_to_clipboard.js b/app/assets/javascripts/behaviors/copy_to_clipboard.js
index e2a73a1797c..75834ba351d 100644
--- a/app/assets/javascripts/behaviors/copy_to_clipboard.js
+++ b/app/assets/javascripts/behaviors/copy_to_clipboard.js
@@ -8,10 +8,10 @@ function showTooltip(target, title) {
if (!$target.data('hideTooltip')) {
$target
.attr('title', title)
- .tooltip('fixTitle')
+ .tooltip('_fixTitle')
.tooltip('show')
.attr('title', originalTitle)
- .tooltip('fixTitle');
+ .tooltip('_fixTitle');
}
}
diff --git a/app/assets/javascripts/behaviors/quick_submit.js b/app/assets/javascripts/behaviors/quick_submit.js
index 3ec932bdb73..b6e2781773c 100644
--- a/app/assets/javascripts/behaviors/quick_submit.js
+++ b/app/assets/javascripts/behaviors/quick_submit.js
@@ -69,7 +69,7 @@ $(document).on('keyup.quick_submit', '.js-quick-submit input[type=submit], .js-q
$this.tooltip({
container: 'body',
html: 'true',
- placement: 'auto top',
+ placement: 'top',
title,
trigger: 'manual',
});
diff --git a/app/assets/javascripts/behaviors/requires_input.js b/app/assets/javascripts/behaviors/requires_input.js
index ffff4ddb71a..a8b6dbf0948 100644
--- a/app/assets/javascripts/behaviors/requires_input.js
+++ b/app/assets/javascripts/behaviors/requires_input.js
@@ -42,9 +42,9 @@ $.fn.requiresInput = function requiresInput() {
function hideOrShowHelpBlock(form) {
const selected = $('.js-select-namespace option:selected');
if (selected.length && selected.data('optionsParent') === 'groups') {
- form.find('.help-block').hide();
+ form.find('.form-text.text-muted').hide();
} else if (selected.length) {
- form.find('.help-block').show();
+ form.find('.form-text.text-muted').show();
}
}
diff --git a/app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js b/app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js
index c17877a276d..766039404ce 100644
--- a/app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js
+++ b/app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js
@@ -2,9 +2,9 @@ import sqljs from 'sql.js';
import { template as _template } from 'underscore';
const PREVIEW_TEMPLATE = _template(`
- <div class="panel panel-default">
- <div class="panel-heading"><%- name %></div>
- <div class="panel-body">
+ <div class="card">
+ <div class="card-header"><%- name %></div>
+ <div class="card-body">
<img class="img-thumbnail" src="data:image/png;base64,<%- image %>"/>
</div>
</div>
diff --git a/app/assets/javascripts/blob/sketch/index.js b/app/assets/javascripts/blob/sketch/index.js
index 0799991aa40..13318c58006 100644
--- a/app/assets/javascripts/blob/sketch/index.js
+++ b/app/assets/javascripts/blob/sketch/index.js
@@ -44,7 +44,7 @@ export default class SketchLoader {
previewLink.href = previewUrl;
previewLink.target = '_blank';
previewImage.src = previewUrl;
- previewImage.className = 'img-responsive';
+ previewImage.className = 'img-fluid';
previewLink.appendChild(previewImage);
this.container.appendChild(previewLink);
diff --git a/app/assets/javascripts/blob/viewer/index.js b/app/assets/javascripts/blob/viewer/index.js
index 137e1f5a099..f61c0be9230 100644
--- a/app/assets/javascripts/blob/viewer/index.js
+++ b/app/assets/javascripts/blob/viewer/index.js
@@ -116,7 +116,7 @@ export default class BlobViewer {
this.copySourceBtn.classList.add('disabled');
}
- $(this.copySourceBtn).tooltip('fixTitle');
+ $(this.copySourceBtn).tooltip('_fixTitle');
}
switchToViewer(name) {
diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue
index 84885ca9306..33e3369b971 100644
--- a/app/assets/javascripts/boards/components/board_card.vue
+++ b/app/assets/javascripts/boards/components/board_card.vue
@@ -77,7 +77,7 @@ export default {
<template>
<li
- class="card"
+ class="board-card"
:class="{
'user-can-drag': !disabled && issue.id,
'is-disabled': disabled || !issue.id,
diff --git a/app/assets/javascripts/boards/components/board_new_issue.vue b/app/assets/javascripts/boards/components/board_new_issue.vue
index 8d84c1735b8..e8dfd95f7ae 100644
--- a/app/assets/javascripts/boards/components/board_new_issue.vue
+++ b/app/assets/javascripts/boards/components/board_new_issue.vue
@@ -92,7 +92,7 @@ export default {
<template>
<div class="board-new-issue-form">
- <div class="card">
+ <div class="board-card">
<form @submit="submit($event)">
<div
class="flash-container"
@@ -122,7 +122,7 @@ export default {
/>
<div class="clearfix prepend-top-10">
<button
- class="btn btn-success pull-left"
+ class="btn btn-success float-left"
type="submit"
:disabled="disabled"
ref="submit-button"
@@ -130,7 +130,7 @@ export default {
Submit issue
</button>
<button
- class="btn btn-default pull-right"
+ class="btn btn-default float-right"
type="button"
@click="cancel"
>
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.js b/app/assets/javascripts/boards/components/issue_card_inner.js
index 84fe9b1288a..dcc07810d01 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.js
+++ b/app/assets/javascripts/boards/components/issue_card_inner.js
@@ -135,8 +135,8 @@ gl.issueBoards.IssueCardInner = Vue.extend({
},
template: `
<div>
- <div class="card-header">
- <h4 class="card-title">
+ <div class="board-card-header">
+ <h4 class="board-card-title">
<i
class="fa fa-eye-slash confidential-icon"
v-if="issue.confidential"
@@ -147,13 +147,13 @@ gl.issueBoards.IssueCardInner = Vue.extend({
:href="issue.path"
:title="issue.title">{{ issue.title }}</a>
<span
- class="card-number"
+ class="board-card-number"
v-if="issueId"
>
{{ issue.referencePath }}
</span>
</h4>
- <div class="card-assignee">
+ <div class="board-card-assignee">
<user-avatar-link
v-for="(assignee, index) in issue.assignees"
:key="assignee.id"
@@ -175,11 +175,11 @@ gl.issueBoards.IssueCardInner = Vue.extend({
</div>
</div>
<div
- class="card-footer"
+ class="board-card-footer"
v-if="showLabelFooter"
>
<button
- class="label color-label has-tooltip"
+ class="badge color-label has-tooltip"
v-for="label in issue.labels"
type="button"
v-if="showLabel(label)"
diff --git a/app/assets/javascripts/boards/components/modal/empty_state.js b/app/assets/javascripts/boards/components/modal/empty_state.js
index 9e37f95cdd6..1e5f2383223 100644
--- a/app/assets/javascripts/boards/components/modal/empty_state.js
+++ b/app/assets/javascripts/boards/components/modal/empty_state.js
@@ -41,10 +41,10 @@ gl.issueBoards.ModalEmptyState = Vue.extend({
template: `
<section class="empty-state">
<div class="row">
- <div class="col-xs-12 col-sm-6 col-sm-push-6">
+ <div class="col-12 col-md-6 order-md-last">
<aside class="svg-content"><img :src="emptyStateSvg"/></aside>
</div>
- <div class="col-xs-12 col-sm-6 col-sm-pull-6">
+ <div class="col-12 col-md-6 order-md-first">
<div class="text-content">
<h4>{{ contents.title }}</h4>
<p v-html="contents.content"></p>
diff --git a/app/assets/javascripts/boards/components/modal/footer.js b/app/assets/javascripts/boards/components/modal/footer.js
index 9735e0ddacc..11bb3e98334 100644
--- a/app/assets/javascripts/boards/components/modal/footer.js
+++ b/app/assets/javascripts/boards/components/modal/footer.js
@@ -58,7 +58,7 @@ gl.issueBoards.ModalFooter = Vue.extend({
template: `
<footer
class="form-actions add-issues-footer">
- <div class="pull-left">
+ <div class="float-left">
<button
class="btn btn-success"
type="button"
@@ -72,7 +72,7 @@ gl.issueBoards.ModalFooter = Vue.extend({
<lists-dropdown></lists-dropdown>
</div>
<button
- class="btn btn-default pull-right"
+ class="btn btn-default float-right"
type="button"
@click="toggleModal(false)">
Cancel
diff --git a/app/assets/javascripts/boards/components/modal/list.js b/app/assets/javascripts/boards/components/modal/list.js
index 6b04a6c7a6c..f86896d2178 100644
--- a/app/assets/javascripts/boards/components/modal/list.js
+++ b/app/assets/javascripts/boards/components/modal/list.js
@@ -1,5 +1,3 @@
-/* global ListIssue */
-
import Vue from 'vue';
import bp from '../../../breakpoints';
import ModalStore from '../../stores/modal_store';
@@ -56,8 +54,11 @@ gl.issueBoards.ModalList = Vue.extend({
scrollHandler() {
const currentPage = Math.floor(this.issues.length / this.perPage);
- if ((this.scrollTop() > this.scrollHeight() - 100) && !this.loadingNewPage
- && currentPage === this.page) {
+ if (
+ this.scrollTop() > this.scrollHeight() - 100 &&
+ !this.loadingNewPage &&
+ currentPage === this.page
+ ) {
this.loadingNewPage = true;
this.page += 1;
}
@@ -133,9 +134,9 @@ gl.issueBoards.ModalList = Vue.extend({
<div
v-for="issue in group"
v-if="showIssue(issue)"
- class="card-parent">
+ class="board-card-parent">
<div
- class="card"
+ class="board-card"
:class="{ 'is-active': issue.selected }"
@click="toggleIssue($event, issue)">
<issue-card-inner
diff --git a/app/assets/javascripts/boards/components/modal/tabs.js b/app/assets/javascripts/boards/components/modal/tabs.js
index b6465a88e5e..9d331de8e22 100644
--- a/app/assets/javascripts/boards/components/modal/tabs.js
+++ b/app/assets/javascripts/boards/components/modal/tabs.js
@@ -24,7 +24,7 @@ gl.issueBoards.ModalTabs = Vue.extend({
role="button"
@click.prevent="changeTab('all')">
Open issues
- <span class="badge">
+ <span class="badge badge-pill">
{{ issuesCount }}
</span>
</a>
@@ -35,7 +35,7 @@ gl.issueBoards.ModalTabs = Vue.extend({
role="button"
@click.prevent="changeTab('selected')">
Selected issues
- <span class="badge">
+ <span class="badge badge-pill">
{{ selectedCount }}
</span>
</a>
diff --git a/app/assets/javascripts/boards/components/project_select.vue b/app/assets/javascripts/boards/components/project_select.vue
index 371774098b9..eb335f352d3 100644
--- a/app/assets/javascripts/boards/components/project_select.vue
+++ b/app/assets/javascripts/boards/components/project_select.vue
@@ -1,71 +1,69 @@
<script>
- /* global ListIssue */
+import $ from 'jquery';
+import _ from 'underscore';
+import eventHub from '../eventhub';
+import loadingIcon from '../../vue_shared/components/loading_icon.vue';
+import Api from '../../api';
- import $ from 'jquery';
- import _ from 'underscore';
- import eventHub from '../eventhub';
- import loadingIcon from '../../vue_shared/components/loading_icon.vue';
- import Api from '../../api';
-
- export default {
- name: 'BoardProjectSelect',
- components: {
- loadingIcon,
- },
- props: {
- groupId: {
- type: Number,
- required: true,
- default: 0,
- },
+export default {
+ name: 'BoardProjectSelect',
+ components: {
+ loadingIcon,
+ },
+ props: {
+ groupId: {
+ type: Number,
+ required: true,
+ default: 0,
},
- data() {
- return {
- loading: true,
- selectedProject: {},
- };
+ },
+ data() {
+ return {
+ loading: true,
+ selectedProject: {},
+ };
+ },
+ computed: {
+ selectedProjectName() {
+ return this.selectedProject.name || 'Select a project';
},
- computed: {
- selectedProjectName() {
- return this.selectedProject.name || 'Select a project';
+ },
+ mounted() {
+ $(this.$refs.projectsDropdown).glDropdown({
+ filterable: true,
+ filterRemote: true,
+ search: {
+ fields: ['name_with_namespace'],
},
- },
- mounted() {
- $(this.$refs.projectsDropdown).glDropdown({
- filterable: true,
- filterRemote: true,
- search: {
- fields: ['name_with_namespace'],
- },
- clicked: ({ $el, e }) => {
- e.preventDefault();
- this.selectedProject = {
- id: $el.data('project-id'),
- name: $el.data('project-name'),
- };
- eventHub.$emit('setSelectedProject', this.selectedProject);
- },
- selectable: true,
- data: (term, callback) => {
- this.loading = true;
- return Api.groupProjects(this.groupId, term, (projects) => {
- this.loading = false;
- callback(projects);
- });
- },
- renderRow(project) {
- return `
+ clicked: ({ $el, e }) => {
+ e.preventDefault();
+ this.selectedProject = {
+ id: $el.data('project-id'),
+ name: $el.data('project-name'),
+ };
+ eventHub.$emit('setSelectedProject', this.selectedProject);
+ },
+ selectable: true,
+ data: (term, callback) => {
+ this.loading = true;
+ return Api.groupProjects(this.groupId, term, projects => {
+ this.loading = false;
+ callback(projects);
+ });
+ },
+ renderRow(project) {
+ return `
<li>
<a href='#' class='dropdown-menu-link' data-project-id="${project.id}" data-project-name="${project.name}">
${_.escape(project.name)}
</a>
</li>
`;
- },
- text: project => project.name,
- });
- },
- };
+ },
+ text: project => project.name,
+ });
+ },
+};
</script>
<template>
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index a6f8681cfac..29ab13b8e0b 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -214,7 +214,7 @@ export default () => {
if (this.disabled) {
$tooltip.tooltip();
} else {
- $tooltip.tooltip('destroy');
+ $tooltip.tooltip('dispose');
}
});
},
diff --git a/app/assets/javascripts/ci_variable_list/ci_variable_list.js b/app/assets/javascripts/ci_variable_list/ci_variable_list.js
index e177a3bfdc7..47efb3a8cee 100644
--- a/app/assets/javascripts/ci_variable_list/ci_variable_list.js
+++ b/app/assets/javascripts/ci_variable_list/ci_variable_list.js
@@ -141,6 +141,11 @@ export default class VariableList {
$rowClone.find(entry.selector).val(entry.default);
});
+ // Close any dropdowns
+ $rowClone.find('.dropdown-menu.show').each((index, $dropdown) => {
+ $dropdown.classList.remove('show');
+ });
+
this.initRow($rowClone);
$row.after($rowClone);
diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue
index 9c12b89240c..bb5fcea648d 100644
--- a/app/assets/javascripts/clusters/components/applications.vue
+++ b/app/assets/javascripts/clusters/components/applications.vue
@@ -191,11 +191,11 @@ export default {
:value="ingressExternalIp"
readonly
/>
- <span class="input-group-btn">
+ <span class="input-group-append">
<clipboard-button
:text="ingressExternalIp"
:title="s__('ClusterIntegration|Copy Ingress IP Address to clipboard')"
- class="js-clipboard-btn"
+ class="input-group-text js-clipboard-btn"
/>
</span>
</div>
diff --git a/app/assets/javascripts/commons/bootstrap.js b/app/assets/javascripts/commons/bootstrap.js
index db96da4ccba..50e2949ab55 100644
--- a/app/assets/javascripts/commons/bootstrap.js
+++ b/app/assets/javascripts/commons/bootstrap.js
@@ -1,15 +1,7 @@
import $ from 'jquery';
// bootstrap jQuery plugins
-import 'bootstrap-sass/assets/javascripts/bootstrap/affix';
-import 'bootstrap-sass/assets/javascripts/bootstrap/alert';
-import 'bootstrap-sass/assets/javascripts/bootstrap/button';
-import 'bootstrap-sass/assets/javascripts/bootstrap/dropdown';
-import 'bootstrap-sass/assets/javascripts/bootstrap/modal';
-import 'bootstrap-sass/assets/javascripts/bootstrap/tab';
-import 'bootstrap-sass/assets/javascripts/bootstrap/transition';
-import 'bootstrap-sass/assets/javascripts/bootstrap/tooltip';
-import 'bootstrap-sass/assets/javascripts/bootstrap/popover';
+import 'bootstrap';
// custom jQuery functions
$.fn.extend({
diff --git a/app/assets/javascripts/compare_autocomplete.js b/app/assets/javascripts/compare_autocomplete.js
index 9c88466e576..ffe15f02f2e 100644
--- a/app/assets/javascripts/compare_autocomplete.js
+++ b/app/assets/javascripts/compare_autocomplete.js
@@ -54,7 +54,7 @@ export default function initCompareAutocomplete(limitTo = null, clickHandler = (
.attr('href', '#')
.addClass(ref === selected ? 'is-active' : '')
.text(ref)
- .attr('data-ref', escape(ref));
+ .attr('data-ref', ref);
return $('<li />').append(link);
}
},
@@ -78,7 +78,7 @@ export default function initCompareAutocomplete(limitTo = null, clickHandler = (
$dropdownContainer.on('click', '.dropdown-content a', e => {
$dropdown.prop('title', e.target.text.replace(/_+?/g, '-'));
if ($dropdown.hasClass('has-tooltip')) {
- $dropdown.tooltip('fixTitle');
+ $dropdown.tooltip('_fixTitle');
}
});
});
diff --git a/app/assets/javascripts/create_merge_request_dropdown.js b/app/assets/javascripts/create_merge_request_dropdown.js
index a88b6971f90..09d490106df 100644
--- a/app/assets/javascripts/create_merge_request_dropdown.js
+++ b/app/assets/javascripts/create_merge_request_dropdown.js
@@ -61,8 +61,8 @@ export default class CreateMergeRequestDropdown {
}
available() {
- this.availableButton.classList.remove('hide');
- this.unavailableButton.classList.add('hide');
+ this.availableButton.classList.remove('hidden');
+ this.unavailableButton.classList.add('hidden');
}
bindEvents() {
@@ -232,7 +232,7 @@ export default class CreateMergeRequestDropdown {
}
hide() {
- this.wrapperEl.classList.add('hide');
+ this.wrapperEl.classList.add('hidden');
}
init() {
@@ -406,8 +406,8 @@ export default class CreateMergeRequestDropdown {
}
unavailable() {
- this.availableButton.classList.add('hide');
- this.unavailableButton.classList.remove('hide');
+ this.availableButton.classList.add('hidden');
+ this.unavailableButton.classList.remove('hidden');
}
updateBranchName(suggestedBranchName) {
diff --git a/app/assets/javascripts/cycle_analytics/components/limit_warning_component.vue b/app/assets/javascripts/cycle_analytics/components/limit_warning_component.vue
index 32ae0cc1476..5be17081b58 100644
--- a/app/assets/javascripts/cycle_analytics/components/limit_warning_component.vue
+++ b/app/assets/javascripts/cycle_analytics/components/limit_warning_component.vue
@@ -16,7 +16,7 @@
<template>
<span
v-if="count === 50"
- class="events-info pull-right"
+ class="events-info float-right"
>
<i
class="fa fa-warning"
diff --git a/app/assets/javascripts/diff_notes/components/diff_note_avatars.js b/app/assets/javascripts/diff_notes/components/diff_note_avatars.js
index 180a6bd67e7..fe9b0795609 100644
--- a/app/assets/javascripts/diff_notes/components/diff_note_avatars.js
+++ b/app/assets/javascripts/diff_notes/components/diff_note_avatars.js
@@ -79,7 +79,7 @@ const DiffNoteAvatars = Vue.extend({
storeState: {
handler() {
this.$nextTick(() => {
- $('.has-tooltip', this.$el).tooltip('fixTitle');
+ $('.has-tooltip', this.$el).tooltip('_fixTitle');
// We need to add/remove a class to an element that is outside the Vue instance
this.addNoCommentClass();
@@ -138,7 +138,7 @@ const DiffNoteAvatars = Vue.extend({
this.$nextTick(() => {
this.setDiscussionVisible();
- $('.has-tooltip', this.$el).tooltip('fixTitle');
+ $('.has-tooltip', this.$el).tooltip('_fixTitle');
$('.has-tooltip', this.$el).tooltip('hide');
});
},
diff --git a/app/assets/javascripts/diff_notes/components/resolve_btn.js b/app/assets/javascripts/diff_notes/components/resolve_btn.js
index df4c72ba0ed..8d66417abac 100644
--- a/app/assets/javascripts/diff_notes/components/resolve_btn.js
+++ b/app/assets/javascripts/diff_notes/components/resolve_btn.js
@@ -61,7 +61,7 @@ const ResolveBtn = Vue.extend({
this.$nextTick(() => {
$(this.$refs.button)
.tooltip('hide')
- .tooltip('fixTitle');
+ .tooltip('_fixTitle');
});
},
resolve: function () {
diff --git a/app/assets/javascripts/environments/components/environment_actions.vue b/app/assets/javascripts/environments/components/environment_actions.vue
index ab9e22037d0..0b3fef9fcca 100644
--- a/app/assets/javascripts/environments/components/environment_actions.vue
+++ b/app/assets/javascripts/environments/components/environment_actions.vue
@@ -74,7 +74,7 @@
</span>
</button>
- <ul class="dropdown-menu dropdown-menu-align-right">
+ <ul class="dropdown-menu dropdown-menu-right">
<li
v-for="(action, i) in actions"
:key="i">
diff --git a/app/assets/javascripts/environments/components/environment_item.vue b/app/assets/javascripts/environments/components/environment_item.vue
index 79326ca3487..23aaab2c441 100644
--- a/app/assets/javascripts/environments/components/environment_item.vue
+++ b/app/assets/javascripts/environments/components/environment_item.vue
@@ -486,14 +486,14 @@
{{ model.folderName }}
</span>
- <span class="badge">
+ <span class="badge badge-pill">
{{ model.size }}
</span>
</span>
</div>
<div
- class="table-section section-10 deployment-column hidden-xs hidden-sm"
+ class="table-section section-10 deployment-column d-none d-sm-none d-md-block"
role="gridcell"
>
<span v-if="shouldRenderDeploymentID">
@@ -513,7 +513,7 @@
</div>
<div
- class="table-section section-15 hidden-xs hidden-sm"
+ class="table-section section-15 d-none d-sm-none d-md-block"
role="gridcell"
>
<a
diff --git a/app/assets/javascripts/environments/components/environment_monitoring.vue b/app/assets/javascripts/environments/components/environment_monitoring.vue
index deada134b27..8df1b6317e3 100644
--- a/app/assets/javascripts/environments/components/environment_monitoring.vue
+++ b/app/assets/javascripts/environments/components/environment_monitoring.vue
@@ -28,7 +28,7 @@
<template>
<a
v-tooltip
- class="btn monitoring-url hidden-xs hidden-sm"
+ class="btn monitoring-url d-none d-sm-none d-md-block"
data-container="body"
rel="noopener noreferrer nofollow"
:href="monitoringUrl"
diff --git a/app/assets/javascripts/environments/components/environment_rollback.vue b/app/assets/javascripts/environments/components/environment_rollback.vue
index c822fb1574c..7515d711c50 100644
--- a/app/assets/javascripts/environments/components/environment_rollback.vue
+++ b/app/assets/javascripts/environments/components/environment_rollback.vue
@@ -40,7 +40,7 @@
<template>
<button
type="button"
- class="btn hidden-xs hidden-sm"
+ class="btn d-none d-sm-none d-md-block"
@click="onClick"
:disabled="isLoading"
>
diff --git a/app/assets/javascripts/environments/components/environment_stop.vue b/app/assets/javascripts/environments/components/environment_stop.vue
index dda7429a726..7055f208451 100644
--- a/app/assets/javascripts/environments/components/environment_stop.vue
+++ b/app/assets/javascripts/environments/components/environment_stop.vue
@@ -43,7 +43,7 @@
if (confirm('Are you sure you want to stop this environment?')) {
this.isLoading = true;
- $(this.$el).tooltip('destroy');
+ $(this.$el).tooltip('dispose');
eventHub.$emit('postAction', this.stopUrl);
}
@@ -55,7 +55,7 @@
<button
v-tooltip
type="button"
- class="btn stop-env-link hidden-xs hidden-sm"
+ class="btn stop-env-link d-none d-sm-none d-md-block"
data-container="body"
@click="onClick"
:disabled="isLoading"
diff --git a/app/assets/javascripts/environments/components/environment_terminal_button.vue b/app/assets/javascripts/environments/components/environment_terminal_button.vue
index e8469d088ef..0dbbbb75e07 100644
--- a/app/assets/javascripts/environments/components/environment_terminal_button.vue
+++ b/app/assets/javascripts/environments/components/environment_terminal_button.vue
@@ -30,7 +30,7 @@
<template>
<a
v-tooltip
- class="btn terminal-button hidden-xs hidden-sm"
+ class="btn terminal-button d-none d-sm-none d-md-block"
data-container="body"
:title="title"
:aria-label="title"
diff --git a/app/assets/javascripts/feature_highlight/feature_highlight.js b/app/assets/javascripts/feature_highlight/feature_highlight.js
index 2d5bae9a9c4..2f27c9351bc 100644
--- a/app/assets/javascripts/feature_highlight/feature_highlight.js
+++ b/app/assets/javascripts/feature_highlight/feature_highlight.js
@@ -24,7 +24,7 @@ export function setupFeatureHighlightPopover(id, debounceTimeout = 300) {
template: `
<div class="popover feature-highlight-popover" role="tooltip">
<div class="arrow"></div>
- <div class="popover-content"></div>
+ <div class="popover-body"></div>
</div>
`,
})
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js
index fa48d7d1915..746a06b7c4f 100644
--- a/app/assets/javascripts/gl_dropdown.js
+++ b/app/assets/javascripts/gl_dropdown.js
@@ -374,7 +374,7 @@ GitLabDropdown = (function() {
$relatedTarget = $(e.relatedTarget);
$dropdownMenu = $relatedTarget.closest('.dropdown-menu');
if ($dropdownMenu.length === 0) {
- return _this.dropdown.removeClass('open');
+ return _this.dropdown.removeClass('show');
}
}
};
@@ -801,7 +801,7 @@ GitLabDropdown = (function() {
if (this.options.filterable) {
const initialScrollTop = $(window).scrollTop();
- if (this.dropdown.is('.open')) {
+ if (this.dropdown.is('.show') && !this.filterInput.is(':focus')) {
this.filterInput.focus();
}
diff --git a/app/assets/javascripts/gl_field_error.js b/app/assets/javascripts/gl_field_error.js
index 972b2252acb..87c6e37b9fb 100644
--- a/app/assets/javascripts/gl_field_error.js
+++ b/app/assets/javascripts/gl_field_error.js
@@ -62,7 +62,7 @@ export default class GlFieldError {
this.inputDomElement = this.inputElement.get(0);
this.form = formErrors;
this.errorMessage = this.inputElement.attr('title') || 'This field is required.';
- this.fieldErrorElement = $(`<p class='${errorMessageClass} hide'>${this.errorMessage}</p>`);
+ this.fieldErrorElement = $(`<p class='${errorMessageClass} hidden'>${this.errorMessage}</p>`);
this.state = {
valid: false,
@@ -146,8 +146,8 @@ export default class GlFieldError {
renderInvalid() {
this.inputElement.addClass(inputErrorClass);
- this.scopedSiblings.hide();
- return this.fieldErrorElement.show();
+ this.scopedSiblings.addClass('hidden');
+ return this.fieldErrorElement.removeClass('hidden');
}
renderClear() {
@@ -157,7 +157,7 @@ export default class GlFieldError {
this.accessCurrentValue(trimmedInput);
}
this.inputElement.removeClass(inputErrorClass);
- this.scopedSiblings.hide();
- this.fieldErrorElement.hide();
+ this.scopedSiblings.addClass('hidden');
+ this.fieldErrorElement.addClass('hidden');
}
}
diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue
index 764b130fdb8..7f64a9bd741 100644
--- a/app/assets/javascripts/groups/components/group_item.vue
+++ b/app/assets/javascripts/groups/components/group_item.vue
@@ -99,7 +99,7 @@ export default {
/>
</div>
<div
- class="avatar-container prepend-top-8 prepend-left-5 s24 hidden-xs"
+ class="avatar-container prepend-top-8 prepend-left-5 s24 d-none d-sm-block"
:class="{ 'content-loading': group.isChildrenLoading }"
>
<a
diff --git a/app/assets/javascripts/ide/components/changed_file_icon.vue b/app/assets/javascripts/ide/components/changed_file_icon.vue
index 1cec84706fc..a4e06bbbe3c 100644
--- a/app/assets/javascripts/ide/components/changed_file_icon.vue
+++ b/app/assets/javascripts/ide/components/changed_file_icon.vue
@@ -43,7 +43,7 @@ export default {
return `${this.changedIcon}-solid`;
},
changedIconClass() {
- return `multi-${this.changedIcon} pull-left`;
+ return `multi-${this.changedIcon} float-left`;
},
tooltipTitle() {
if (!this.showTooltip) return undefined;
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/form.vue b/app/assets/javascripts/ide/components/commit_sidebar/form.vue
index 81961fe3c57..705953c86e3 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/form.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/form.vue
@@ -144,14 +144,14 @@ export default {
<loading-button
:loading="submitCommitLoading"
:disabled="commitButtonDisabled"
- container-class="btn btn-success btn-sm pull-left"
+ container-class="btn btn-success btn-sm float-left"
:label="__('Commit')"
@click="commitChanges"
/>
<button
v-if="!discardDraftButtonDisabled"
type="button"
- class="btn btn-default btn-sm pull-right"
+ class="btn btn-default btn-sm float-right"
@click="discardDraft"
>
{{ __('Discard draft') }}
@@ -159,7 +159,7 @@ export default {
<button
v-else
type="button"
- class="btn btn-default btn-sm pull-right"
+ class="btn btn-default btn-sm float-right"
@click="toggleIsSmall"
>
{{ __('Collapse') }}
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue
index c3ac18bfb83..1325fc993b2 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/list.vue
@@ -120,7 +120,7 @@ export default {
</ul>
<p
v-else
- class="multi-file-commit-list help-block"
+ class="multi-file-commit-list form-text text-muted"
>
{{ __('No changes') }}
</p>
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue b/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue
index dcd934f76b7..f14fcdc88ed 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/message_field.vue
@@ -80,7 +80,7 @@ export default {
{{ __('Commit Message') }}
<span
v-popover="$options.popoverOptions"
- class="help-block prepend-left-10"
+ class="form-text text-muted prepend-left-10"
>
<icon
name="question"
diff --git a/app/assets/javascripts/ide/components/external_link.vue b/app/assets/javascripts/ide/components/external_link.vue
new file mode 100644
index 00000000000..cf3316a8179
--- /dev/null
+++ b/app/assets/javascripts/ide/components/external_link.vue
@@ -0,0 +1,41 @@
+<script>
+import Icon from '~/vue_shared/components/icon.vue';
+
+export default {
+ components: {
+ Icon,
+ },
+ props: {
+ file: {
+ type: Object,
+ required: true,
+ },
+ },
+ computed: {
+ showButtons() {
+ return this.file.permalink;
+ },
+ },
+};
+</script>
+
+<template>
+ <div
+ v-if="showButtons"
+ class="pull-right ide-btn-group"
+ >
+ <a
+ :href="file.permalink"
+ target="_blank"
+ :title="s__('IDE|Open in file view')"
+ rel="noopener noreferrer"
+ >
+ <span class="vertical-align-middle">Open in file view</span>
+ <icon
+ name="external-link"
+ css-classes="vertical-align-middle space-right"
+ :size="16"
+ />
+ </a>
+ </div>
+</template>
diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue
index 1ec69adce09..2c184ea726c 100644
--- a/app/assets/javascripts/ide/components/ide.vue
+++ b/app/assets/javascripts/ide/components/ide.vue
@@ -102,12 +102,12 @@ export default {
class="ide-empty-state"
>
<div class="row js-empty-state">
- <div class="col-xs-12">
+ <div class="col-12">
<div class="svg-content svg-250">
<img :src="emptyStateSvgPath" />
</div>
</div>
- <div class="col-xs-12">
+ <div class="col-12">
<div class="text-content text-center">
<h4>
Welcome to the GitLab IDE
@@ -123,8 +123,6 @@ export default {
</template>
</div>
</div>
- <ide-status-bar
- :file="activeFile"
- />
+ <ide-status-bar :file="activeFile"/>
</article>
</template>
diff --git a/app/assets/javascripts/ide/components/ide_file_buttons.vue b/app/assets/javascripts/ide/components/ide_file_buttons.vue
deleted file mode 100644
index a6c6f46a144..00000000000
--- a/app/assets/javascripts/ide/components/ide_file_buttons.vue
+++ /dev/null
@@ -1,84 +0,0 @@
-<script>
-import { __ } from '~/locale';
-import tooltip from '~/vue_shared/directives/tooltip';
-import Icon from '~/vue_shared/components/icon.vue';
-
-export default {
- components: {
- Icon,
- },
- directives: {
- tooltip,
- },
- props: {
- file: {
- type: Object,
- required: true,
- },
- },
- computed: {
- showButtons() {
- return (
- this.file.rawPath || this.file.blamePath || this.file.commitsPath || this.file.permalink
- );
- },
- rawDownloadButtonLabel() {
- return this.file.binary ? __('Download') : __('Raw');
- },
- },
-};
-</script>
-
-<template>
- <div
- v-if="showButtons"
- class="pull-right ide-btn-group"
- >
- <a
- v-tooltip
- v-if="!file.binary"
- :href="file.blamePath"
- :title="__('Blame')"
- class="btn btn-xs btn-transparent blame"
- >
- <icon
- name="blame"
- :size="16"
- />
- </a>
- <a
- v-tooltip
- :href="file.commitsPath"
- :title="__('History')"
- class="btn btn-xs btn-transparent history"
- >
- <icon
- name="history"
- :size="16"
- />
- </a>
- <a
- v-tooltip
- :href="file.permalink"
- :title="__('Permalink')"
- class="btn btn-xs btn-transparent permalink"
- >
- <icon
- name="link"
- :size="16"
- />
- </a>
- <a
- v-tooltip
- :href="file.rawPath"
- target="_blank"
- class="btn btn-xs btn-transparent prepend-left-10 raw"
- rel="noopener noreferrer"
- :title="rawDownloadButtonLabel">
- <icon
- name="download"
- :size="16"
- />
- </a>
- </div>
-</template>
diff --git a/app/assets/javascripts/ide/components/ide_status_bar.vue b/app/assets/javascripts/ide/components/ide_status_bar.vue
index 70c6d53c3ab..6f60cfbf184 100644
--- a/app/assets/javascripts/ide/components/ide_status_bar.vue
+++ b/app/assets/javascripts/ide/components/ide_status_bar.vue
@@ -1,14 +1,16 @@
<script>
-import { mapGetters } from 'vuex';
+import { mapActions, mapState, mapGetters } from 'vuex';
import icon from '~/vue_shared/components/icon.vue';
import tooltip from '~/vue_shared/directives/tooltip';
import timeAgoMixin from '~/vue_shared/mixins/timeago';
+import CiIcon from '../../vue_shared/components/ci_icon.vue';
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
export default {
components: {
icon,
userAvatarImage,
+ CiIcon,
},
directives: {
tooltip,
@@ -27,8 +29,16 @@ export default {
};
},
computed: {
+ ...mapState(['currentBranchId', 'currentProjectId']),
...mapGetters(['currentProject', 'lastCommit']),
},
+ watch: {
+ lastCommit() {
+ if (!this.isPollingInitialized) {
+ this.initPipelinePolling();
+ }
+ },
+ },
mounted() {
this.startTimer();
},
@@ -36,13 +46,21 @@ export default {
if (this.intervalId) {
clearInterval(this.intervalId);
}
+ if (this.isPollingInitialized) {
+ this.stopPipelinePolling();
+ }
},
methods: {
+ ...mapActions(['pipelinePoll', 'stopPipelinePolling']),
startTimer() {
this.intervalId = setInterval(() => {
this.commitAgeUpdate();
}, 1000);
},
+ initPipelinePolling() {
+ this.pipelinePoll();
+ this.isPollingInitialized = true;
+ },
commitAgeUpdate() {
if (this.lastCommit) {
this.lastCommitFormatedAge = this.timeFormated(this.lastCommit.committed_date);
@@ -61,6 +79,23 @@ export default {
class="ide-status-branch"
v-if="lastCommit && lastCommitFormatedAge"
>
+ <span
+ class="ide-status-pipeline"
+ v-if="lastCommit.pipeline && lastCommit.pipeline.details"
+ >
+ <ci-icon
+ :status="lastCommit.pipeline.details.status"
+ v-tooltip
+ :title="lastCommit.pipeline.details.status.text"
+ />
+ Pipeline
+ <a
+ class="monospace"
+ :href="lastCommit.pipeline.details.status.details_path">#{{ lastCommit.pipeline.id }}</a>
+ {{ lastCommit.pipeline.details.status.text }}
+ for
+ </span>
+
<icon
name="commit"
/>
diff --git a/app/assets/javascripts/ide/components/new_dropdown/index.vue b/app/assets/javascripts/ide/components/new_dropdown/index.vue
index a0ce1c9dac7..f0b29702497 100644
--- a/app/assets/javascripts/ide/components/new_dropdown/index.vue
+++ b/app/assets/javascripts/ide/components/new_dropdown/index.vue
@@ -57,7 +57,7 @@ export default {
<div
class="dropdown"
:class="{
- open: dropdownOpen,
+ show: dropdownOpen,
}"
>
<button
@@ -69,12 +69,12 @@ export default {
<icon
name="plus"
:size="12"
- css-classes="pull-left"
+ css-classes="float-left"
/>
<icon
name="arrow-down"
:size="12"
- css-classes="pull-left"
+ css-classes="float-left"
/>
</button>
<ul
diff --git a/app/assets/javascripts/ide/components/new_dropdown/modal.vue b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
index a95a0225950..dd2800179ff 100644
--- a/app/assets/javascripts/ide/components/new_dropdown/modal.vue
+++ b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
@@ -70,23 +70,21 @@ export default {
@submit="createEntryInStore"
>
<form
- class="form-horizontal"
slot="body"
@submit.prevent="createEntryInStore"
+ class="form-group row"
>
- <fieldset class="form-group append-bottom-0">
- <label class="label-light col-sm-3 ide-new-modal-label">
- {{ __('Name') }}
- </label>
- <div class="col-sm-9">
- <input
- type="text"
- class="form-control"
- v-model="entryName"
- ref="fieldName"
- />
- </div>
- </fieldset>
+ <label class="label-light col-form-label col-sm-3">
+ {{ __('Name') }}
+ </label>
+ <div class="col-sm-9">
+ <input
+ type="text"
+ class="form-control"
+ v-model="entryName"
+ ref="fieldName"
+ />
+ </div>
</form>
</deprecated-modal>
</template>
diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue
index f2178c06c10..93453989c08 100644
--- a/app/assets/javascripts/ide/components/repo_editor.vue
+++ b/app/assets/javascripts/ide/components/repo_editor.vue
@@ -6,12 +6,12 @@ import ContentViewer from '~/vue_shared/components/content_viewer/content_viewer
import { activityBarViews, viewerTypes } from '../constants';
import monacoLoader from '../monaco_loader';
import Editor from '../lib/editor';
-import IdeFileButtons from './ide_file_buttons.vue';
+import ExternalLink from './external_link.vue';
export default {
components: {
ContentViewer,
- IdeFileButtons,
+ ExternalLink,
},
props: {
file: {
@@ -197,7 +197,7 @@ export default {
>
<div class="ide-mode-tabs clearfix" >
<ul
- class="nav-links pull-left"
+ class="nav-links float-left"
v-if="!shouldHideEditor && isEditModeActive"
>
<li :class="editTabCSS">
@@ -224,7 +224,7 @@ export default {
</a>
</li>
</ul>
- <ide-file-buttons
+ <external-link
:file="file"
/>
</div>
diff --git a/app/assets/javascripts/ide/components/repo_file.vue b/app/assets/javascripts/ide/components/repo_file.vue
index 7bc865058c6..f56aeced806 100644
--- a/app/assets/javascripts/ide/components/repo_file.vue
+++ b/app/assets/javascripts/ide/components/repo_file.vue
@@ -144,7 +144,7 @@ export default {
:file="file"
/>
</span>
- <span class="pull-right ide-file-icon-holder">
+ <span class="float-right ide-file-icon-holder">
<mr-file-icon
v-if="file.mrChange"
/>
@@ -169,7 +169,7 @@ export default {
:show-tooltip="true"
:show-staged-icon="true"
:force-modified-icon="true"
- class="pull-right"
+ class="float-right"
/>
</span>
<new-dropdown
@@ -177,7 +177,7 @@ export default {
:project-id="file.projectId"
:branch="file.branchId"
:path="file.path"
- class="pull-right prepend-left-8"
+ class="float-right prepend-left-8"
/>
</div>
</div>
diff --git a/app/assets/javascripts/ide/components/repo_loading_file.vue b/app/assets/javascripts/ide/components/repo_loading_file.vue
index 79af8c0b0c7..3e47da88050 100644
--- a/app/assets/javascripts/ide/components/repo_loading_file.vue
+++ b/app/assets/javascripts/ide/components/repo_loading_file.vue
@@ -25,13 +25,13 @@
/>
</td>
<template v-if="!leftPanelCollapsed">
- <td class="hidden-sm hidden-xs">
+ <td class="d-none d-sm-none d-md-block">
<skeleton-loading-container
:small="true"
/>
</td>
- <td class="hidden-xs">
+ <td class="d-none d-sm-block">
<skeleton-loading-container
class="animation-container-right"
:small="true"
diff --git a/app/assets/javascripts/ide/lib/common/model.js b/app/assets/javascripts/ide/lib/common/model.js
index b1e43a1e38c..e5149b1f3ad 100644
--- a/app/assets/javascripts/ide/lib/common/model.js
+++ b/app/assets/javascripts/ide/lib/common/model.js
@@ -1,4 +1,3 @@
-/* global monaco */
import Disposable from './disposable';
import eventHub from '../../eventhub';
diff --git a/app/assets/javascripts/ide/services/index.js b/app/assets/javascripts/ide/services/index.js
index a12e637616a..e8b51f2b516 100644
--- a/app/assets/javascripts/ide/services/index.js
+++ b/app/assets/javascripts/ide/services/index.js
@@ -75,4 +75,8 @@ export default {
},
});
},
+ lastCommitPipelines({ getters }) {
+ const commitSha = getters.lastCommit.id;
+ return Api.commitPipelines(getters.currentProject.path_with_namespace, commitSha);
+ },
};
diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js
index 13aea91d8ba..74f9c112f5a 100644
--- a/app/assets/javascripts/ide/stores/actions/file.js
+++ b/app/assets/javascripts/ide/stores/actions/file.js
@@ -84,11 +84,11 @@ export const getFileData = ({ state, commit, dispatch }, { path, makeFileActive
});
};
-export const setFileMrChange = ({ state, commit }, { file, mrChange }) => {
+export const setFileMrChange = ({ commit }, { file, mrChange }) => {
commit(types.SET_FILE_MERGE_REQUEST_CHANGE, { file, mrChange });
};
-export const getRawFileData = ({ state, commit, dispatch }, { path, baseSha }) => {
+export const getRawFileData = ({ state, commit }, { path, baseSha }) => {
const file = state.entries[path];
return new Promise((resolve, reject) => {
service
@@ -156,7 +156,7 @@ export const setEditorPosition = ({ getters, commit }, { editorRow, editorColumn
}
};
-export const setFileViewMode = ({ state, commit }, { file, viewMode }) => {
+export const setFileViewMode = ({ commit }, { file, viewMode }) => {
commit(types.SET_FILE_VIEWMODE, { file, viewMode });
};
diff --git a/app/assets/javascripts/ide/stores/actions/merge_request.js b/app/assets/javascripts/ide/stores/actions/merge_request.js
index da73034fd7d..5ec9bd661bb 100644
--- a/app/assets/javascripts/ide/stores/actions/merge_request.js
+++ b/app/assets/javascripts/ide/stores/actions/merge_request.js
@@ -3,7 +3,7 @@ import service from '../../services';
import * as types from '../mutation_types';
export const getMergeRequestData = (
- { commit, state, dispatch },
+ { commit, state },
{ projectId, mergeRequestId, force = false } = {},
) =>
new Promise((resolve, reject) => {
@@ -32,7 +32,7 @@ export const getMergeRequestData = (
});
export const getMergeRequestChanges = (
- { commit, state, dispatch },
+ { commit, state },
{ projectId, mergeRequestId, force = false } = {},
) =>
new Promise((resolve, reject) => {
@@ -58,7 +58,7 @@ export const getMergeRequestChanges = (
});
export const getMergeRequestVersions = (
- { commit, state, dispatch },
+ { commit, state },
{ projectId, mergeRequestId, force = false } = {},
) =>
new Promise((resolve, reject) => {
diff --git a/app/assets/javascripts/ide/stores/actions/project.js b/app/assets/javascripts/ide/stores/actions/project.js
index eff9bc03651..75cfd9946d7 100644
--- a/app/assets/javascripts/ide/stores/actions/project.js
+++ b/app/assets/javascripts/ide/stores/actions/project.js
@@ -1,11 +1,13 @@
+import Visibility from 'visibilityjs';
import flash from '~/flash';
+import { __ } from '~/locale';
import service from '../../services';
import * as types from '../mutation_types';
+import Poll from '../../../lib/utils/poll';
-export const getProjectData = (
- { commit, state, dispatch },
- { namespace, projectId, force = false } = {},
-) =>
+let eTagPoll;
+
+export const getProjectData = ({ commit, state }, { namespace, projectId, force = false } = {}) =>
new Promise((resolve, reject) => {
if (!state.projects[`${namespace}/${projectId}`] || force) {
commit(types.TOGGLE_LOADING, { entry: state });
@@ -21,7 +23,7 @@ export const getProjectData = (
})
.catch(() => {
flash(
- 'Error loading project data. Please try again.',
+ __('Error loading project data. Please try again.'),
'alert',
document,
null,
@@ -35,10 +37,7 @@ export const getProjectData = (
}
});
-export const getBranchData = (
- { commit, state, dispatch },
- { projectId, branchId, force = false } = {},
-) =>
+export const getBranchData = ({ commit, state }, { projectId, branchId, force = false } = {}) =>
new Promise((resolve, reject) => {
if (
typeof state.projects[`${projectId}`] === 'undefined' ||
@@ -59,7 +58,7 @@ export const getBranchData = (
})
.catch(() => {
flash(
- 'Error loading branch data. Please try again.',
+ __('Error loading branch data. Please try again.'),
'alert',
document,
null,
@@ -73,25 +72,74 @@ export const getBranchData = (
}
});
-export const refreshLastCommitData = (
- { commit, state, dispatch },
- { projectId, branchId } = {},
-) => service
- .getBranchData(projectId, branchId)
- .then(({ data }) => {
- commit(types.SET_BRANCH_COMMIT, {
- projectId,
- branchId,
- commit: data.commit,
+export const refreshLastCommitData = ({ commit }, { projectId, branchId } = {}) =>
+ service
+ .getBranchData(projectId, branchId)
+ .then(({ data }) => {
+ commit(types.SET_BRANCH_COMMIT, {
+ projectId,
+ branchId,
+ commit: data.commit,
+ });
+ })
+ .catch(() => {
+ flash(__('Error loading last commit.'), 'alert', document, null, false, true);
});
- })
- .catch(() => {
- flash(
- 'Error loading last commit.',
- 'alert',
- document,
- null,
- false,
- true,
+
+export const pollSuccessCallBack = ({ commit, state }, { data }) => {
+ if (data.pipelines && data.pipelines.length) {
+ const lastCommitHash =
+ state.projects[state.currentProjectId].branches[state.currentBranchId].commit.id;
+ const lastCommitPipeline = data.pipelines.find(
+ pipeline => pipeline.commit.id === lastCommitHash,
);
+ commit(types.SET_LAST_COMMIT_PIPELINE, {
+ projectId: state.currentProjectId,
+ branchId: state.currentBranchId,
+ pipeline: lastCommitPipeline || {},
+ });
+ }
+
+ return data;
+};
+
+export const pipelinePoll = ({ getters, dispatch }) => {
+ eTagPoll = new Poll({
+ resource: service,
+ method: 'lastCommitPipelines',
+ data: {
+ getters,
+ },
+ successCallback: ({ data }) => dispatch('pollSuccessCallBack', { data }),
+ errorCallback: () => {
+ flash(
+ __('Something went wrong while fetching the latest pipeline status.'),
+ 'alert',
+ document,
+ null,
+ false,
+ true,
+ );
+ },
+ });
+
+ if (!Visibility.hidden()) {
+ eTagPoll.makeRequest();
+ }
+
+ Visibility.change(() => {
+ if (!Visibility.hidden()) {
+ eTagPoll.restart();
+ } else {
+ eTagPoll.stop();
+ }
});
+};
+
+export const stopPipelinePolling = () => {
+ eTagPoll.stop();
+};
+
+export const restartPipelinePolling = () => {
+ eTagPoll.restart();
+};
diff --git a/app/assets/javascripts/ide/stores/actions/tree.js b/app/assets/javascripts/ide/stores/actions/tree.js
index 6536be04f0a..cc5116413f7 100644
--- a/app/assets/javascripts/ide/stores/actions/tree.js
+++ b/app/assets/javascripts/ide/stores/actions/tree.js
@@ -5,7 +5,7 @@ import * as types from '../mutation_types';
import { findEntry } from '../utils';
import FilesDecoratorWorker from '../workers/files_decorator_worker';
-export const toggleTreeOpen = ({ commit, dispatch }, path) => {
+export const toggleTreeOpen = ({ commit }, path) => {
commit(types.TOGGLE_TREE_OPEN, path);
};
@@ -23,7 +23,7 @@ export const handleTreeEntryAction = ({ commit, dispatch }, row) => {
}
};
-export const getLastCommitData = ({ state, commit, dispatch, getters }, tree = state) => {
+export const getLastCommitData = ({ state, commit, dispatch }, tree = state) => {
if (!tree || tree.lastCommitPath === null || !tree.lastCommitPath) return;
service
@@ -49,7 +49,7 @@ export const getLastCommitData = ({ state, commit, dispatch, getters }, tree = s
.catch(() => flash('Error fetching log data.', 'alert', document, null, false, true));
};
-export const getFiles = ({ state, commit, dispatch }, { projectId, branchId } = {}) =>
+export const getFiles = ({ state, commit }, { projectId, branchId } = {}) =>
new Promise((resolve, reject) => {
if (!state.trees[`${projectId}/${branchId}`]) {
const selectedProject = state.projects[projectId];
diff --git a/app/assets/javascripts/ide/stores/modules/commit/actions.js b/app/assets/javascripts/ide/stores/modules/commit/actions.js
index cd25c3060f2..0a0db4033c8 100644
--- a/app/assets/javascripts/ide/stores/modules/commit/actions.js
+++ b/app/assets/javascripts/ide/stores/modules/commit/actions.js
@@ -31,9 +31,9 @@ export const setLastCommitMessage = ({ rootState, commit }, data) => {
const currentProject = rootState.projects[rootState.currentProjectId];
const commitStats = data.stats
? sprintf(__('with %{additions} additions, %{deletions} deletions.'), {
- additions: data.stats.additions, // eslint-disable-line indent
- deletions: data.stats.deletions, // eslint-disable-line indent
- }) // eslint-disable-line indent
+ additions: data.stats.additions, // eslint-disable-line indent-legacy
+ deletions: data.stats.deletions, // eslint-disable-line indent-legacy
+ }) // eslint-disable-line indent-legacy
: '';
const commitMsg = sprintf(
__('Your changes have been committed. Commit %{commitId} %{commitStats}'),
@@ -74,10 +74,7 @@ export const checkCommitStatus = ({ rootState }) =>
),
);
-export const updateFilesAfterCommit = (
- { commit, dispatch, state, rootState, rootGetters },
- { data },
-) => {
+export const updateFilesAfterCommit = ({ commit, dispatch, rootState }, { data }) => {
const selectedProject = rootState.projects[rootState.currentProjectId];
const lastCommit = {
commit_path: `${selectedProject.web_url}/commit/${data.id}`,
diff --git a/app/assets/javascripts/ide/stores/mutation_types.js b/app/assets/javascripts/ide/stores/mutation_types.js
index a3fb3232f1d..0a3f8d031c4 100644
--- a/app/assets/javascripts/ide/stores/mutation_types.js
+++ b/app/assets/javascripts/ide/stores/mutation_types.js
@@ -23,6 +23,7 @@ export const SET_BRANCH = 'SET_BRANCH';
export const SET_BRANCH_COMMIT = 'SET_BRANCH_COMMIT';
export const SET_BRANCH_WORKING_REFERENCE = 'SET_BRANCH_WORKING_REFERENCE';
export const TOGGLE_BRANCH_OPEN = 'TOGGLE_BRANCH_OPEN';
+export const SET_LAST_COMMIT_PIPELINE = 'SET_LAST_COMMIT_PIPELINE';
// Tree mutation types
export const SET_DIRECTORY_DATA = 'SET_DIRECTORY_DATA';
diff --git a/app/assets/javascripts/ide/stores/mutations/branch.js b/app/assets/javascripts/ide/stores/mutations/branch.js
index e09f88878f4..f17ec4da308 100644
--- a/app/assets/javascripts/ide/stores/mutations/branch.js
+++ b/app/assets/javascripts/ide/stores/mutations/branch.js
@@ -14,6 +14,10 @@ export default {
treeId: `${projectPath}/${branchName}`,
active: true,
workingReference: '',
+ commit: {
+ ...branch.commit,
+ pipeline: {},
+ },
},
},
});
@@ -28,4 +32,9 @@ export default {
commit,
});
},
+ [types.SET_LAST_COMMIT_PIPELINE](state, { projectId, branchId, pipeline }) {
+ Object.assign(state.projects[projectId].branches[branchId].commit, {
+ pipeline,
+ });
+ },
};
diff --git a/app/assets/javascripts/issuable_form.js b/app/assets/javascripts/issuable_form.js
index 90d4e19e90b..bb8b3d91e40 100644
--- a/app/assets/javascripts/issuable_form.js
+++ b/app/assets/javascripts/issuable_form.js
@@ -30,7 +30,7 @@ export default class IssuableForm {
}
this.initAutosave();
- this.form.on('submit:success', this.handleSubmit);
+ this.form.on('submit', this.handleSubmit);
this.form.on('click', '.btn-cancel', this.resetAutosave);
this.initWip();
diff --git a/app/assets/javascripts/issue_show/components/edit_actions.vue b/app/assets/javascripts/issue_show/components/edit_actions.vue
index a539506bce2..7ef5e679881 100644
--- a/app/assets/javascripts/issue_show/components/edit_actions.vue
+++ b/app/assets/javascripts/issue_show/components/edit_actions.vue
@@ -51,7 +51,7 @@
<template>
<div class="prepend-top-default append-bottom-default clearfix">
<button
- class="btn btn-save pull-left"
+ class="btn btn-save float-left"
:class="{ disabled: formState.updateLoading || !isSubmitEnabled }"
type="submit"
:disabled="formState.updateLoading || !isSubmitEnabled"
@@ -64,14 +64,14 @@
</i>
</button>
<button
- class="btn btn-default pull-right"
+ class="btn btn-default float-right"
type="button"
@click="closeForm">
Cancel
</button>
<button
v-if="shouldShowDeleteButton"
- class="btn btn-danger pull-right append-right-default"
+ class="btn btn-danger float-right append-right-default"
:class="{ disabled: deleteLoading }"
type="button"
:disabled="deleteLoading"
diff --git a/app/assets/javascripts/issue_show/components/form.vue b/app/assets/javascripts/issue_show/components/form.vue
index 779705e19ac..ab8bd34762f 100644
--- a/app/assets/javascripts/issue_show/components/form.vue
+++ b/app/assets/javascripts/issue_show/components/form.vue
@@ -84,7 +84,7 @@
<div
:class="{
'col-sm-8 col-lg-9': hasIssuableTemplates,
- 'col-xs-12': !hasIssuableTemplates,
+ 'col-12': !hasIssuableTemplates,
}"
>
<title-field
diff --git a/app/assets/javascripts/job.js b/app/assets/javascripts/job.js
index ace45e9dd29..611e8200b4d 100644
--- a/app/assets/javascripts/job.js
+++ b/app/assets/javascripts/job.js
@@ -1,5 +1,6 @@
import $ from 'jquery';
import _ from 'underscore';
+import StickyFill from 'stickyfilljs';
import axios from './lib/utils/axios_utils';
import { visitUrl } from './lib/utils/url_utility';
import bp from './breakpoints';
@@ -82,17 +83,11 @@ export default class Job {
/**
If the browser does not support position sticky, it returns the position as static.
If the browser does support sticky, then we allow the browser to handle it, if not
- then we default back to Bootstraps affix
- **/
+ then we use a polyfill
+ */
if (this.$topBar.css('position') !== 'static') return;
- const offsetTop = this.$buildTrace.offset().top;
-
- this.$topBar.affix({
- offset: {
- top: offsetTop,
- },
- });
+ StickyFill.add(this.$topBar);
}
// eslint-disable-next-line class-methods-use-this
diff --git a/app/assets/javascripts/jobs/components/header.vue b/app/assets/javascripts/jobs/components/header.vue
index 21b545d6cab..c1044f4cd42 100644
--- a/app/assets/javascripts/jobs/components/header.vue
+++ b/app/assets/javascripts/jobs/components/header.vue
@@ -56,7 +56,7 @@ export default {
actions.push({
label: 'New issue',
path: this.job.new_issue_path,
- cssClass: 'js-new-issue btn btn-new btn-inverted visible-md-block visible-lg-block',
+ cssClass: 'js-new-issue btn btn-new btn-inverted d-none d-md-block d-lg-block d-xl-block',
type: 'link',
});
}
diff --git a/app/assets/javascripts/jobs/components/sidebar_detail_row.vue b/app/assets/javascripts/jobs/components/sidebar_detail_row.vue
index dfe87d89a39..83560a8ff0e 100644
--- a/app/assets/javascripts/jobs/components/sidebar_detail_row.vue
+++ b/app/assets/javascripts/jobs/components/sidebar_detail_row.vue
@@ -39,7 +39,7 @@
<span
v-if="hasHelpURL"
- class="help-button pull-right"
+ class="help-button float-right"
>
<a
:href="helpUrl"
diff --git a/app/assets/javascripts/jobs/components/sidebar_details_block.vue b/app/assets/javascripts/jobs/components/sidebar_details_block.vue
index db19dc9b238..8f3c66b0cbe 100644
--- a/app/assets/javascripts/jobs/components/sidebar_details_block.vue
+++ b/app/assets/javascripts/jobs/components/sidebar_details_block.vue
@@ -48,11 +48,10 @@ export default {
return `${this.job.runner.description} (#${this.job.runner.id})`;
},
retryButtonClass() {
- let className = 'js-retry-button pull-right btn btn-retry visible-md-block visible-lg-block';
+ let className =
+ 'js-retry-button float-right btn btn-retry d-none d-md-block d-lg-block d-xl-block';
className +=
- this.job.status && this.job.recoverable
- ? ' btn-primary'
- : ' btn-inverted-secondary';
+ this.job.status && this.job.recoverable ? ' btn-primary' : ' btn-inverted-secondary';
return className;
},
hasTimeout() {
@@ -104,8 +103,7 @@ export default {
<button
type="button"
:aria-label="__('Toggle Sidebar')"
- class="btn btn-blank gutter-toggle pull-right
- visible-xs-block visible-sm-block js-sidebar-build-toggle"
+ class="btn btn-blank gutter-toggle float-right d-block d-md-none js-sidebar-build-toggle"
>
<i
aria-hidden="true"
diff --git a/app/assets/javascripts/jobs/job_details_mediator.js b/app/assets/javascripts/jobs/job_details_mediator.js
index 5a216f8fae2..89019da9d1e 100644
--- a/app/assets/javascripts/jobs/job_details_mediator.js
+++ b/app/assets/javascripts/jobs/job_details_mediator.js
@@ -1,5 +1,3 @@
-/* global Build */
-
import Visibility from 'visibilityjs';
import Flash from '../flash';
import Poll from '../lib/utils/poll';
@@ -50,7 +48,8 @@ export default class JobMediator {
}
getJob() {
- return this.service.getJob()
+ return this.service
+ .getJob()
.then(response => this.successCallback(response))
.catch(() => this.errorCallback());
}
diff --git a/app/assets/javascripts/label_manager.js b/app/assets/javascripts/label_manager.js
index e230dbbd4ac..6af22ecc990 100644
--- a/app/assets/javascripts/label_manager.js
+++ b/app/assets/javascripts/label_manager.js
@@ -35,7 +35,7 @@ export default class LabelManager {
const $label = $(`#${$btn.data('domId')}`);
const action = $btn.parents('.js-prioritized-labels').length ? 'remove' : 'add';
const $tooltip = $(`#${$btn.find('.has-tooltip:visible').attr('aria-describedby')}`);
- $tooltip.tooltip('destroy');
+ $tooltip.tooltip('dispose');
_this.toggleLabelPriority($label, action);
_this.toggleEmptyState($label, $btn, action);
}
diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js
index 9b62cfb8206..eafdaf4a672 100644
--- a/app/assets/javascripts/labels_select.js
+++ b/app/assets/javascripts/labels_select.js
@@ -120,7 +120,7 @@ export default class LabelsSelect {
$sidebarLabelTooltip
.attr('title', labelTooltipTitle)
- .tooltip('fixTitle');
+ .tooltip('_fixTitle');
$('.has-tooltip', $value).tooltip({
container: 'body'
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 9ff2042475b..8b5445d012b 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -51,7 +51,7 @@ export const rstrip = (val) => {
return val;
};
-export const updateTooltipTitle = ($tooltipEl, newTitle) => $tooltipEl.attr('title', newTitle).tooltip('fixTitle');
+export const updateTooltipTitle = ($tooltipEl, newTitle) => $tooltipEl.attr('title', newTitle).tooltip('_fixTitle');
export const disableButtonIfEmptyField = (fieldSelector, buttonSelector, eventName = 'input') => {
const field = $(fieldSelector);
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index b7624cf490a..0ff23bbb061 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -143,8 +143,7 @@ export const localTimeAgo = ($timeagoEls, setTimeago = true) => {
if (setTimeago) {
// Recreate with custom template
$(el).tooltip({
- template:
- '<div class="tooltip local-timeago" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
+ template: '<div class="tooltip local-timeago" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',
});
}
diff --git a/app/assets/javascripts/locale/index.js b/app/assets/javascripts/locale/index.js
index 2f4328b56e1..2cc5fb10027 100644
--- a/app/assets/javascripts/locale/index.js
+++ b/app/assets/javascripts/locale/index.js
@@ -9,7 +9,7 @@ delete window.translations;
Translates `text`
@param text The text to be translated
@returns {String} The translated text
-**/
+*/
const gettext = locale.gettext.bind(locale);
/**
@@ -21,7 +21,7 @@ const gettext = locale.gettext.bind(locale);
@param pluralText Plural text to translate (eg. '%d days')
@param count Number to decide which translation to use (eg. 2)
@returns {String} Translated text with the number replaced (eg. '2 days')
-**/
+*/
const ngettext = (text, pluralText, count) => {
const translated = locale.ngettext(text, pluralText, count).replace(/%d/g, count).split('|');
@@ -38,7 +38,7 @@ const ngettext = (text, pluralText, count) => {
(eg. 'Context')
@param key Is the dynamic variable you want to be translated
@returns {String} Translated context based text
-**/
+*/
const pgettext = (keyOrContext, key) => {
const normalizedKey = key ? `${keyOrContext}|${key}` : keyOrContext;
const translated = gettext(normalizedKey).split('|');
diff --git a/app/assets/javascripts/locale/sprintf.js b/app/assets/javascripts/locale/sprintf.js
index 5f4a053f98e..599104dcfa0 100644
--- a/app/assets/javascripts/locale/sprintf.js
+++ b/app/assets/javascripts/locale/sprintf.js
@@ -10,7 +10,7 @@ import _ from 'underscore';
@see https://ruby-doc.org/core-2.3.3/Kernel.html#method-i-sprintf
@see https://gitlab.com/gitlab-org/gitlab-ce/issues/37992
-**/
+*/
export default (input, parameters, escapeParameters = true) => {
let output = input;
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 247aeb481c6..9803bebfd10 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -46,9 +46,9 @@ document.addEventListener('beforeunload', () => {
// Unbind scroll events
$(document).off('scroll');
// Close any open tooltips
- $('.has-tooltip, [data-toggle="tooltip"]').tooltip('destroy');
+ $('.has-tooltip, [data-toggle="tooltip"]').tooltip('dispose');
// Close any open popover
- $('[data-toggle="popover"]').popover('destroy');
+ $('[data-toggle="popover"]').popover('dispose');
});
window.addEventListener('hashchange', handleLocationHash);
@@ -111,7 +111,7 @@ document.addEventListener('DOMContentLoaded', () => {
$('.remove-row').on('ajax:success', function removeRowAjaxSuccessCallback() {
$(this)
- .tooltip('destroy')
+ .tooltip('dispose')
.closest('li')
.fadeOut();
});
@@ -141,9 +141,9 @@ document.addEventListener('DOMContentLoaded', () => {
});
// Initialize tooltips
- $.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover';
$body.tooltip({
selector: '.has-tooltip, [data-toggle="tooltip"]',
+ trigger: 'hover',
placement(tip, el) {
return $(el).data('placement') || 'bottom';
},
@@ -196,7 +196,7 @@ document.addEventListener('DOMContentLoaded', () => {
$container.remove();
});
- $('.navbar-toggle').on('click', () => {
+ $('.navbar-toggler').on('click', () => {
$('.header-content').toggleClass('menu-expanded');
gl.lazyLoader.loadCheck();
});
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index 3f84f4b9499..493c119dc6f 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -362,7 +362,7 @@ export default class MergeRequestTabs {
//
// status - Boolean, true to show, false to hide
toggleLoading(status) {
- $('.mr-loading-status .loading').toggle(status);
+ $('.mr-loading-status .loading').toggleClass('hidden', !status);
}
diffViewType() {
@@ -427,7 +427,7 @@ export default class MergeRequestTabs {
If the browser does not support position sticky, it returns the position as static.
If the browser does support sticky, then we allow the browser to handle it, if not
then we default back to Bootstraps affix
- **/
+ */
if ($tabs.css('position') !== 'static') return;
const $diffTabs = $('#diff-notes-app');
diff --git a/app/assets/javascripts/monitoring/components/graph_group.vue b/app/assets/javascripts/monitoring/components/graph_group.vue
index a6dbe42a8f0..241627f9790 100644
--- a/app/assets/javascripts/monitoring/components/graph_group.vue
+++ b/app/assets/javascripts/monitoring/components/graph_group.vue
@@ -17,12 +17,12 @@ export default {
<template>
<div
v-if="showPanels"
- class="panel panel-default prometheus-panel"
+ class="card prometheus-panel"
>
- <div class="panel-heading">
+ <div class="card-header">
<h4>{{ name }}</h4>
</div>
- <div class="panel-body prometheus-graph-group">
+ <div class="card-body prometheus-graph-group">
<slot></slot>
</div>
</div>
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index 96f2b3eac98..b2c1a26bbae 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -1231,8 +1231,8 @@ export default class Notes {
const isForced = forceShow === true || forceShow === false;
const showNow = forceShow === true || (!isCurrentlyShown && !isForced);
- targetRow.toggle(showNow);
- notesContent.toggle(showNow);
+ targetRow.toggleClass('hide', !showNow);
+ notesContent.toggleClass('hide', !showNow);
}
if (addForm) {
@@ -1675,7 +1675,7 @@ export default class Notes {
<div class="note-header">
<div class="note-header-info">
<a href="/${_.escape(currentUsername)}">
- <span class="hidden-xs">${_.escape(
+ <span class="d-none d-sm-block">${_.escape(
currentUsername,
)}</span>
<span class="note-headline-light">${_.escape(
@@ -1694,7 +1694,7 @@ export default class Notes {
</li>`,
);
- $tempNote.find('.hidden-xs').text(_.escape(currentUserFullname));
+ $tempNote.find('.d-none.d-sm-block').text(_.escape(currentUserFullname));
$tempNote
.find('.note-headline-light')
.text(`@${_.escape(currentUsername)}`);
diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue
index 48642c4a086..72d7e22fba0 100644
--- a/app/assets/javascripts/notes/components/comment_form.vue
+++ b/app/assets/javascripts/notes/components/comment_form.vue
@@ -321,7 +321,7 @@ Please check your network connection and try again.`;
<li class="timeline-entry">
<div class="timeline-entry-inner">
<div class="flash-container error-alert timeline-content"></div>
- <div class="timeline-icon hidden-xs hidden-sm">
+ <div class="timeline-icon d-none d-sm-none d-md-block">
<user-avatar-link
v-if="author"
:link-href="author.path"
@@ -369,7 +369,7 @@ js-gfm-input js-autosize markdown-area js-vue-textarea"
</markdown-field>
<div class="note-form-actions">
<div
- class="pull-left btn-group
+ class="float-left btn-group
append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown">
<button
@click.prevent="handleSave()"
@@ -383,6 +383,7 @@ append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown"
name="button"
type="button"
class="btn comment-btn note-type-toggle js-note-new-discussion dropdown-toggle"
+ data-display="static"
data-toggle="dropdown"
aria-label="Open comment type dropdown">
<i
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue
index e0f883a8e08..7f5aacaa3a2 100644
--- a/app/assets/javascripts/notes/components/noteable_discussion.vue
+++ b/app/assets/javascripts/notes/components/noteable_discussion.vue
@@ -100,7 +100,7 @@ export default {
: 'div';
},
wrapperClass() {
- return this.isDiffDiscussion ? '' : 'panel panel-default';
+ return this.isDiffDiscussion ? '' : 'card';
},
},
mounted() {
@@ -263,7 +263,7 @@ Please check your network connection and try again.`;
class="discussion-reply-holder">
<template v-if="!isReplying && canReply">
<div
- class="btn-group-justified discussion-with-resolve-btn"
+ class="btn-group d-flex discussion-with-resolve-btn"
role="group">
<div
class="btn-group"
diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js
index 98ce070288e..b2222476924 100644
--- a/app/assets/javascripts/notes/stores/actions.js
+++ b/app/assets/javascripts/notes/stores/actions.js
@@ -12,20 +12,13 @@ import { isInViewport, scrollToElement } from '../../lib/utils/common_utils';
let eTagPoll;
-export const setNotesData = ({ commit }, data) =>
- commit(types.SET_NOTES_DATA, data);
-export const setNoteableData = ({ commit }, data) =>
- commit(types.SET_NOTEABLE_DATA, data);
-export const setUserData = ({ commit }, data) =>
- commit(types.SET_USER_DATA, data);
-export const setLastFetchedAt = ({ commit }, data) =>
- commit(types.SET_LAST_FETCHED_AT, data);
-export const setInitialNotes = ({ commit }, data) =>
- commit(types.SET_INITIAL_NOTES, data);
-export const setTargetNoteHash = ({ commit }, data) =>
- commit(types.SET_TARGET_NOTE_HASH, data);
-export const toggleDiscussion = ({ commit }, data) =>
- commit(types.TOGGLE_DISCUSSION, data);
+export const setNotesData = ({ commit }, data) => commit(types.SET_NOTES_DATA, data);
+export const setNoteableData = ({ commit }, data) => commit(types.SET_NOTEABLE_DATA, data);
+export const setUserData = ({ commit }, data) => commit(types.SET_USER_DATA, data);
+export const setLastFetchedAt = ({ commit }, data) => commit(types.SET_LAST_FETCHED_AT, data);
+export const setInitialNotes = ({ commit }, data) => commit(types.SET_INITIAL_NOTES, data);
+export const setTargetNoteHash = ({ commit }, data) => commit(types.SET_TARGET_NOTE_HASH, data);
+export const toggleDiscussion = ({ commit }, data) => commit(types.TOGGLE_DISCUSSION, data);
export const fetchNotes = ({ commit }, path) =>
service
@@ -69,20 +62,14 @@ export const createNewNote = ({ commit }, { endpoint, data }) =>
return res;
});
-export const removePlaceholderNotes = ({ commit }) =>
- commit(types.REMOVE_PLACEHOLDER_NOTES);
+export const removePlaceholderNotes = ({ commit }) => commit(types.REMOVE_PLACEHOLDER_NOTES);
-export const toggleResolveNote = (
- { commit },
- { endpoint, isResolved, discussion },
-) =>
+export const toggleResolveNote = ({ commit }, { endpoint, isResolved, discussion }) =>
service
.toggleResolveNote(endpoint, isResolved)
.then(res => res.json())
.then(res => {
- const mutationType = discussion
- ? types.UPDATE_DISCUSSION
- : types.UPDATE_NOTE;
+ const mutationType = discussion ? types.UPDATE_DISCUSSION : types.UPDATE_NOTE;
commit(mutationType, res);
});
@@ -114,7 +101,7 @@ export const reopenIssue = ({ commit, dispatch, state }) => {
export const toggleStateButtonLoading = ({ commit }, value) =>
commit(types.TOGGLE_STATE_BUTTON_LOADING, value);
-export const emitStateChangedEvent = ({ commit, getters }, data) => {
+export const emitStateChangedEvent = ({ getters }, data) => {
const event = new CustomEvent('issuable_vue_app:change', {
detail: {
data,
@@ -179,10 +166,7 @@ export const saveNote = ({ commit, dispatch }, noteData) => {
loadAwardsHandler()
.then(awardsHandler => {
- awardsHandler.addAwardToEmojiBar(
- votesBlock,
- commandsChanges.emoji_award,
- );
+ awardsHandler.addAwardToEmojiBar(votesBlock, commandsChanges.emoji_award);
awardsHandler.scrollToAwards();
})
.catch(() => {
@@ -194,10 +178,7 @@ export const saveNote = ({ commit, dispatch }, noteData) => {
});
}
- if (
- commandsChanges.spend_time != null ||
- commandsChanges.time_estimate != null
- ) {
+ if (commandsChanges.spend_time != null || commandsChanges.time_estimate != null) {
sidebarTimeTrackingEventHub.$emit('timeTrackingUpdated', res);
}
}
@@ -218,14 +199,8 @@ const pollSuccessCallBack = (resp, commit, state, getters) => {
resp.notes.forEach(note => {
if (notesById[note.id]) {
commit(types.UPDATE_NOTE, note);
- } else if (
- note.type === constants.DISCUSSION_NOTE ||
- note.type === constants.DIFF_NOTE
- ) {
- const discussion = utils.findNoteObjectById(
- state.notes,
- note.discussion_id,
- );
+ } else if (note.type === constants.DISCUSSION_NOTE || note.type === constants.DIFF_NOTE) {
+ const discussion = utils.findNoteObjectById(state.notes, note.discussion_id);
if (discussion) {
commit(types.ADD_NEW_REPLY_TO_DISCUSSION, note);
@@ -249,11 +224,8 @@ export const poll = ({ commit, state, getters }) => {
method: 'poll',
data: state,
successCallback: resp =>
- resp
- .json()
- .then(data => pollSuccessCallBack(data, commit, state, getters)),
- errorCallback: () =>
- Flash('Something went wrong while fetching latest comments.'),
+ resp.json().then(data => pollSuccessCallBack(data, commit, state, getters)),
+ errorCallback: () => Flash('Something went wrong while fetching latest comments.'),
});
if (!Visibility.hidden()) {
@@ -292,14 +264,11 @@ export const fetchData = ({ commit, state, getters }) => {
.catch(() => Flash('Something went wrong while fetching latest comments.'));
};
-export const toggleAward = (
- { commit, state, getters, dispatch },
- { awardName, noteId },
-) => {
+export const toggleAward = ({ commit, getters }, { awardName, noteId }) => {
commit(types.TOGGLE_AWARD, { awardName, note: getters.notesById[noteId] });
};
-export const toggleAwardRequest = ({ commit, getters, dispatch }, data) => {
+export const toggleAwardRequest = ({ dispatch }, data) => {
const { endpoint, awardName } = data;
return service
diff --git a/app/assets/javascripts/notifications_form.js b/app/assets/javascripts/notifications_form.js
index 9e6cf67dff0..00e27ca0e70 100644
--- a/app/assets/javascripts/notifications_form.js
+++ b/app/assets/javascripts/notifications_form.js
@@ -15,7 +15,7 @@ export default class NotificationsForm {
toggleCheckbox(e) {
const $checkbox = $(e.currentTarget);
- const $parent = $checkbox.closest('.checkbox');
+ const $parent = $checkbox.closest('.form-check');
this.saveEvent($checkbox, $parent);
}
diff --git a/app/assets/javascripts/pages/admin/admin.js b/app/assets/javascripts/pages/admin/admin.js
index 91f154b7ecd..ff4d6ab15f9 100644
--- a/app/assets/javascripts/pages/admin/admin.js
+++ b/app/assets/javascripts/pages/admin/admin.js
@@ -25,7 +25,7 @@ export default function adminInit() {
$('body').on('click', '.js-toggle-colors-link', (e) => {
e.preventDefault();
- $('.js-toggle-colors-container').toggle();
+ $('.js-toggle-colors-container').toggleClass('hide');
});
$('.log-tabs a').on('click', function logTabsClick(e) {
diff --git a/app/assets/javascripts/pages/groups/edit/index.js b/app/assets/javascripts/pages/groups/edit/index.js
index bb91ac84ffb..8737f537296 100644
--- a/app/assets/javascripts/pages/groups/edit/index.js
+++ b/app/assets/javascripts/pages/groups/edit/index.js
@@ -1,9 +1,15 @@
import groupAvatar from '~/group_avatar';
import TransferDropdown from '~/groups/transfer_dropdown';
import initConfirmDangerModal from '~/confirm_danger_modal';
+import initSettingsPanels from '~/settings_panels';
document.addEventListener('DOMContentLoaded', () => {
groupAvatar();
new TransferDropdown(); // eslint-disable-line no-new
initConfirmDangerModal();
});
+
+document.addEventListener('DOMContentLoaded', () => {
+ // Initialize expandable settings panels
+ initSettingsPanels();
+});
diff --git a/app/assets/javascripts/pages/profiles/two_factor_auths/index.js b/app/assets/javascripts/pages/profiles/two_factor_auths/index.js
index fbdef329ab2..8e8f47c21d8 100644
--- a/app/assets/javascripts/pages/profiles/two_factor_auths/index.js
+++ b/app/assets/javascripts/pages/profiles/two_factor_auths/index.js
@@ -5,7 +5,7 @@ document.addEventListener('DOMContentLoaded', () => {
const twoFactorNode = document.querySelector('.js-two-factor-auth');
const skippable = twoFactorNode.dataset.twoFactorSkippable === 'true';
if (skippable) {
- const button = `<a class="btn btn-xs btn-warning pull-right" data-method="patch" href="${twoFactorNode.dataset.two_factor_skip_url}">Configure it later</a>`;
+ const button = `<a class="btn btn-sm btn-warning float-right" data-method="patch" href="${twoFactorNode.dataset.two_factor_skip_url}">Configure it later</a>`;
const flashAlert = document.querySelector('.flash-alert .container-fluid');
if (flashAlert) flashAlert.insertAdjacentHTML('beforeend', button);
}
diff --git a/app/assets/javascripts/pages/projects/clusters/gcp/new/index.js b/app/assets/javascripts/pages/projects/clusters/gcp/new/index.js
new file mode 100644
index 00000000000..d4f34e32a48
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/clusters/gcp/new/index.js
@@ -0,0 +1,5 @@
+import initGkeDropdowns from '~/projects/gke_cluster_dropdowns';
+
+document.addEventListener('DOMContentLoaded', () => {
+ initGkeDropdowns();
+});
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/project_setting_row.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/project_setting_row.vue
index 25a88f846eb..17b91479ea5 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/project_setting_row.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/project_setting_row.vue
@@ -42,7 +42,7 @@
</label>
<span
v-if="helpText"
- class="help-block"
+ class="form-text text-muted"
>
{{ helpText }}
</span>
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
index 755a34b7348..06b0ab184ed 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
@@ -213,7 +213,7 @@
</i>
</div>
</div>
- <span class="help-block">{{ visibilityLevelDescription }}</span>
+ <span class="form-text text-muted">{{ visibilityLevelDescription }}</span>
<label
v-if="visibilityLevel !== visibilityOptions.PRIVATE"
class="request-access"
diff --git a/app/assets/javascripts/pages/projects/wikis/wikis.js b/app/assets/javascripts/pages/projects/wikis/wikis.js
index 34a12ef76a1..dcd0b9a76ce 100644
--- a/app/assets/javascripts/pages/projects/wikis/wikis.js
+++ b/app/assets/javascripts/pages/projects/wikis/wikis.js
@@ -1,5 +1,7 @@
import bp from '../../../breakpoints';
import { slugify } from '../../../lib/utils/text_utility';
+import { parseQueryStringIntoObject } from '../../../lib/utils/common_utils';
+import { mergeUrlParams, redirectTo } from '../../../lib/utils/url_utility';
export default class Wikis {
constructor() {
@@ -28,7 +30,12 @@ export default class Wikis {
if (slug.length > 0) {
const wikisPath = slugInput.getAttribute('data-wikis-path');
- window.location.href = `${wikisPath}/${slug}`;
+
+ // If the wiki is empty, we need to merge the current URL params to keep the "create" view.
+ const params = parseQueryStringIntoObject(window.location.search.substr(1));
+ const url = mergeUrlParams(params, `${wikisPath}/${slug}`);
+ redirectTo(url);
+
e.preventDefault();
}
}
diff --git a/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js b/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js
index 53030045292..18c7b21cf8c 100644
--- a/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js
+++ b/app/assets/javascripts/pages/sessions/new/oauth_remember_me.js
@@ -5,7 +5,7 @@ import $ from 'jquery';
*
* Toggling this checkbox adds/removes a `remember_me` parameter to the
* login buttons' href, which is passed on to the omniauth callback.
- **/
+ */
export default class OAuthRememberMe {
constructor(opts = {}) {
diff --git a/app/assets/javascripts/pages/users/user_tabs.js b/app/assets/javascripts/pages/users/user_tabs.js
index 124bc2ba710..9404b06615e 100644
--- a/app/assets/javascripts/pages/users/user_tabs.js
+++ b/app/assets/javascripts/pages/users/user_tabs.js
@@ -77,10 +77,9 @@ export default class UserTabs {
this.action = action || this.defaultAction;
this.$parentEl = $(parentEl) || $(document);
this.windowLocation = window.location;
- this.$parentEl.find('.nav-links a')
- .each((i, navLink) => {
- this.loaded[$(navLink).attr('data-action')] = false;
- });
+ this.$parentEl.find('.nav-links a').each((i, navLink) => {
+ this.loaded[$(navLink).attr('data-action')] = false;
+ });
this.actions = Object.keys(this.loaded);
this.bindEvents();
@@ -116,8 +115,7 @@ export default class UserTabs {
}
activateTab(action) {
- return this.$parentEl.find(`.nav-links .js-${action}-tab a`)
- .tab('show');
+ return this.$parentEl.find(`.nav-links .js-${action}-tab a`).tab('show');
}
setTab(action, endpoint) {
@@ -137,7 +135,8 @@ export default class UserTabs {
loadTab(action, endpoint) {
this.toggleLoading(true);
- return axios.get(endpoint)
+ return axios
+ .get(endpoint)
.then(({ data }) => {
const tabSelector = `div#${action}`;
this.$parentEl.find(tabSelector).html(data.html);
@@ -161,10 +160,11 @@ export default class UserTabs {
const utcOffset = $calendarWrap.data('utcOffset');
let utcFormatted = 'UTC';
if (utcOffset !== 0) {
- utcFormatted = `UTC${utcOffset > 0 ? '+' : ''}${(utcOffset / 3600)}`;
+ utcFormatted = `UTC${utcOffset > 0 ? '+' : ''}${utcOffset / 3600}`;
}
- axios.get(calendarPath)
+ axios
+ .get(calendarPath)
.then(({ data }) => {
$calendarWrap.html(CALENDAR_TEMPLATE);
$calendarWrap.find('.calendar-hint').append(`(Timezone: ${utcFormatted})`);
@@ -180,21 +180,24 @@ export default class UserTabs {
}
toggleLoading(status) {
- return this.$parentEl.find('.loading-status .loading')
- .toggle(status);
+ return this.$parentEl.find('.loading-status .loading').toggleClass('hidden', !status);
}
setCurrentAction(source) {
let newState = source;
newState = newState.replace(/\/+$/, '');
newState += this.windowLocation.search + this.windowLocation.hash;
- history.replaceState({
- url: newState,
- }, document.title, newState);
+ history.replaceState(
+ {
+ url: newState,
+ },
+ document.title,
+ newState,
+ );
return newState;
}
getCurrentAction() {
- return this.$parentEl.find('.nav-links .active a').data('action');
+ return this.$parentEl.find('.nav-links a.active').data('action');
}
}
diff --git a/app/assets/javascripts/performance_bar/components/request_selector.vue b/app/assets/javascripts/performance_bar/components/request_selector.vue
index 3ed07a4a47d..dd9578a6c7f 100644
--- a/app/assets/javascripts/performance_bar/components/request_selector.vue
+++ b/app/assets/javascripts/performance_bar/components/request_selector.vue
@@ -37,7 +37,7 @@ export default {
<template>
<div
id="peek-request-selector"
- class="pull-right"
+ class="float-right"
>
<select v-model="currentRequestId">
<option
diff --git a/app/assets/javascripts/pipelines/components/blank_state.vue b/app/assets/javascripts/pipelines/components/blank_state.vue
index 8d3d6223d7b..f3219b8291c 100644
--- a/app/assets/javascripts/pipelines/components/blank_state.vue
+++ b/app/assets/javascripts/pipelines/components/blank_state.vue
@@ -17,13 +17,13 @@
<template>
<div class="row empty-state">
- <div class="col-xs-12">
+ <div class="col-12">
<div class="svg-content">
<img :src="svgPath" />
</div>
</div>
- <div class="col-xs-12 text-center">
+ <div class="col-12 text-center">
<div class="text-content">
<h4>{{ message }}</h4>
</div>
diff --git a/app/assets/javascripts/pipelines/components/empty_state.vue b/app/assets/javascripts/pipelines/components/empty_state.vue
index 10ac8c08bed..50c27bed9fd 100644
--- a/app/assets/javascripts/pipelines/components/empty_state.vue
+++ b/app/assets/javascripts/pipelines/components/empty_state.vue
@@ -19,13 +19,13 @@
</script>
<template>
<div class="row empty-state js-empty-state">
- <div class="col-xs-12">
+ <div class="col-12">
<div class="svg-content svg-250">
<img :src="emptyStateSvgPath" />
</div>
</div>
- <div class="col-xs-12">
+ <div class="col-12">
<div class="text-content">
<template v-if="canSetCi">
@@ -34,7 +34,7 @@
</h4>
<p>
- {{ s__(`Pipelines|Continous Integration can help
+ {{ s__(`Pipelines|Continuous Integration can help
catch bugs by running your tests automatically,
while Continuous Deployment can help you deliver
code to your product environment.`) }}
diff --git a/app/assets/javascripts/pipelines/components/graph/job_component.vue b/app/assets/javascripts/pipelines/components/graph/job_component.vue
index 27b938c4985..dc16d395bcb 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_component.vue
@@ -96,6 +96,7 @@ export default {
:class="cssClassJobName"
data-container="body"
data-html="true"
+ data-boundary="viewport"
class="js-pipeline-graph-job-link"
>
diff --git a/app/assets/javascripts/pipelines/components/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipeline_url.vue
index ceb4d9ca604..4d965733f95 100644
--- a/app/assets/javascripts/pipelines/components/pipeline_url.vue
+++ b/app/assets/javascripts/pipelines/components/pipeline_url.vue
@@ -46,7 +46,7 @@
};
</script>
<template>
- <div class="table-section section-15 hidden-xs hidden-sm pipeline-tags">
+ <div class="table-section section-15 d-none d-sm-none d-md-block pipeline-tags">
<a
:href="pipeline.path"
class="js-pipeline-url-link">
@@ -69,35 +69,35 @@
<span
v-if="pipeline.flags.latest"
v-tooltip
- class="js-pipeline-url-latest label label-success"
+ class="js-pipeline-url-latest badge badge-success"
title="Latest pipeline for this branch">
latest
</span>
<span
v-if="pipeline.flags.yaml_errors"
v-tooltip
- class="js-pipeline-url-yaml label label-danger"
+ class="js-pipeline-url-yaml badge badge-danger"
:title="pipeline.yaml_errors">
yaml invalid
</span>
<span
v-if="pipeline.flags.failure_reason"
v-tooltip
- class="js-pipeline-url-failure label label-danger"
+ class="js-pipeline-url-failure badge badge-danger"
:title="pipeline.failure_reason">
error
</span>
<a
v-if="pipeline.flags.auto_devops"
tabindex="0"
- class="js-pipeline-url-autodevops label label-info autodevops-badge"
+ class="js-pipeline-url-autodevops badge badge-info autodevops-badge"
v-popover="popoverOptions"
role="button">
Auto DevOps
</a>
<span
v-if="pipeline.flags.stuck"
- class="js-pipeline-url-stuck label label-warning">
+ class="js-pipeline-url-stuck badge badge-warning">
stuck
</span>
</div>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_actions.vue
index 3297af7bde4..e9bc3cf14ca 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_actions.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_actions.vue
@@ -63,7 +63,7 @@
<loading-icon v-if="isLoading" />
</button>
- <ul class="dropdown-menu dropdown-menu-align-right">
+ <ul class="dropdown-menu dropdown-menu-right">
<li
v-for="(action, i) in actions"
:key="i"
diff --git a/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue b/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue
index 1b9e0f917a4..31fcc9dd412 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue
@@ -37,7 +37,7 @@
>
</i>
</button>
- <ul class="dropdown-menu dropdown-menu-align-right">
+ <ul class="dropdown-menu dropdown-menu-right">
<li
v-for="(artifact, i) in artifacts"
:key="i">
diff --git a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
index b99246a92d0..a3c17479e6f 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
@@ -331,7 +331,7 @@
<pipelines-artifacts-component
v-if="pipeline.details.artifacts.length"
- class="hidden-xs hidden-sm"
+ class="d-none d-sm-none d-md-block"
:artifacts="pipeline.details.artifacts"
/>
diff --git a/app/assets/javascripts/pipelines/components/time_ago.vue b/app/assets/javascripts/pipelines/components/time_ago.vue
index cd54d26c9d3..79dbdca4010 100644
--- a/app/assets/javascripts/pipelines/components/time_ago.vue
+++ b/app/assets/javascripts/pipelines/components/time_ago.vue
@@ -75,7 +75,7 @@
</p>
<p
- class="finished-at hidden-xs hidden-sm"
+ class="finished-at d-none d-sm-none d-md-block"
v-if="hasFinishedTime"
>
diff --git a/app/assets/javascripts/profile/account/components/update_username.vue b/app/assets/javascripts/profile/account/components/update_username.vue
index e5de3f69b01..b37febe523c 100644
--- a/app/assets/javascripts/profile/account/components/update_username.vue
+++ b/app/assets/javascripts/profile/account/components/update_username.vue
@@ -86,7 +86,11 @@ Please update your Git repository remotes as soon as possible.`),
<div class="form-group">
<label :for="$options.inputId">{{ s__('Profiles|Path') }}</label>
<div class="input-group">
- <div class="input-group-addon">{{ rootUrl }}</div>
+ <div class="input-group-prepend">
+ <div class="input-group-text">
+ {{ rootUrl }}
+ </div>
+ </div>
<input
:id="$options.inputId"
class="form-control"
@@ -95,7 +99,7 @@ Please update your Git repository remotes as soon as possible.`),
:disabled="isRequestPending"
/>
</div>
- <p class="help-block">
+ <p class="form-text text-muted">
{{ path }}
</p>
</div>
diff --git a/app/assets/javascripts/project_fork.js b/app/assets/javascripts/project_fork.js
index 6fedd94a6a9..f5cd1c3cc3e 100644
--- a/app/assets/javascripts/project_fork.js
+++ b/app/assets/javascripts/project_fork.js
@@ -4,6 +4,6 @@ export default () => {
$('.js-fork-thumbnail').on('click', function forkThumbnailClicked() {
if ($(this).hasClass('disabled')) return false;
- return $('.js-fork-content').toggle();
+ return $('.js-fork-content').toggleClass('hidden');
});
};
diff --git a/app/assets/javascripts/project_label_subscription.js b/app/assets/javascripts/project_label_subscription.js
index f31beb4dc78..6f06944ebb6 100644
--- a/app/assets/javascripts/project_label_subscription.js
+++ b/app/assets/javascripts/project_label_subscription.js
@@ -42,7 +42,7 @@ export default class ProjectLabelSubscription {
const $button = $(button);
if ($button.attr('data-original-title')) {
- $button.tooltip('hide').attr('data-original-title', newAction).tooltip('fixTitle');
+ $button.tooltip('hide').attr('data-original-title', newAction).tooltip('_fixTitle');
}
return button;
diff --git a/app/assets/javascripts/project_visibility.js b/app/assets/javascripts/project_visibility.js
index 7c95c71e239..a52ac768e57 100644
--- a/app/assets/javascripts/project_visibility.js
+++ b/app/assets/javascripts/project_visibility.js
@@ -7,7 +7,7 @@ function setVisibilityOptions(namespaceSelector) {
const selectedNamespace = namespaceSelector.options[namespaceSelector.selectedIndex];
const { name, visibility, visibilityLevel, showPath, editPath } = selectedNamespace.dataset;
- document.querySelectorAll('.visibility-level-setting .radio').forEach((option) => {
+ document.querySelectorAll('.visibility-level-setting .form-check').forEach((option) => {
const optionInput = option.querySelector('input[type=radio]');
const optionValue = optionInput ? optionInput.value : 0;
const optionTitle = option.querySelector('.option-title');
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_dropdown_mixin.js b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_dropdown_mixin.js
new file mode 100644
index 00000000000..c15d8ba49e1
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_dropdown_mixin.js
@@ -0,0 +1,71 @@
+import _ from 'underscore';
+import LoadingIcon from '~/vue_shared/components/loading_icon.vue';
+import DropdownSearchInput from '~/vue_shared/components/dropdown/dropdown_search_input.vue';
+import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue';
+import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue';
+
+import store from '../store';
+
+export default {
+ store,
+ components: {
+ LoadingIcon,
+ DropdownButton,
+ DropdownSearchInput,
+ DropdownHiddenInput,
+ },
+ props: {
+ fieldId: {
+ type: String,
+ required: true,
+ },
+ fieldName: {
+ type: String,
+ required: true,
+ },
+ defaultValue: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ data() {
+ return {
+ isLoading: false,
+ hasErrors: false,
+ searchQuery: '',
+ gapiError: '',
+ };
+ },
+ computed: {
+ results() {
+ if (!this.items) {
+ return [];
+ }
+
+ return this.items.filter(item => item.name.toLowerCase().indexOf(this.searchQuery) > -1);
+ },
+ },
+ methods: {
+ fetchSuccessHandler() {
+ if (this.defaultValue) {
+ const itemToSelect = _.find(this.items, item => item.name === this.defaultValue);
+
+ if (itemToSelect) {
+ this.setItem(itemToSelect.name);
+ }
+ }
+
+ this.isLoading = false;
+ this.hasErrors = false;
+ },
+ fetchFailureHandler(resp) {
+ this.isLoading = false;
+ this.hasErrors = true;
+
+ if (resp.result && resp.result.error) {
+ this.gapiError = resp.result.error.message;
+ }
+ },
+ },
+};
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown.vue b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown.vue
new file mode 100644
index 00000000000..ab7d2d41ece
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown.vue
@@ -0,0 +1,142 @@
+<script>
+import { sprintf, s__ } from '~/locale';
+import { mapState, mapGetters, mapActions } from 'vuex';
+
+import gkeDropdownMixin from './gke_dropdown_mixin';
+
+export default {
+ name: 'GkeMachineTypeDropdown',
+ mixins: [gkeDropdownMixin],
+ computed: {
+ ...mapState([
+ 'isValidatingProjectBilling',
+ 'projectHasBillingEnabled',
+ 'selectedZone',
+ 'selectedMachineType',
+ ]),
+ ...mapState({ items: 'machineTypes' }),
+ ...mapGetters(['hasZone', 'hasMachineType']),
+ allDropdownsSelected() {
+ return this.projectHasBillingEnabled && this.hasZone && this.hasMachineType;
+ },
+ isDisabled() {
+ return (
+ this.isLoading ||
+ this.isValidatingProjectBilling ||
+ !this.projectHasBillingEnabled ||
+ !this.hasZone
+ );
+ },
+ toggleText() {
+ if (this.isLoading) {
+ return s__('ClusterIntegration|Fetching machine types');
+ }
+
+ if (this.selectedMachineType) {
+ return this.selectedMachineType;
+ }
+
+ if (!this.projectHasBillingEnabled && !this.hasZone) {
+ return s__('ClusterIntegration|Select project and zone to choose machine type');
+ }
+
+ return !this.hasZone
+ ? s__('ClusterIntegration|Select zone to choose machine type')
+ : s__('ClusterIntegration|Select machine type');
+ },
+ errorMessage() {
+ return sprintf(
+ s__(
+ 'ClusterIntegration|An error occured while trying to fetch zone machine types: %{error}',
+ ),
+ { error: this.gapiError },
+ );
+ },
+ },
+ watch: {
+ selectedZone() {
+ this.hasErrors = false;
+
+ if (this.hasZone) {
+ this.isLoading = true;
+
+ this.fetchMachineTypes()
+ .then(this.fetchSuccessHandler)
+ .catch(this.fetchFailureHandler);
+ }
+ },
+ selectedMachineType() {
+ this.enableSubmit();
+ },
+ },
+ methods: {
+ ...mapActions(['fetchMachineTypes']),
+ ...mapActions({ setItem: 'setMachineType' }),
+ enableSubmit() {
+ if (this.allDropdownsSelected) {
+ const submitButtonEl = document.querySelector('.js-gke-cluster-creation-submit');
+
+ if (submitButtonEl) {
+ submitButtonEl.removeAttribute('disabled');
+ }
+ }
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div
+ class="js-gcp-machine-type-dropdown dropdown"
+ :class="{ 'gl-show-field-errors': hasErrors }"
+ >
+ <dropdown-hidden-input
+ :name="fieldName"
+ :value="selectedMachineType"
+ />
+ <dropdown-button
+ :class="{ 'gl-field-error-outline': hasErrors }"
+ :is-disabled="isDisabled"
+ :is-loading="isLoading"
+ :toggle-text="toggleText"
+ />
+ <div class="dropdown-menu dropdown-select">
+ <dropdown-search-input
+ v-model="searchQuery"
+ :placeholder-text="s__('ClusterIntegration|Search machine types')"
+ />
+ <div class="dropdown-content">
+ <ul>
+ <li v-show="!results.length">
+ <span class="menu-item">
+ {{ s__('ClusterIntegration|No machine types matched your search') }}
+ </span>
+ </li>
+ <li
+ v-for="result in results"
+ :key="result.id"
+ >
+ <button
+ type="button"
+ @click.prevent="setItem(result.name)"
+ >
+ {{ result.name }}
+ </button>
+ </li>
+ </ul>
+ </div>
+ <div class="dropdown-loading">
+ <loading-icon />
+ </div>
+ </div>
+ </div>
+ <span
+ class="form-text text-muted"
+ :class="{ 'gl-field-error': hasErrors }"
+ v-if="hasErrors"
+ >
+ {{ errorMessage }}
+ </span>
+ </div>
+</template>
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown.vue b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown.vue
new file mode 100644
index 00000000000..25350ef0fa9
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown.vue
@@ -0,0 +1,201 @@
+<script>
+import _ from 'underscore';
+import { s__, sprintf } from '~/locale';
+import { mapState, mapGetters, mapActions } from 'vuex';
+
+import gkeDropdownMixin from './gke_dropdown_mixin';
+
+export default {
+ name: 'GkeProjectIdDropdown',
+ mixins: [gkeDropdownMixin],
+ props: {
+ docsUrl: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapState(['selectedProject', 'isValidatingProjectBilling', 'projectHasBillingEnabled']),
+ ...mapState({ items: 'projects' }),
+ ...mapGetters(['hasProject']),
+ hasOneProject() {
+ return this.items && this.items.length === 1;
+ },
+ isDisabled() {
+ return (
+ this.isLoading || this.isValidatingProjectBilling || (this.items && this.items.length < 2)
+ );
+ },
+ toggleText() {
+ if (this.isValidatingProjectBilling) {
+ return s__('ClusterIntegration|Validating project billing status');
+ }
+
+ if (this.isLoading) {
+ return s__('ClusterIntegration|Fetching projects');
+ }
+
+ if (this.hasProject) {
+ return this.selectedProject.name;
+ }
+
+ if (!this.items) {
+ return s__('ClusterIntegration|No projects found');
+ }
+
+ return s__('ClusterIntegration|Select project');
+ },
+ helpText() {
+ let message;
+ if (this.hasErrors) {
+ return this.errorMessage;
+ }
+
+ if (!this.items) {
+ message =
+ 'ClusterIntegration|We were unable to fetch any projects. Ensure that you have a project on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}.';
+ }
+
+ message =
+ this.items && this.items.length
+ ? 'ClusterIntegration|To use a new project, first create one on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}.'
+ : 'ClusterIntegration|To create a cluster, first create a project on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}.';
+
+ return sprintf(
+ s__(message),
+ {
+ docsLinkEnd: '&nbsp;<i class="fa fa-external-link" aria-hidden="true"></i></a>',
+ docsLinkStart: `<a href="${_.escape(
+ this.docsUrl,
+ )}" target="_blank" rel="noopener noreferrer">`,
+ },
+ false,
+ );
+ },
+ errorMessage() {
+ if (!this.projectHasBillingEnabled) {
+ if (this.gapiError) {
+ return s__(
+ 'ClusterIntegration|We could not verify that one of your projects on GCP has billing enabled. Please try again.',
+ );
+ }
+
+ return sprintf(
+ s__(
+ 'This project does not have billing enabled. To create a cluster, <a href=%{linkToBilling} target="_blank" rel="noopener noreferrer">enable billing <i class="fa fa-external-link" aria-hidden="true"></i></a> and try again.',
+ ),
+ {
+ linkToBilling:
+ 'https://console.cloud.google.com/freetrial?utm_campaign=2018_cpanel&utm_source=gitlab&utm_medium=referral',
+ },
+ false,
+ );
+ }
+
+ return sprintf(
+ s__('ClusterIntegration|An error occured while trying to fetch your projects: %{error}'),
+ { error: this.gapiError },
+ );
+ },
+ },
+ watch: {
+ selectedProject() {
+ this.setIsValidatingProjectBilling(true);
+
+ this.validateProjectBilling()
+ .then(this.validateProjectBillingSuccessHandler)
+ .catch(this.validateProjectBillingFailureHandler);
+ },
+ },
+ created() {
+ this.isLoading = true;
+
+ this.fetchProjects()
+ .then(this.fetchSuccessHandler)
+ .catch(this.fetchFailureHandler);
+ },
+ methods: {
+ ...mapActions(['fetchProjects', 'setIsValidatingProjectBilling', 'validateProjectBilling']),
+ ...mapActions({ setItem: 'setProject' }),
+ fetchSuccessHandler() {
+ if (this.defaultValue) {
+ const projectToSelect = _.find(this.items, item => item.projectId === this.defaultValue);
+
+ if (projectToSelect) {
+ this.setItem(projectToSelect);
+ }
+ } else if (this.items.length === 1) {
+ this.setItem(this.items[0]);
+ }
+
+ this.isLoading = false;
+ this.hasErrors = false;
+ },
+ validateProjectBillingSuccessHandler() {
+ this.hasErrors = !this.projectHasBillingEnabled;
+ },
+ validateProjectBillingFailureHandler(resp) {
+ this.hasErrors = true;
+
+ this.gapiError = resp.result ? resp.result.error.message : resp;
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div
+ class="js-gcp-project-id-dropdown dropdown"
+ :class="{ 'gl-show-field-errors': hasErrors }"
+ >
+ <dropdown-hidden-input
+ :name="fieldName"
+ :value="selectedProject.projectId"
+ />
+ <dropdown-button
+ :class="{
+ 'gl-field-error-outline': hasErrors,
+ 'read-only': hasOneProject
+ }"
+ :is-disabled="isDisabled"
+ :is-loading="isLoading"
+ :toggle-text="toggleText"
+ />
+ <div class="dropdown-menu dropdown-select">
+ <dropdown-search-input
+ v-model="searchQuery"
+ :placeholder-text="s__('ClusterIntegration|Search projects')"
+ />
+ <div class="dropdown-content">
+ <ul>
+ <li v-show="!results.length">
+ <span class="menu-item">
+ {{ s__('ClusterIntegration|No projects matched your search') }}
+ </span>
+ </li>
+ <li
+ v-for="result in results"
+ :key="result.project_number"
+ >
+ <button
+ type="button"
+ @click.prevent="setItem(result)"
+ >
+ {{ result.name }}
+ </button>
+ </li>
+ </ul>
+ </div>
+ <div class="dropdown-loading">
+ <loading-icon />
+ </div>
+ </div>
+ </div>
+ <span
+ class="form-text text-muted"
+ :class="{ 'gl-field-error': hasErrors }"
+ v-html="helpText"
+ ></span>
+ </div>
+</template>
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown.vue b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown.vue
new file mode 100644
index 00000000000..8ee4eefcd91
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown.vue
@@ -0,0 +1,116 @@
+<script>
+import { sprintf, s__ } from '~/locale';
+import { mapState, mapActions } from 'vuex';
+
+import gkeDropdownMixin from './gke_dropdown_mixin';
+
+export default {
+ name: 'GkeZoneDropdown',
+ mixins: [gkeDropdownMixin],
+ computed: {
+ ...mapState([
+ 'selectedProject',
+ 'selectedZone',
+ 'projects',
+ 'isValidatingProjectBilling',
+ 'projectHasBillingEnabled',
+ ]),
+ ...mapState({ items: 'zones' }),
+ isDisabled() {
+ return this.isLoading || this.isValidatingProjectBilling || !this.projectHasBillingEnabled;
+ },
+ toggleText() {
+ if (this.isLoading) {
+ return s__('ClusterIntegration|Fetching zones');
+ }
+
+ if (this.selectedZone) {
+ return this.selectedZone;
+ }
+
+ return !this.projectHasBillingEnabled
+ ? s__('ClusterIntegration|Select project to choose zone')
+ : s__('ClusterIntegration|Select zone');
+ },
+ errorMessage() {
+ return sprintf(
+ s__('ClusterIntegration|An error occured while trying to fetch project zones: %{error}'),
+ { error: this.gapiError },
+ );
+ },
+ },
+ watch: {
+ isValidatingProjectBilling(isValidating) {
+ this.hasErrors = false;
+
+ if (!isValidating && this.projectHasBillingEnabled) {
+ this.isLoading = true;
+
+ this.fetchZones()
+ .then(this.fetchSuccessHandler)
+ .catch(this.fetchFailureHandler);
+ }
+ },
+ },
+ methods: {
+ ...mapActions(['fetchZones']),
+ ...mapActions({ setItem: 'setZone' }),
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div
+ class="js-gcp-zone-dropdown dropdown"
+ :class="{ 'gl-show-field-errors': hasErrors }"
+ >
+ <dropdown-hidden-input
+ :name="fieldName"
+ :value="selectedZone"
+ />
+ <dropdown-button
+ :class="{ 'gl-field-error-outline': hasErrors }"
+ :is-disabled="isDisabled"
+ :is-loading="isLoading"
+ :toggle-text="toggleText"
+ />
+ <div class="dropdown-menu dropdown-select">
+ <dropdown-search-input
+ v-model="searchQuery"
+ :placeholder-text="s__('ClusterIntegration|Search zones')"
+ />
+ <div class="dropdown-content">
+ <ul>
+ <li v-show="!results.length">
+ <span class="menu-item">
+ {{ s__('ClusterIntegration|No zones matched your search') }}
+ </span>
+ </li>
+ <li
+ v-for="result in results"
+ :key="result.id"
+ >
+ <button
+ type="button"
+ @click.prevent="setItem(result.name)"
+ >
+ {{ result.name }}
+ </button>
+ </li>
+ </ul>
+ </div>
+ <div class="dropdown-loading">
+ <loading-icon />
+ </div>
+ </div>
+ </div>
+ <span
+ class="form-text text-muted"
+ :class="{ 'gl-field-error': hasErrors }"
+ v-if="hasErrors"
+ >
+ {{ errorMessage }}
+ </span>
+ </div>
+</template>
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/constants.js b/app/assets/javascripts/projects/gke_cluster_dropdowns/constants.js
new file mode 100644
index 00000000000..2a1c0819916
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/constants.js
@@ -0,0 +1,11 @@
+import { s__ } from '~/locale';
+
+export const GCP_API_ERROR = s__(
+ 'ClusterIntegration|An error occurred when trying to contact the Google Cloud API. Please try again later.',
+);
+export const GCP_API_CLOUD_BILLING_ENDPOINT =
+ 'https://www.googleapis.com/discovery/v1/apis/cloudbilling/v1/rest';
+export const GCP_API_CLOUD_RESOURCE_MANAGER_ENDPOINT =
+ 'https://www.googleapis.com/discovery/v1/apis/cloudresourcemanager/v1/rest';
+export const GCP_API_COMPUTE_ENDPOINT =
+ 'https://www.googleapis.com/discovery/v1/apis/compute/v1/rest';
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/index.js b/app/assets/javascripts/projects/gke_cluster_dropdowns/index.js
new file mode 100644
index 00000000000..729b9404b64
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/index.js
@@ -0,0 +1,88 @@
+/* global gapi */
+import Vue from 'vue';
+import Flash from '~/flash';
+import GkeProjectIdDropdown from './components/gke_project_id_dropdown.vue';
+import GkeZoneDropdown from './components/gke_zone_dropdown.vue';
+import GkeMachineTypeDropdown from './components/gke_machine_type_dropdown.vue';
+import * as CONSTANTS from './constants';
+
+const mountComponent = (entryPoint, component, componentName, extraProps = {}) => {
+ const el = document.querySelector(entryPoint);
+ if (!el) return false;
+
+ const hiddenInput = el.querySelector('input');
+
+ return new Vue({
+ el,
+ components: {
+ [componentName]: component,
+ },
+ render: createElement =>
+ createElement(componentName, {
+ props: {
+ fieldName: hiddenInput.getAttribute('name'),
+ fieldId: hiddenInput.getAttribute('id'),
+ defaultValue: hiddenInput.value,
+ ...extraProps,
+ },
+ }),
+ });
+};
+
+const mountGkeProjectIdDropdown = () => {
+ const entryPoint = '.js-gcp-project-id-dropdown-entry-point';
+ const el = document.querySelector(entryPoint);
+
+ mountComponent(entryPoint, GkeProjectIdDropdown, 'gke-project-id-dropdown', {
+ docsUrl: el.dataset.docsurl,
+ });
+};
+
+const mountGkeZoneDropdown = () => {
+ mountComponent('.js-gcp-zone-dropdown-entry-point', GkeZoneDropdown, 'gke-zone-dropdown');
+};
+
+const mountGkeMachineTypeDropdown = () => {
+ mountComponent(
+ '.js-gcp-machine-type-dropdown-entry-point',
+ GkeMachineTypeDropdown,
+ 'gke-machine-type-dropdown',
+ );
+};
+
+const gkeDropdownErrorHandler = () => {
+ Flash(CONSTANTS.GCP_API_ERROR);
+};
+
+const initializeGapiClient = () => {
+ const el = document.querySelector('.js-gke-cluster-creation');
+ if (!el) return false;
+
+ return gapi.client
+ .init({
+ discoveryDocs: [
+ CONSTANTS.GCP_API_CLOUD_BILLING_ENDPOINT,
+ CONSTANTS.GCP_API_CLOUD_RESOURCE_MANAGER_ENDPOINT,
+ CONSTANTS.GCP_API_COMPUTE_ENDPOINT,
+ ],
+ })
+ .then(() => {
+ gapi.client.setToken({ access_token: el.dataset.token });
+
+ mountGkeProjectIdDropdown();
+ mountGkeZoneDropdown();
+ mountGkeMachineTypeDropdown();
+ })
+ .catch(gkeDropdownErrorHandler);
+};
+
+const initGkeDropdowns = () => {
+ if (!gapi) {
+ gkeDropdownErrorHandler();
+ return false;
+ }
+
+ return gapi.load('client', initializeGapiClient);
+};
+
+export default initGkeDropdowns;
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/store/actions.js b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/actions.js
new file mode 100644
index 00000000000..4834a856271
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/actions.js
@@ -0,0 +1,95 @@
+/* global gapi */
+import * as types from './mutation_types';
+
+const gapiResourceListRequest = ({ resource, params, commit, mutation, payloadKey }) =>
+ new Promise((resolve, reject) => {
+ const request = resource.list(params);
+
+ return request.then(
+ resp => {
+ const { result } = resp;
+
+ commit(mutation, result[payloadKey]);
+
+ resolve();
+ },
+ resp => {
+ reject(resp);
+ },
+ );
+ });
+
+export const setProject = ({ commit }, selectedProject) => {
+ commit(types.SET_PROJECT, selectedProject);
+};
+
+export const setZone = ({ commit }, selectedZone) => {
+ commit(types.SET_ZONE, selectedZone);
+};
+
+export const setMachineType = ({ commit }, selectedMachineType) => {
+ commit(types.SET_MACHINE_TYPE, selectedMachineType);
+};
+
+export const setIsValidatingProjectBilling = ({ commit }, isValidatingProjectBilling) => {
+ commit(types.SET_IS_VALIDATING_PROJECT_BILLING, isValidatingProjectBilling);
+};
+
+export const fetchProjects = ({ commit }) =>
+ gapiResourceListRequest({
+ resource: gapi.client.cloudresourcemanager.projects,
+ params: {},
+ commit,
+ mutation: types.SET_PROJECTS,
+ payloadKey: 'projects',
+ });
+
+export const validateProjectBilling = ({ dispatch, commit, state }) =>
+ new Promise((resolve, reject) => {
+ const request = gapi.client.cloudbilling.projects.getBillingInfo({
+ name: `projects/${state.selectedProject.projectId}`,
+ });
+
+ commit(types.SET_ZONE, '');
+ commit(types.SET_MACHINE_TYPE, '');
+
+ return request.then(
+ resp => {
+ const { billingEnabled } = resp.result;
+
+ commit(types.SET_PROJECT_BILLING_STATUS, !!billingEnabled);
+ dispatch('setIsValidatingProjectBilling', false);
+ resolve();
+ },
+ resp => {
+ dispatch('setIsValidatingProjectBilling', false);
+ reject(resp);
+ },
+ );
+ });
+
+export const fetchZones = ({ commit, state }) =>
+ gapiResourceListRequest({
+ resource: gapi.client.compute.zones,
+ params: {
+ project: state.selectedProject.projectId,
+ },
+ commit,
+ mutation: types.SET_ZONES,
+ payloadKey: 'items',
+ });
+
+export const fetchMachineTypes = ({ commit, state }) =>
+ gapiResourceListRequest({
+ resource: gapi.client.compute.machineTypes,
+ params: {
+ project: state.selectedProject.projectId,
+ zone: state.selectedZone,
+ },
+ commit,
+ mutation: types.SET_MACHINE_TYPES,
+ payloadKey: 'items',
+ });
+
+// prevent babel-plugin-rewire from generating an invalid default during karma tests
+export default () => {};
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/store/getters.js b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/getters.js
new file mode 100644
index 00000000000..e39f02d0894
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/getters.js
@@ -0,0 +1,3 @@
+export const hasProject = state => !!state.selectedProject.projectId;
+export const hasZone = state => !!state.selectedZone;
+export const hasMachineType = state => !!state.selectedMachineType;
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/store/index.js b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/index.js
new file mode 100644
index 00000000000..5f72060633e
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/index.js
@@ -0,0 +1,18 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import * as actions from './actions';
+import * as getters from './getters';
+import mutations from './mutations';
+import createState from './state';
+
+Vue.use(Vuex);
+
+export const createStore = () =>
+ new Vuex.Store({
+ actions,
+ getters,
+ mutations,
+ state: createState(),
+ });
+
+export default createStore();
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/store/mutation_types.js b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/mutation_types.js
new file mode 100644
index 00000000000..45a91efc2d9
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/mutation_types.js
@@ -0,0 +1,8 @@
+export const SET_PROJECT = 'SET_PROJECT';
+export const SET_PROJECT_BILLING_STATUS = 'SET_PROJECT_BILLING_STATUS';
+export const SET_IS_VALIDATING_PROJECT_BILLING = 'SET_IS_VALIDATING_PROJECT_BILLING';
+export const SET_ZONE = 'SET_ZONE';
+export const SET_MACHINE_TYPE = 'SET_MACHINE_TYPE';
+export const SET_PROJECTS = 'SET_PROJECTS';
+export const SET_ZONES = 'SET_ZONES';
+export const SET_MACHINE_TYPES = 'SET_MACHINE_TYPES';
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/store/mutations.js b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/mutations.js
new file mode 100644
index 00000000000..88a2c1b630d
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/mutations.js
@@ -0,0 +1,28 @@
+import * as types from './mutation_types';
+
+export default {
+ [types.SET_PROJECT](state, selectedProject) {
+ Object.assign(state, { selectedProject });
+ },
+ [types.SET_IS_VALIDATING_PROJECT_BILLING](state, isValidatingProjectBilling) {
+ Object.assign(state, { isValidatingProjectBilling });
+ },
+ [types.SET_PROJECT_BILLING_STATUS](state, projectHasBillingEnabled) {
+ Object.assign(state, { projectHasBillingEnabled });
+ },
+ [types.SET_ZONE](state, selectedZone) {
+ Object.assign(state, { selectedZone });
+ },
+ [types.SET_MACHINE_TYPE](state, selectedMachineType) {
+ Object.assign(state, { selectedMachineType });
+ },
+ [types.SET_PROJECTS](state, projects) {
+ Object.assign(state, { projects });
+ },
+ [types.SET_ZONES](state, zones) {
+ Object.assign(state, { zones });
+ },
+ [types.SET_MACHINE_TYPES](state, machineTypes) {
+ Object.assign(state, { machineTypes });
+ },
+};
diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/store/state.js b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/state.js
new file mode 100644
index 00000000000..9f3c473d4bc
--- /dev/null
+++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/store/state.js
@@ -0,0 +1,13 @@
+export default () => ({
+ selectedProject: {
+ projectId: '',
+ name: '',
+ },
+ selectedZone: '',
+ selectedMachineType: '',
+ isValidatingProjectBilling: null,
+ projectHasBillingEnabled: null,
+ projects: [],
+ zones: [],
+ machineTypes: [],
+});
diff --git a/app/assets/javascripts/projects/project_new.js b/app/assets/javascripts/projects/project_new.js
index 93603dfc14d..888b1d6ce33 100644
--- a/app/assets/javascripts/projects/project_new.js
+++ b/app/assets/javascripts/projects/project_new.js
@@ -66,8 +66,8 @@ const bindEvents = () => {
.on('click', (e) => { e.preventDefault(); })
.popover({
title: $pushNewProjectTipTrigger.data('title'),
- placement: 'auto bottom',
- html: 'true',
+ placement: 'bottom',
+ html: true,
content: $('.push-new-project-tip-template').html(),
})
.on('shown.bs.popover', () => {
diff --git a/app/assets/javascripts/projects_dropdown/components/search.vue b/app/assets/javascripts/projects_dropdown/components/search.vue
index 0c46ed184be..7fcd62dcdb8 100644
--- a/app/assets/javascripts/projects_dropdown/components/search.vue
+++ b/app/assets/javascripts/projects_dropdown/components/search.vue
@@ -46,7 +46,7 @@
<template>
<div
- class="search-input-container hidden-xs"
+ class="search-input-container d-none d-sm-block"
>
<input
type="search"
diff --git a/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js b/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js
index 0a60f4845b2..1a75fdd75db 100644
--- a/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js
+++ b/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js
@@ -31,7 +31,7 @@ export default class PrometheusMetrics {
/* eslint-disable class-methods-use-this */
handlePanelToggle(e) {
const $toggleBtn = $(e.currentTarget);
- const $currentPanelBody = $toggleBtn.closest('.panel').find('.panel-body');
+ const $currentPanelBody = $toggleBtn.closest('.card').find('.card-body');
$currentPanelBody.toggleClass('hidden');
if ($toggleBtn.hasClass('fa-caret-down')) {
$toggleBtn.removeClass('fa-caret-down').addClass('fa-caret-right');
diff --git a/app/assets/javascripts/raven/raven_config.js b/app/assets/javascripts/raven/raven_config.js
index ae54fa5f1a9..658caeecde1 100644
--- a/app/assets/javascripts/raven/raven_config.js
+++ b/app/assets/javascripts/raven/raven_config.js
@@ -37,7 +37,7 @@ const IGNORE_URLS = [
/extensions\//i,
/^chrome:\/\//i,
// Other plugins
- /127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb
+ /127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb
/webappstoolbarba\.texthelp\.com\//i,
/metrics\.itunes\.apple\.com\.edgesuite\.net\//i,
];
diff --git a/app/assets/javascripts/registry/components/collapsible_container.vue b/app/assets/javascripts/registry/components/collapsible_container.vue
index 2ce43ef0125..2fc3778820b 100644
--- a/app/assets/javascripts/registry/components/collapsible_container.vue
+++ b/app/assets/javascripts/registry/components/collapsible_container.vue
@@ -84,7 +84,7 @@
css-class="btn-default btn-transparent btn-clipboard"
/>
- <div class="controls hidden-xs pull-right">
+ <div class="controls d-none d-sm-block float-right">
<button
v-if="repo.canDelete"
type="button"
diff --git a/app/assets/javascripts/registry/components/table_registry.vue b/app/assets/javascripts/registry/components/table_registry.vue
index 673b1db6769..e4a4b3bb129 100644
--- a/app/assets/javascripts/registry/components/table_registry.vue
+++ b/app/assets/javascripts/registry/components/table_registry.vue
@@ -120,7 +120,7 @@
<button
v-if="item.canDelete"
type="button"
- class="js-delete-registry btn btn-danger hidden-xs pull-right"
+ class="js-delete-registry btn btn-danger d-none d-sm-block float-right"
:title="s__('ContainerRegistry|Remove tag')"
:aria-label="s__('ContainerRegistry|Remove tag')"
data-container="body"
diff --git a/app/assets/javascripts/registry/stores/actions.js b/app/assets/javascripts/registry/stores/actions.js
index 593a43c7cc1..c0de03373d8 100644
--- a/app/assets/javascripts/registry/stores/actions.js
+++ b/app/assets/javascripts/registry/stores/actions.js
@@ -7,9 +7,10 @@ Vue.use(VueResource);
export const fetchRepos = ({ commit, state }) => {
commit(types.TOGGLE_MAIN_LOADING);
- return Vue.http.get(state.endpoint)
+ return Vue.http
+ .get(state.endpoint)
.then(res => res.json())
- .then((response) => {
+ .then(response => {
commit(types.TOGGLE_MAIN_LOADING);
commit(types.SET_REPOS_LIST, response);
});
@@ -18,19 +19,20 @@ export const fetchRepos = ({ commit, state }) => {
export const fetchList = ({ commit }, { repo, page }) => {
commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo);
- return Vue.http.get(repo.tagsPath, { params: { page } })
- .then((response) => {
- const headers = response.headers;
+ return Vue.http.get(repo.tagsPath, { params: { page } }).then(response => {
+ const headers = response.headers;
- return response.json().then((resp) => {
- commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo);
- commit(types.SET_REGISTRY_LIST, { repo, resp, headers });
- });
+ return response.json().then(resp => {
+ commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo);
+ commit(types.SET_REGISTRY_LIST, { repo, resp, headers });
});
+ });
};
+// eslint-disable-next-line no-unused-vars
export const deleteRepo = ({ commit }, repo) => Vue.http.delete(repo.destroyPath);
+// eslint-disable-next-line no-unused-vars
export const deleteRegistry = ({ commit }, image) => Vue.http.delete(image.destroyPath);
export const setMainEndpoint = ({ commit }, data) => commit(types.SET_MAIN_ENDPOINT, data);
diff --git a/app/assets/javascripts/right_sidebar.js b/app/assets/javascripts/right_sidebar.js
index 6eb0b62fa1c..2afcf4626b8 100644
--- a/app/assets/javascripts/right_sidebar.js
+++ b/app/assets/javascripts/right_sidebar.js
@@ -108,7 +108,7 @@ Sidebar.prototype.todoUpdateDone = function(data) {
.attr('title', $el.data(`${attrPrefix}Text`));
if ($el.hasClass('has-tooltip')) {
- $el.tooltip('fixTitle');
+ $el.tooltip('_fixTitle');
}
if ($el.data(`${attrPrefix}Icon`)) {
diff --git a/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue b/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue
index 5eeb2a41bae..284a258d3c9 100644
--- a/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue
@@ -41,7 +41,7 @@ export default {
</i>
<a
v-if="editable"
- class="js-sidebar-dropdown-toggle edit-link pull-right"
+ class="js-sidebar-dropdown-toggle edit-link float-right"
href="#"
>
{{ __('Edit') }}
@@ -49,7 +49,7 @@ export default {
<a
v-if="showToggle"
aria-label="Toggle sidebar"
- class="gutter-toggle pull-right js-sidebar-toggle"
+ class="gutter-toggle float-right js-sidebar-toggle"
href="#"
role="button"
>
diff --git a/app/assets/javascripts/sidebar/components/assignees/assignees.vue b/app/assets/javascripts/sidebar/components/assignees/assignees.vue
index 2d00e8ac7e0..5a374d84796 100644
--- a/app/assets/javascripts/sidebar/components/assignees/assignees.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/assignees.vue
@@ -130,6 +130,7 @@ export default {
v-tooltip
data-container="body"
data-placement="left"
+ data-boundary="viewport"
:title="collapsedTooltipTitle"
>
<i
diff --git a/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue b/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue
index 7f0de722f61..3f6e2f05396 100644
--- a/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue
+++ b/app/assets/javascripts/sidebar/components/confidential/confidential_issue_sidebar.vue
@@ -75,6 +75,7 @@ export default {
v-tooltip
data-container="body"
data-placement="left"
+ data-boundary="viewport"
:title="tooltipLabel"
>
<icon
@@ -86,7 +87,7 @@ export default {
{{ __('Confidentiality') }}
<a
v-if="isEditable"
- class="pull-right confidential-edit"
+ class="float-right confidential-edit"
href="#"
@click.prevent="toggleForm"
>
diff --git a/app/assets/javascripts/sidebar/components/confidential/edit_form.vue b/app/assets/javascripts/sidebar/components/confidential/edit_form.vue
index 3783f71a848..4165aa19acf 100644
--- a/app/assets/javascripts/sidebar/components/confidential/edit_form.vue
+++ b/app/assets/javascripts/sidebar/components/confidential/edit_form.vue
@@ -32,7 +32,7 @@ export default {
</script>
<template>
- <div class="dropdown open">
+ <div class="dropdown show">
<div class="dropdown-menu sidebar-item-warning-message">
<div>
<p
diff --git a/app/assets/javascripts/sidebar/components/lock/edit_form.vue b/app/assets/javascripts/sidebar/components/lock/edit_form.vue
index e1e4715826a..d392977e5e2 100644
--- a/app/assets/javascripts/sidebar/components/lock/edit_form.vue
+++ b/app/assets/javascripts/sidebar/components/lock/edit_form.vue
@@ -41,7 +41,7 @@ export default {
</script>
<template>
- <div class="dropdown open">
+ <div class="dropdown show">
<div class="dropdown-menu sidebar-item-warning-message">
<p
class="text"
diff --git a/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue b/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue
index 1a5e7b67eca..fb69c741dcd 100644
--- a/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue
+++ b/app/assets/javascripts/sidebar/components/lock/lock_issue_sidebar.vue
@@ -99,6 +99,7 @@ export default {
v-tooltip
data-container="body"
data-placement="left"
+ data-boundary="viewport"
:title="tooltipLabel"
>
<icon
@@ -112,7 +113,7 @@ export default {
{{ sprintf(__('Lock %{issuableDisplayName}'), { issuableDisplayName: issuableDisplayName }) }}
<button
v-if="isEditable"
- class="pull-right lock-edit"
+ class="float-right lock-edit"
type="button"
@click.prevent="toggleForm"
>
diff --git a/app/assets/javascripts/sidebar/components/participants/participants.vue b/app/assets/javascripts/sidebar/components/participants/participants.vue
index 8f9e6761d20..0a945fc7fd5 100644
--- a/app/assets/javascripts/sidebar/components/participants/participants.vue
+++ b/app/assets/javascripts/sidebar/components/participants/participants.vue
@@ -84,6 +84,7 @@
v-tooltip
data-container="body"
data-placement="left"
+ data-boundary="viewport"
:title="participantLabel"
@click="onClickCollapsedIcon"
>
diff --git a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue
index f0df759ef7a..6745c1aafff 100644
--- a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue
+++ b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue
@@ -82,6 +82,7 @@
:title="notificationTooltip"
data-container="body"
data-placement="left"
+ data-boundary="viewport"
>
<icon
:name="notificationIcon"
@@ -91,12 +92,12 @@
/>
</span>
</div>
- <span class="issuable-header-text hide-collapsed pull-left">
+ <span class="issuable-header-text hide-collapsed float-left">
{{ __('Notifications') }}
</span>
<toggle-button
ref="toggleButton"
- class="pull-right hide-collapsed js-issuable-subscribe-button"
+ class="float-right hide-collapsed js-issuable-subscribe-button"
:is-loading="showLoadingState"
:value="subscribed"
@change="toggleSubscription"
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue b/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue
index 9d9ee9dea4d..209af1ce152 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue
@@ -114,6 +114,7 @@
v-tooltip
data-container="body"
data-placement="left"
+ data-boundary="viewport"
:title="tooltipText"
>
<icon name="timer" />
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue b/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue
index 82c4562f9a9..6f79310b1cc 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue
@@ -71,7 +71,7 @@ export default {
</div>
</div>
<div class="compare-display-container">
- <div class="compare-display pull-left">
+ <div class="compare-display float-left">
<span class="compare-label">
{{ s__('TimeTracking|Spent') }}
</span>
@@ -79,7 +79,7 @@ export default {
{{ timeSpentHumanReadable }}
</span>
</div>
- <div class="compare-display estimated pull-right">
+ <div class="compare-display estimated float-right">
<span class="compare-label">
{{ s__('TimeTrackingEstimated|Est') }}
</span>
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
index 8f5d0bee107..7d56d2fa5ee 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
@@ -116,7 +116,7 @@ export default {
<div class="title hide-collapsed">
{{ __('Time tracking') }}
<div
- class="help-button pull-right"
+ class="help-button float-right"
v-if="!showHelpState"
@click="toggleHelpState(true)"
>
@@ -127,7 +127,7 @@ export default {
</i>
</div>
<div
- class="close-help-button pull-right"
+ class="close-help-button float-right"
v-if="showHelpState"
@click="toggleHelpState(false)"
>
diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js
index 8486019897d..cd954f75613 100644
--- a/app/assets/javascripts/users_select.js
+++ b/app/assets/javascripts/users_select.js
@@ -202,7 +202,7 @@ function UsersSelect(currentUser, els, options = {}) {
tooltipTitle = __('Assignee');
}
$value.html(assigneeTemplate(user));
- $collapsedSidebar.attr('title', tooltipTitle).tooltip('fixTitle');
+ $collapsedSidebar.attr('title', tooltipTitle).tooltip('_fixTitle');
return $collapsedSidebar.html(collapsedAssigneeTemplate(user));
});
};
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue
index 1fea231c816..1608858da22 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue
@@ -127,7 +127,7 @@ export default {
</span>
<loading-button
v-if="deployment.stop_url"
- container-class="btn btn-default btn-xs prepend-left-default"
+ container-class="btn btn-default btn-sm prepend-left-default"
label="Stop environment"
:loading="isStopping"
@click="stopEnvironment"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
index 18ee4c62bf1..51a0fda6555 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
@@ -131,7 +131,7 @@ export default {
aria-hidden="true">
</i>
</button>
- <ul class="dropdown-menu dropdown-menu-align-right">
+ <ul class="dropdown-menu dropdown-menu-right">
<li>
<a
class="js-download-email-patches"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue
index ebaf2b972eb..b404a592234 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue
@@ -42,7 +42,7 @@
@click="refreshWidget"
:disabled="isRefreshing"
type="button"
- class="btn btn-xs btn-default"
+ class="btn btn-sm btn-default"
>
<loading-icon
v-if="isRefreshing"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
index dad4b0fe49d..5c1500ab801 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
@@ -43,13 +43,13 @@ To merge this request, first rebase locally.`) }}
<a
v-if="mr.canMerge && mr.conflictResolutionPath"
:href="mr.conflictResolutionPath"
- class="js-resolve-conflicts-button btn btn-default btn-xs"
+ class="js-resolve-conflicts-button btn btn-default btn-sm"
>
{{ s__("mrWidget|Resolve conflicts") }}
</a>
<button
v-if="mr.canMerge"
- class="js-merge-locally-button btn btn-default btn-xs"
+ class="js-merge-locally-button btn btn-default btn-sm"
data-toggle="modal"
data-target="#modal_merge_info"
>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue
index 7d366c495f0..05fecd4de35 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue
@@ -98,7 +98,7 @@ export default {
</span>
<button
@click="refresh"
- class="btn btn-default btn-xs js-refresh-button"
+ class="btn btn-default btn-sm js-refresh-button"
type="button"
>
{{ s__("mrWidget|Refresh now") }}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.vue
index 84be9327443..e8352c362d6 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.vue
@@ -94,7 +94,7 @@
:disabled="isCancellingAutoMerge"
role="button"
href="#"
- class="btn btn-xs btn-default js-cancel-auto-merge">
+ class="btn btn-sm btn-default js-cancel-auto-merge">
<i
v-if="isCancellingAutoMerge"
class="fa fa-spinner fa-spin"
@@ -129,7 +129,7 @@
:disabled="isRemovingSourceBranch"
@click.prevent="removeSourceBranch"
role="button"
- class="btn btn-xs btn-default js-remove-source-branch"
+ class="btn btn-sm btn-default js-remove-source-branch"
href="#"
>
<i
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
index 3e36a3a10f9..eb581b807a2 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue
@@ -118,7 +118,7 @@
<a
v-if="mr.canRevertInCurrentMR"
v-tooltip
- class="btn btn-close btn-xs"
+ class="btn btn-close btn-sm"
href="#modal-revert-commit"
data-toggle="modal"
data-container="body"
@@ -129,7 +129,7 @@
<a
v-else-if="mr.revertInForkPath"
v-tooltip
- class="btn btn-close btn-xs"
+ class="btn btn-close btn-sm"
data-method="post"
:href="mr.revertInForkPath"
:title="revertTitle"
@@ -139,7 +139,7 @@
<a
v-if="mr.canCherryPickInCurrentMR"
v-tooltip
- class="btn btn-default btn-xs"
+ class="btn btn-default btn-sm"
href="#modal-cherry-pick-commit"
data-toggle="modal"
data-container="body"
@@ -150,7 +150,7 @@
<a
v-else-if="mr.cherryPickInForkPath"
v-tooltip
- class="btn btn-default btn-xs"
+ class="btn btn-default btn-sm"
data-method="post"
:href="mr.cherryPickInForkPath"
:title="cherryPickTitle"
@@ -168,8 +168,8 @@
<a
:href="mr.mergeCommitPath"
class="commit-sha js-mr-merged-commit-sha"
+ v-text="mr.shortMergeCommitSha"
>
- {{ mr.shortMergeCommitSha }}
</a>
<clipboard-button
:title="__('Copy commit SHA to clipboard')"
@@ -189,7 +189,7 @@
@click="removeSourceBranch"
:disabled="isMakingRequest"
type="button"
- class="btn btn-xs btn-default js-remove-branch-button"
+ class="btn btn-sm btn-default js-remove-branch-button"
>
{{ s__("mrWidget|Remove Source Branch") }}
</button>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue
index 926a3172412..875c3323dbb 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_squash_before_merge.vue
@@ -1,15 +1,63 @@
-/*
-The squash-before-merge button is EE only, but it's located right in the middle
-of the readyToMerge state component template.
-
-If we didn't declare this component in CE, we'd need to maintain a separate copy
-of the readyToMergeState template in EE, which is pretty big and likely to change.
-
-Instead, in CE, we declare the component, but it's hidden and is configured to do nothing.
-In EE, the configuration extends this object to add a functioning squash-before-merge
-button.
-*/
-
<script>
- export default {};
+import Icon from '~/vue_shared/components/icon.vue';
+import eventHub from '~/vue_merge_request_widget/event_hub';
+import tooltip from '~/vue_shared/directives/tooltip';
+
+export default {
+ components: {
+ Icon,
+ },
+ directives: {
+ tooltip,
+ },
+ props: {
+ mr: {
+ type: Object,
+ required: true,
+ },
+ isMergeButtonDisabled: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ squashBeforeMerge: this.mr.squash,
+ };
+ },
+ methods: {
+ updateSquashModel() {
+ eventHub.$emit('MRWidgetUpdateSquash', this.squashBeforeMerge);
+ },
+ },
+};
</script>
+
+<template>
+ <div class="accept-control inline">
+ <label class="merge-param-checkbox">
+ <input
+ type="checkbox"
+ name="squash"
+ class="qa-squash-checkbox"
+ :disabled="isMergeButtonDisabled"
+ v-model="squashBeforeMerge"
+ @change="updateSquashModel"
+ />
+ {{ __('Squash commits') }}
+ </label>
+ <a
+ :href="mr.squashBeforeMergeHelpPath"
+ data-title="About this feature"
+ data-placement="bottom"
+ target="_blank"
+ rel="noopener noreferrer nofollow"
+ data-container="body"
+ v-tooltip
+ >
+ <icon
+ name="question-o"
+ />
+ </a>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
index 3d9161f6926..086dbabe77e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/nothing_to_merge.vue
@@ -18,10 +18,10 @@ export default {
<template>
<div class="mr-widget-body mr-widget-empty-state">
<div class="row">
- <div class="artwork col-sm-5 col-sm-push-7 col-xs-12 text-center">
+ <div class="artwork col-md-5 order-md-last col-12 text-center">
<span v-html="emptyStateSVG"></span>
</div>
- <div class="text col-sm-7 col-sm-pull-5 col-xs-12">
+ <div class="text col-md-7 order-md-first col-12">
<span>
Merge requests are a place to propose changes you have made to a project
and discuss those changes with others.
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
index 0264625a526..3a194320bd8 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
@@ -6,11 +6,13 @@ import MergeRequest from '../../../merge_request';
import Flash from '../../../flash';
import statusIcon from '../mr_widget_status_icon.vue';
import eventHub from '../../event_hub';
+import SquashBeforeMerge from './mr_widget_squash_before_merge.vue';
export default {
name: 'ReadyToMerge',
components: {
statusIcon,
+ 'squash-before-merge': SquashBeforeMerge,
},
props: {
mr: { type: Object, required: true },
@@ -101,6 +103,12 @@ export default {
return enableSquashBeforeMerge && commitsCount > 1;
},
},
+ created() {
+ eventHub.$on('MRWidgetUpdateSquash', this.handleUpdateSquash);
+ },
+ beforeDestroy() {
+ eventHub.$off('MRWidgetUpdateSquash', this.handleUpdateSquash);
+ },
methods: {
shouldShowMergeControls() {
return this.mr.isMergeAllowed || this.shouldShowMergeWhenPipelineSucceedsText;
@@ -128,13 +136,9 @@ export default {
commit_message: this.commitMessage,
merge_when_pipeline_succeeds: this.setToMergeWhenPipelineSucceeds,
should_remove_source_branch: this.removeSourceBranch === true,
+ squash: this.mr.squash,
};
- // Only truthy in EE extension of this component
- if (this.setAdditionalParams) {
- this.setAdditionalParams(options);
- }
-
this.isMakingRequest = true;
this.service.merge(options)
.then(res => res.data)
@@ -154,6 +158,9 @@ export default {
new Flash('Something went wrong. Please try again.'); // eslint-disable-line
});
},
+ handleUpdateSquash(val) {
+ this.mr.squash = val;
+ },
initiateMergePolling() {
simplePoll((continuePolling, stopPolling) => {
this.handleMergePolling(continuePolling, stopPolling);
@@ -312,7 +319,7 @@ export default {
v-else
@click="toggleCommitMessageEditor"
:disabled="isMergeButtonDisabled"
- class="js-modify-commit-message-button btn btn-default btn-xs"
+ class="js-modify-commit-message-button btn btn-default btn-sm"
type="button">
Modify commit message
</button>
@@ -329,7 +336,7 @@ export default {
class="prepend-top-default commit-message-editor">
<div class="form-group clearfix">
<label
- class="control-label"
+ class="col-form-label"
for="commit-message">
Commit message
</label>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
index a1f7e696795..8ea3f22ecc2 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/unresolved_discussions.vue
@@ -28,7 +28,7 @@ export default {
<a
v-if="mr.createIssueToResolveDiscussionsPath"
:href="mr.createIssueToResolveDiscussionsPath"
- class="btn btn-default btn-xs js-create-issue"
+ class="btn btn-default btn-sm js-create-issue"
>
{{ s__("mrWidget|Create an issue to resolve them later") }}
</a>
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index 83b7b054e6f..e5b7e1f1c68 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -15,6 +15,11 @@ export default class MergeRequestStore {
const currentUser = data.current_user;
const pipelineStatus = data.pipeline ? data.pipeline.details.status : null;
+ this.squash = data.squash;
+ this.squashBeforeMergeHelpPath = this.squashBeforeMergeHelpPath ||
+ data.squash_before_merge_help_path;
+ this.enableSquashBeforeMerge = this.enableSquashBeforeMerge || true;
+
this.title = data.title;
this.targetBranch = data.target_branch;
this.sourceBranch = data.source_branch;
diff --git a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/download_viewer.vue b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/download_viewer.vue
index 395a71acccf..7b5367ac19b 100644
--- a/app/assets/javascripts/vue_shared/components/content_viewer/viewers/download_viewer.vue
+++ b/app/assets/javascripts/vue_shared/components/content_viewer/viewers/download_viewer.vue
@@ -42,7 +42,7 @@ export default {
target="_blank">
<icon
name="download"
- css-classes="pull-left append-right-8"
+ css-classes="float-left append-right-8"
:size="16"
/>
{{ __('Download') }}
diff --git a/app/assets/javascripts/vue_shared/components/deprecated_modal.vue b/app/assets/javascripts/vue_shared/components/deprecated_modal.vue
index dcf1489b37c..424af5a0293 100644
--- a/app/assets/javascripts/vue_shared/components/deprecated_modal.vue
+++ b/app/assets/javascripts/vue_shared/components/deprecated_modal.vue
@@ -87,7 +87,7 @@
<div
:id="id"
class="modal"
- :class="id ? '' : 'show'"
+ :class="id ? '' : 'd-block'"
role="dialog"
tabindex="-1"
>
@@ -99,12 +99,12 @@
<div class="modal-content">
<div class="modal-header">
<slot name="header">
- <h4 class="modal-title pull-left">
+ <h4 class="modal-title float-left">
{{ title }}
</h4>
<button
type="button"
- class="close pull-right"
+ class="close float-right"
@click="emitCancel($event)"
data-dismiss="modal"
aria-label="Close"
@@ -166,7 +166,7 @@
</div>
<div
v-if="!id"
- class="modal-backdrop fade in"
+ class="modal-backdrop fade show"
>
</div>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/dropdown/dropdown_button.vue b/app/assets/javascripts/vue_shared/components/dropdown/dropdown_button.vue
new file mode 100644
index 00000000000..c159333d89a
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/dropdown/dropdown_button.vue
@@ -0,0 +1,55 @@
+<script>
+import { __ } from '~/locale';
+import LoadingIcon from '~/vue_shared/components/loading_icon.vue';
+
+export default {
+ components: {
+ LoadingIcon,
+ },
+ props: {
+ isDisabled: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isLoading: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ toggleText: {
+ type: String,
+ required: false,
+ default: __('Select'),
+ },
+ },
+};
+</script>
+
+<template>
+ <button
+ class="dropdown-menu-toggle dropdown-menu-full-width"
+ type="button"
+ data-toggle="dropdown"
+ aria-expanded="false"
+ :disabled="isDisabled || isLoading"
+ >
+ <loading-icon
+ v-show="isLoading"
+ :inline="true"
+ />
+ <span class="dropdown-toggle-text">
+ {{ toggleText }}
+ </span>
+ <span
+ class="dropdown-toggle-icon"
+ v-show="!isLoading"
+ >
+ <i
+ class="fa fa-chevron-down"
+ aria-hidden="true"
+ data-hidden="true"
+ ></i>
+ </span>
+ </button>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_hidden_input.vue b/app/assets/javascripts/vue_shared/components/dropdown/dropdown_hidden_input.vue
index 1832c3c1757..1fe27eb97ab 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_hidden_input.vue
+++ b/app/assets/javascripts/vue_shared/components/dropdown/dropdown_hidden_input.vue
@@ -5,8 +5,8 @@ export default {
type: String,
required: true,
},
- label: {
- type: Object,
+ value: {
+ type: [Number, String],
required: true,
},
},
@@ -17,6 +17,6 @@ export default {
<input
type="hidden"
:name="name"
- :value="label.id"
+ :value="value"
/>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/dropdown/dropdown_search_input.vue b/app/assets/javascripts/vue_shared/components/dropdown/dropdown_search_input.vue
new file mode 100644
index 00000000000..c2145a26e64
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/dropdown/dropdown_search_input.vue
@@ -0,0 +1,46 @@
+<script>
+import { __ } from '~/locale';
+
+export default {
+ props: {
+ placeholderText: {
+ type: String,
+ required: true,
+ default: __('Search'),
+ },
+ },
+ data() {
+ return { searchQuery: this.value };
+ },
+ watch: {
+ searchQuery(query) {
+ this.$emit('input', query);
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="dropdown-input">
+ <input
+ class="dropdown-input-field"
+ type="search"
+ v-model="searchQuery"
+ :placeholder="placeholderText"
+ autocomplete="off"
+ />
+ <i
+ class="fa fa-search dropdown-input-search"
+ aria-hidden="true"
+ data-hidden="true"
+ >
+ </i>
+ <i
+ class="fa fa-times dropdown-input-clear js-dropdown-input-clear"
+ aria-hidden="true"
+ data-hidden="true"
+ role="button"
+ >
+ </i>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/gl_modal.vue b/app/assets/javascripts/vue_shared/components/gl_modal.vue
index f28e5e2715d..d5d5a7d3798 100644
--- a/app/assets/javascripts/vue_shared/components/gl_modal.vue
+++ b/app/assets/javascripts/vue_shared/components/gl_modal.vue
@@ -53,6 +53,11 @@ export default {
<div class="modal-content">
<div class="modal-header">
<slot name="header">
+ <h4 class="modal-title">
+ <slot name="title">
+ {{ headerTitleText }}
+ </slot>
+ </h4>
<button
type="button"
class="close js-modal-close-action"
@@ -62,11 +67,6 @@ export default {
>
<span aria-hidden="true">&times;</span>
</button>
- <h4 class="modal-title">
- <slot name="title">
- {{ headerTitleText }}
- </slot>
- </h4>
</slot>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/header_ci_component.vue b/app/assets/javascripts/vue_shared/components/header_ci_component.vue
index 088187ed348..ca17fa06a00 100644
--- a/app/assets/javascripts/vue_shared/components/header_ci_component.vue
+++ b/app/assets/javascripts/vue_shared/components/header_ci_component.vue
@@ -163,8 +163,8 @@ export default {
<button
v-if="hasSidebarButton"
type="button"
- class="btn btn-default visible-xs-block
-visible-sm-block sidebar-toggle-btn js-sidebar-build-toggle js-sidebar-build-toggle-header"
+ class="btn btn-default d-block d-sm-none d-md-none
+sidebar-toggle-btn js-sidebar-build-toggle js-sidebar-build-toggle-header"
aria-label="Toggle Sidebar"
id="toggleSidebar"
>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
index c0ee88bbf72..d63318f3da6 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
@@ -111,7 +111,7 @@
Attach a file
</button>
<button
- class="btn btn-default btn-xs hide button-cancel-uploading-files"
+ class="btn btn-default btn-sm hide button-cancel-uploading-files"
type="button"
>
Cancel
diff --git a/app/assets/javascripts/vue_shared/components/navigation_tabs.vue b/app/assets/javascripts/vue_shared/components/navigation_tabs.vue
index 92d187e24bf..08d4936f480 100644
--- a/app/assets/javascripts/vue_shared/components/navigation_tabs.vue
+++ b/app/assets/javascripts/vue_shared/components/navigation_tabs.vue
@@ -67,7 +67,7 @@ export default {
<span
v-if="shouldRenderBadge(tab.count)"
- class="badge"
+ class="badge badge-pill"
>
{{ tab.count }}
</span>
diff --git a/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue b/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
index 50b1508691b..eccba61a8c0 100644
--- a/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
@@ -54,7 +54,7 @@
<div class="note-header">
<div class="note-header-info">
<a :href="getUserData.path">
- <span class="hidden-xs">{{ getUserData.name }}</span>
+ <span class="d-none d-sm-block">{{ getUserData.name }}</span>
<span class="note-headline-light">@{{ getUserData.username }}</span>
</a>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue b/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue
index 3fcacd156c5..71ec34f2c7a 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/date_picker.vue
@@ -116,7 +116,7 @@
v-if="isLoading"
:inline="true"
/>
- <div class="pull-right">
+ <div class="float-right">
<button
v-if="editable && !editing"
type="button"
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue
index 70b46a9c2bb..f155ac2be02 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/base.vue
@@ -2,13 +2,13 @@
import $ from 'jquery';
import { __ } from '~/locale';
import LabelsSelect from '~/labels_select';
+import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue';
import LoadingIcon from '../../loading_icon.vue';
import DropdownTitle from './dropdown_title.vue';
import DropdownValue from './dropdown_value.vue';
import DropdownValueCollapsed from './dropdown_value_collapsed.vue';
import DropdownButton from './dropdown_button.vue';
-import DropdownHiddenInput from './dropdown_hidden_input.vue';
import DropdownHeader from './dropdown_header.vue';
import DropdownSearchInput from './dropdown_search_input.vue';
import DropdownFooter from './dropdown_footer.vue';
@@ -140,7 +140,7 @@ export default {
v-for="label in context.labels"
:key="label.id"
:name="hiddenInputName"
- :label="label"
+ :value="label.id"
/>
<div
class="dropdown"
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label.vue
index 34a07f33a23..3c400afdc1d 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label.vue
@@ -77,13 +77,13 @@ export default {
<div class="clearfix">
<button
type="button"
- class="btn btn-primary pull-left js-new-label-btn disabled"
+ class="btn btn-primary float-left js-new-label-btn disabled"
>
{{ __('Create') }}
</button>
<button
type="button"
- class="btn btn-default pull-right js-cancel-label-btn"
+ class="btn btn-default float-right js-cancel-label-btn"
>
{{ __('Cancel') }}
</button>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title.vue
index 7da82e90e29..9ac32ff13c6 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title.vue
@@ -21,7 +21,7 @@ export default {
</i>
<button
type="button"
- class="edit-link btn btn-blank pull-right js-sidebar-dropdown-toggle"
+ class="edit-link btn btn-blank float-right js-sidebar-dropdown-toggle"
>
{{ __('Edit') }}
</button>
diff --git a/app/assets/javascripts/vue_shared/directives/popover.js b/app/assets/javascripts/vue_shared/directives/popover.js
index eb35294906b..c913bc34c68 100644
--- a/app/assets/javascripts/vue_shared/directives/popover.js
+++ b/app/assets/javascripts/vue_shared/directives/popover.js
@@ -17,6 +17,6 @@ export default {
},
unbind(el) {
- $(el).popover('destroy');
+ $(el).popover('dispose');
},
};
diff --git a/app/assets/javascripts/vue_shared/directives/tooltip.js b/app/assets/javascripts/vue_shared/directives/tooltip.js
index b7f7e9fec15..155e6b6698a 100644
--- a/app/assets/javascripts/vue_shared/directives/tooltip.js
+++ b/app/assets/javascripts/vue_shared/directives/tooltip.js
@@ -6,10 +6,10 @@ export default {
},
componentUpdated(el) {
- $(el).tooltip('fixTitle');
+ $(el).tooltip('_fixTitle');
},
unbind(el) {
- $(el).tooltip('destroy');
+ $(el).tooltip('dispose');
},
};
diff --git a/app/assets/javascripts/vue_shared/translate.js b/app/assets/javascripts/vue_shared/translate.js
index 2c7886ec308..48c63373b77 100644
--- a/app/assets/javascripts/vue_shared/translate.js
+++ b/app/assets/javascripts/vue_shared/translate.js
@@ -13,7 +13,7 @@ export default (Vue) => {
@param text The text to be translated
@returns {String} The translated text
- **/
+ */
__,
/**
Translate the text with a number
@@ -24,7 +24,7 @@ export default (Vue) => {
@param pluralText Plural text to translate (eg. '%d days')
@param count Number to decide which translation to use (eg. 2)
@returns {String} Translated text with the number replaced (eg. '2 days')
- **/
+ */
n__,
/**
Translate context based text
@@ -36,7 +36,7 @@ export default (Vue) => {
(eg. 'Context')
@param key Is the dynamic variable you want to be translated
@returns {String} Translated context based text
- **/
+ */
s__,
sprintf,
},
diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss
new file mode 100644
index 00000000000..a40f4ea4f4b
--- /dev/null
+++ b/app/assets/stylesheets/bootstrap_migration.scss
@@ -0,0 +1,163 @@
+/*
+ * Scss to help with bootstrap 3 to 4 migration
+ */
+
+$text-color: $gl-text-color;
+
+$brand-primary: $gl-primary;
+$brand-success: $gl-success;
+$brand-info: $gl-info;
+$brand-warning: $gl-warning;
+$brand-danger: $gl-danger;
+
+$border-radius-base: 3px !default;
+
+$modal-body-bg: $white-light;
+$input-border: $border-color;
+$input-border-focus: $focus-border-color;
+
+$padding-base-vertical: $gl-vert-padding;
+$padding-base-horizontal: $gl-padding;
+
+html {
+ // Override default font size used in bs4
+ font-size: 14px;
+}
+
+button,
+html [type="button"],
+[type="reset"],
+[type="submit"] {
+ // Override bootstrap reboot
+ -webkit-appearance: inherit;
+}
+
+[role="button"] {
+ cursor: pointer;
+}
+
+a {
+ color: $gl-link-color;
+}
+
+.form-group.row .col-form-label {
+ // Bootstrap 4 aligns labels to the left
+ // for horizontal forms
+ @include media-breakpoint-up(md) {
+ text-align: right;
+ }
+}
+
+table {
+ // Remove any table border lines
+ border-spacing: 0;
+}
+
+.tooltip {
+ // Fix bootstrap4 bug whereby tooltips flicker when they are hovered over their borders
+ pointer-events: none;
+}
+
+.popover {
+ font-size: 14px;
+}
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .d#{$infix}-table-header-group { display: table-header-group !important; }
+ }
+}
+
+.text-secondary {
+ // Override Bootstrap's light secondary color
+ // We have to use !important because bootstrap has that set as well
+ color: $gl-text-color-secondary !important;
+}
+
+// Polyfill deprecated selectors
+
+.hidden {
+ display: none !important;
+ visibility: hidden !important;
+}
+
+.hide {
+ display: none;
+}
+
+.dropdown-toggle::after {
+ // Remove bootstrap's dropdown caret
+ display: none;
+}
+
+.badge {
+ padding: 4px 5px;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: $gl-font-weight-normal;
+ display: inline-block;
+
+ &.badge-gray {
+ background-color: $label-gray-bg;
+ color: $gl-text-color;
+ text-shadow: none;
+ }
+
+ &.badge-inverse {
+ background-color: $label-inverse-bg;
+ }
+}
+
+.divider {
+ @extend .dropdown-divider;
+}
+
+.info-well {
+ background: $theme-gray-50;
+ color: $gl-text-color;
+ border: 1px solid $border-color;
+ border-radius: 4px;
+ margin-bottom: 16px;
+
+ .well-segment {
+ padding: 16px;
+
+ &:not(:last-of-type) {
+ border-bottom: 1px solid $well-inner-border;
+ }
+ }
+}
+
+.card {
+ .card-title {
+ margin-bottom: 0;
+ }
+
+ &.card-without-border {
+ @extend .border-0;
+ }
+
+ &.card-without-margin {
+ margin: 0;
+ }
+
+ &.bg-light {
+ @extend .border-0;
+ }
+}
+
+.nav-tabs {
+ .nav-link {
+ border: 0;
+ }
+
+ .nav-item {
+ margin-bottom: 0;
+ }
+}
+
+pre code {
+ white-space: pre-wrap;
+}
diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss
index 9bd35183d8a..7c28024001f 100644
--- a/app/assets/stylesheets/framework.scss
+++ b/app/assets/stylesheets/framework.scss
@@ -1,7 +1,7 @@
@import 'framework/variables';
@import 'framework/mixins';
-@import 'framework/tw_bootstrap_variables';
-@import 'framework/tw_bootstrap';
+@import '../../../node_modules/bootstrap/scss/bootstrap';
+@import 'bootstrap_migration';
@import 'framework/layout';
@import 'framework/animations';
diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss
index 077d0424093..c1ec11e434a 100644
--- a/app/assets/stylesheets/framework/avatar.scss
+++ b/app/assets/stylesheets/framework/avatar.scss
@@ -31,7 +31,7 @@
.avatar {
@extend .avatar-circle;
- @include transition-property(none);
+ transition-property: none;
width: 40px;
height: 40px;
diff --git a/app/assets/stylesheets/framework/badges.scss b/app/assets/stylesheets/framework/badges.scss
index 6bbe32df772..57df9b969c3 100644
--- a/app/assets/stylesheets/framework/badges.scss
+++ b/app/assets/stylesheets/framework/badges.scss
@@ -1,4 +1,4 @@
-.badge {
+.badge.badge-pill {
font-weight: $gl-font-weight-normal;
background-color: $badge-bg;
color: $badge-color;
diff --git a/app/assets/stylesheets/framework/banner.scss b/app/assets/stylesheets/framework/banner.scss
index 02f3896d591..71bbab2065d 100644
--- a/app/assets/stylesheets/framework/banner.scss
+++ b/app/assets/stylesheets/framework/banner.scss
@@ -23,7 +23,7 @@
border-bottom: 1px solid $border-color;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
justify-content: center;
flex-direction: column;
align-items: center;
diff --git a/app/assets/stylesheets/framework/blank.scss b/app/assets/stylesheets/framework/blank.scss
index 9982a5779af..91dbb2a6365 100644
--- a/app/assets/stylesheets/framework/blank.scss
+++ b/app/assets/stylesheets/framework/blank.scss
@@ -37,7 +37,7 @@
flex: 0 0 100%;
margin-bottom: 15px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
flex: 0 0 49%;
&:nth-child(odd) {
@@ -67,7 +67,7 @@
border: 1px solid $border-color;
border-radius: $border-radius-default;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: flex;
align-items: center;
padding: 50px 30px;
@@ -89,12 +89,12 @@
}
.blank-state-body {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
text-align: center;
margin-top: 20px;
}
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
padding-left: 20px;
}
}
diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss
index c60f65e7a85..c5be27f2d29 100644
--- a/app/assets/stylesheets/framework/blocks.scss
+++ b/app/assets/stylesheets/framework/blocks.scss
@@ -151,7 +151,7 @@
display: inline-block;
margin-left: 5px;
font-size: 18px;
- color: $gray;
+ color: color("gray");
}
p {
@@ -195,7 +195,7 @@
}
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
text-align: center;
.avatar {
@@ -315,7 +315,7 @@
}
}
- @media (max-width: $screen-sm-min) {
+ @include media-breakpoint-down(sm) {
flex-direction: column;
.inner-content {
@@ -342,7 +342,7 @@
.btn {
margin: $btn-side-margin 5px;
- @media(max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
width: 100%;
}
}
diff --git a/app/assets/stylesheets/framework/broadcast_messages.scss b/app/assets/stylesheets/framework/broadcast_messages.scss
index 9b54fb94cdc..d3e7d751e63 100644
--- a/app/assets/stylesheets/framework/broadcast_messages.scss
+++ b/app/assets/stylesheets/framework/broadcast_messages.scss
@@ -19,3 +19,9 @@
@extend .broadcast-message;
margin-bottom: 20px;
}
+
+.toggle-colors {
+ input {
+ min-height: 34px;
+ }
+}
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index cd9d60b96d3..0115f542c88 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -304,7 +304,8 @@
padding: 0 5px;
}
-.input-group-btn {
+.input-group-prepend,
+.input-group-append {
.btn {
@include btn-middle;
@@ -393,7 +394,7 @@
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.btn-wide-on-xs {
width: 100%;
}
diff --git a/app/assets/stylesheets/framework/calendar.scss b/app/assets/stylesheets/framework/calendar.scss
index c165ec0b94b..0b9dff64b0b 100644
--- a/app/assets/stylesheets/framework/calendar.scss
+++ b/app/assets/stylesheets/framework/calendar.scss
@@ -4,7 +4,7 @@
border-top: 0;
direction: rtl;
- @media (min-width: $screen-sm-min) and (max-width: $screen-md-max) {
+ @media (min-width: map-get($grid-breakpoints, sm)) and (max-width: map-get($grid-breakpoints, sm)) {
overflow-x: auto;
}
}
diff --git a/app/assets/stylesheets/framework/ci_variable_list.scss b/app/assets/stylesheets/framework/ci_variable_list.scss
index 5fe835dd8f9..7207e5119ce 100644
--- a/app/assets/stylesheets/framework/ci_variable_list.scss
+++ b/app/assets/stylesheets/framework/ci_variable_list.scss
@@ -10,14 +10,14 @@
display: flex;
align-items: flex-start;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
align-items: flex-end;
}
&:not(:last-child) {
margin-bottom: $gl-btn-padding;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
margin-bottom: 3 * $gl-btn-padding;
}
}
@@ -26,7 +26,7 @@
.ci-variable-body-item:last-child {
margin-right: $ci-variable-remove-button-width;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
margin-right: 0;
}
}
@@ -35,7 +35,7 @@
display: none;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.ci-variable-row-body {
margin-right: $ci-variable-remove-button-width;
}
@@ -48,7 +48,7 @@
align-items: flex-start;
width: 100%;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
display: block;
}
}
@@ -59,7 +59,7 @@
&:not(:last-child) {
margin-right: $gl-btn-padding;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
margin-right: 0;
margin-bottom: $gl-btn-padding;
}
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index 2faea55a5f5..1e7b9534275 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -70,7 +70,7 @@ pre {
padding: 0;
}
- &.well-pre {
+ &.card.card-body-pre {
border: 1px solid $well-pre-bg;
background: $gray-light;
border-radius: 0;
@@ -218,7 +218,7 @@ li.note {
}
.git_error_tips {
- @extend .col-md-6;
+ @extend .col-lg-6;
text-align: left;
margin-top: 40px;
@@ -308,7 +308,7 @@ img.emoji {
.btn-sign-in {
text-shadow: none;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
margin-top: 8px;
}
}
@@ -327,7 +327,7 @@ img.emoji {
}
}
-.well {
+.card.card-body {
margin-bottom: $gl-padding;
hr {
@@ -336,7 +336,7 @@ img.emoji {
}
.search_box {
- @extend .well;
+ @extend .card.card-body;
text-align: center;
}
diff --git a/app/assets/stylesheets/framework/contextual_sidebar.scss b/app/assets/stylesheets/framework/contextual_sidebar.scss
index e2d97d0298f..1a415e1b852 100644
--- a/app/assets/stylesheets/framework/contextual_sidebar.scss
+++ b/app/assets/stylesheets/framework/contextual_sidebar.scss
@@ -1,11 +1,11 @@
.page-with-contextual-sidebar {
transition: padding-left $sidebar-transition-duration;
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
padding-left: $contextual-sidebar-collapsed-width;
}
- @media (min-width: $screen-lg-min) {
+ @include media-breakpoint-up(lg) {
padding-left: $contextual-sidebar-width;
}
@@ -16,7 +16,7 @@
}
.page-with-icon-sidebar {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
padding-left: $contextual-sidebar-collapsed-width;
}
}
@@ -75,7 +75,7 @@
transform: translate3d(0, 0, 0);
&:not(.sidebar-collapsed-desktop) {
- @media (min-width: $screen-sm-min) and (max-width: $screen-md-max) {
+ @media (min-width: map-get($grid-breakpoints, sm)) and (max-width: map-get($grid-breakpoints, sm)) {
box-shadow: inset -2px 0 0 $border-color,
2px 1px 3px $dropdown-shadow-color;
}
@@ -88,7 +88,7 @@
overflow-x: hidden;
}
- .badge:not(.fly-out-badge),
+ .badge.badge-pill:not(.fly-out-badge),
.sidebar-context-title,
.nav-item-name {
display: none;
@@ -142,7 +142,7 @@
}
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
left: (-$contextual-sidebar-width);
}
@@ -166,7 +166,7 @@
width: 100%;
overflow: auto;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
overflow: hidden;
}
}
@@ -207,7 +207,7 @@
> li {
> a {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
margin-right: 2px;
}
@@ -222,7 +222,7 @@
}
.sidebar-sub-level-items {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
position: fixed;
top: 0;
left: 0;
@@ -277,7 +277,7 @@
}
}
- .badge {
+ .badge.badge-pill {
background-color: $inactive-badge-background;
color: $gl-text-color-secondary;
}
@@ -291,7 +291,7 @@
padding-left: 11px;
}
- .badge {
+ .badge.badge-pill {
font-weight: $gl-font-weight-bold;
}
@@ -339,7 +339,7 @@
}
.toggle-sidebar-button {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
display: none;
}
}
@@ -420,7 +420,7 @@
color: $gl-text-color-secondary;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
display: flex;
align-items: center;
@@ -429,7 +429,7 @@
}
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
+ .breadcrumbs-links {
padding-left: $gl-padding;
border-left: 1px solid $gl-text-color-quaternary;
@@ -437,7 +437,7 @@
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.close-nav-button {
display: flex;
}
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index 664aade7375..b91d579cae6 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -24,7 +24,7 @@
display: none;
}
-.open {
+.show.dropdown {
.dropdown-menu,
.dropdown-menu-nav {
@include set-visible;
@@ -32,7 +32,7 @@
max-height: $dropdown-max-height;
overflow-y: auto;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
width: 100%;
}
}
@@ -63,6 +63,10 @@
border-radius: $border-radius-base;
white-space: nowrap;
+ &:disabled.read-only {
+ color: $gl-text-color !important;
+ }
+
&.no-outline {
outline: 0;
}
@@ -184,7 +188,7 @@
text-decoration: none;
- .badge {
+ .badge.badge-pill {
background-color: darken($dropdown-link-hover-bg, 5%);
}
}
@@ -210,11 +214,10 @@
.dropdown-menu,
.dropdown-menu-nav {
- @include set-invisible;
+ display: none;
position: absolute;
width: auto;
top: 100%;
- left: 0;
z-index: 300;
min-width: 240px;
max-width: 500px;
@@ -328,7 +331,7 @@
color: $gl-text-color-secondary;
}
- .badge + span:not(.badge) {
+ .badge.badge-pill + span:not(.badge.badge-pill) {
// Expects up to 3 digits on the badge
margin-right: 40px;
}
@@ -392,7 +395,7 @@
transform: translateY(0);
}
-.comment-type-dropdown.open .dropdown-menu {
+.comment-type-dropdown.show .dropdown-menu {
display: block;
}
@@ -473,16 +476,11 @@
.dropdown-select {
width: $dropdown-width;
- @media (max-width: $screen-sm-min) {
+ @include media-breakpoint-down(sm) {
width: 100%;
}
}
-.dropdown-menu-align-right {
- left: auto;
- right: 0;
-}
-
.dropdown-menu-selectable {
li {
a,
@@ -783,7 +781,7 @@
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.navbar-gitlab {
li.header-projects,
li.header-more,
@@ -838,7 +836,7 @@ header.header-content .dropdown-menu.projects-dropdown-menu {
width: 70%;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
flex-direction: column;
width: 100%;
height: auto;
@@ -894,7 +892,7 @@ header.header-content .dropdown-menu.projects-dropdown-menu {
height: 284px;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.projects-list-frequent-container {
width: auto;
height: auto;
@@ -935,7 +933,7 @@ header.header-content .dropdown-menu.projects-dropdown-menu {
color: $gl-text-color-secondary;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.project-item-metadata-container {
float: none;
}
diff --git a/app/assets/stylesheets/framework/feature_highlight.scss b/app/assets/stylesheets/framework/feature_highlight.scss
index 4f26cd015e4..cad915bc86f 100644
--- a/app/assets/stylesheets/framework/feature_highlight.scss
+++ b/app/assets/stylesheets/framework/feature_highlight.scss
@@ -79,7 +79,7 @@
border-right-color: $dropdown-border-color;
}
- .popover-content {
+ .popover-body {
padding: 0;
}
}
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index d835d49d8b2..f77ec4b6a2c 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -75,7 +75,7 @@
padding: 8px $gl-padding;
border-bottom: 1px solid $border-color;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
text-align: left;
}
@@ -125,7 +125,7 @@
&.wiki {
padding: $gl-padding;
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
padding: $gl-padding * 2;
}
}
@@ -364,7 +364,7 @@ span.idiff {
}
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
display: block;
.file-actions {
diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss
index 621a4adc0cb..0ee5748952a 100644
--- a/app/assets/stylesheets/framework/filters.scss
+++ b/app/assets/stylesheets/framework/filters.scss
@@ -9,19 +9,19 @@
float: right;
margin-right: 0;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
float: none;
}
}
}
.filters-section {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
display: inline-block;
}
}
-@media (min-width: $screen-sm-min) {
+@include media-breakpoint-up(sm) {
.filter-item:not(:last-child) {
margin-right: 6px;
}
@@ -37,7 +37,7 @@
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.filter-item {
display: block;
margin: 0 0 10px;
@@ -53,7 +53,7 @@
display: -webkit-flex;
display: flex;
- @media (max-width: $screen-xs-min) {
+ @include media-breakpoint-down(xs) {
-webkit-flex-direction: column;
flex-direction: column;
}
@@ -193,7 +193,7 @@
border: 1px solid $border-color;
background-color: $white-light;
- @media (max-width: $screen-xs-min) {
+ @include media-breakpoint-down(xs) {
-webkit-flex: 1 1 auto;
flex: 1 1 auto;
margin-bottom: 10px;
@@ -264,7 +264,7 @@
max-width: 280px;
overflow: auto;
- @media (max-width: $screen-xs-min) {
+ @include media-breakpoint-down(xs) {
width: auto;
left: 0;
right: 0;
@@ -315,7 +315,7 @@
.filtered-search-history-dropdown {
width: 40%;
- @media (max-width: $screen-xs-min) {
+ @include media-breakpoint-down(xs) {
left: 0;
right: 0;
max-width: none;
@@ -353,7 +353,7 @@
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.issues-details-filters {
padding: 0 0 10px;
background-color: $white-light;
@@ -361,7 +361,7 @@
}
}
-@media (max-width: $screen-xs) {
+@include media-breakpoint-down(sm) {
.filter-dropdown-container {
.dropdown-toggle,
.dropdown,
diff --git a/app/assets/stylesheets/framework/flash.scss b/app/assets/stylesheets/framework/flash.scss
index cb2f71b0033..52c3f18a682 100644
--- a/app/assets/stylesheets/framework/flash.scss
+++ b/app/assets/stylesheets/framework/flash.scss
@@ -8,19 +8,19 @@
.flash-notice {
@extend .alert;
- @extend .alert-info;
+ background-color: $blue-500;
margin: 0;
}
.flash-warning {
@extend .alert;
- @extend .alert-warning;
+ background-color: $orange-500;
margin: 0;
}
.flash-alert {
@extend .alert;
- @extend .alert-danger;
+ background-color: $red-500;
margin: 0;
.flash-text,
@@ -42,14 +42,16 @@
.flash-success {
@extend .alert;
- @extend .alert-success;
+ background-color: $green-500;
margin: 0;
}
.flash-notice,
.flash-alert,
- .flash-success {
+ .flash-success,
+ .flash-warning {
border-radius: $border-radius-default;
+ color: $white-light;
.container-fluid,
.container-fluid.container-limited {
@@ -72,7 +74,7 @@
}
}
-@media (max-width: $screen-sm-max) {
+@include media-breakpoint-down(sm) {
ul.notes {
.flash-container.timeline-content {
margin-left: 0;
diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss
index 1fb4e3ec761..c76ea532912 100644
--- a/app/assets/stylesheets/framework/forms.scss
+++ b/app/assets/stylesheets/framework/forms.scss
@@ -36,8 +36,8 @@ label {
}
}
-.control-label {
- @extend .col-sm-2;
+.form-control-label {
+ @extend .col-md-2;
}
.inline-input-group {
@@ -48,21 +48,21 @@ label {
width: 150px;
}
-@media (min-width: $screen-sm-min) {
+@include media-breakpoint-up(sm) {
.custom-form-control {
width: 150px;
}
}
/* Medium devices (desktops, 992px and up) */
-@media (min-width: $screen-md-min) {
+@include media-breakpoint-up(md) {
.custom-form-control {
width: 170px;
}
}
/* Large devices (large desktops, 1200px and up) */
-@media (min-width: $screen-lg-min) {
+@include media-breakpoint-up(lg) {
.custom-form-control {
width: 200px;
}
@@ -72,7 +72,7 @@ label {
margin-left: 0;
margin-right: 0;
- .control-label {
+ .form-control-label {
font-weight: $gl-font-weight-bold;
padding-top: 4px;
}
@@ -83,7 +83,8 @@ label {
font-family: $monospace_font;
}
- .input-group-btn .btn {
+ .input-group-prepend .btn,
+ .input-group-append .btn {
padding: 3px $gl-btn-padding;
background-color: $gray-light;
border: 1px solid $border-color;
@@ -102,10 +103,10 @@ label {
}
}
- @media(max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
padding: 0 $gl-padding;
- .control-label,
+ .form-control-label,
.text-block {
padding-left: 0;
}
@@ -124,7 +125,7 @@ label {
&.input-short {
width: $input-short-width;
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
width: $input-short-md-width;
}
}
@@ -163,8 +164,8 @@ label {
margin-top: 35px;
}
-.form-group .control-label,
-.form-group .control-label-full-width {
+.form-group .form-control-label,
+.form-group .form-control-label-full-width {
font-weight: $gl-font-weight-normal;
}
@@ -178,17 +179,19 @@ label {
max-width: 180px;
}
- .input-group-addon {
+ .input-group-prepend,
+ .input-group-append {
background-color: $input-group-addon-bg;
}
- .input-group-addon:not(:first-child):not(:last-child) {
+ .input-group-prepend:not(:first-child):not(:last-child),
+ .input-group-append:not(:first-child):not(:last-child) {
border-left: 0;
border-right: 0;
}
}
-.help-block {
+.form-text.text-muted {
margin-bottom: 0;
margin-top: #{$grid-size / 2};
}
@@ -229,7 +232,7 @@ label {
}
}
-@media(max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.remember-me {
.remember-me-checkbox {
margin-top: 0;
diff --git a/app/assets/stylesheets/framework/gitlab_theme.scss b/app/assets/stylesheets/framework/gitlab_theme.scss
index 0bbd6eb27c1..3bbb50117bc 100644
--- a/app/assets/stylesheets/framework/gitlab_theme.scss
+++ b/app/assets/stylesheets/framework/gitlab_theme.scss
@@ -21,7 +21,7 @@
}
.container-fluid {
- .navbar-toggle {
+ .navbar-toggler {
border-left: 1px solid lighten($color-700, 10%);
}
}
@@ -63,7 +63,7 @@
&:hover,
&:focus {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
background-color: rgba($color-200, 0.2);
}
@@ -165,15 +165,18 @@
}
}
- .sidebar-top-level-items > li.active .badge {
+ .sidebar-top-level-items > li.active .badge.badge-pill {
color: $color-800;
}
- .nav-links li.active a {
- border-bottom-color: $color-500;
+ .nav-links li {
+ &.active a,
+ a.active {
+ border-bottom: 2px solid $color-500;
- .badge {
- font-weight: $gl-font-weight-bold;
+ .badge.badge-pill {
+ font-weight: $gl-font-weight-bold;
+ }
}
}
@@ -277,8 +280,8 @@ body {
}
.container-fluid {
- .navbar-toggle,
- .navbar-toggle:hover {
+ .navbar-toggler,
+ .navbar-toggler:hover {
color: $theme-gray-700;
border-left: 1px solid $theme-gray-200;
}
@@ -328,7 +331,7 @@ body {
}
}
- .sidebar-top-level-items > li.active .badge {
+ .sidebar-top-level-items > li.active .badge.badge-pill {
color: $theme-gray-900;
}
}
diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss
index 0136af76a13..2085e5646ef 100644
--- a/app/assets/stylesheets/framework/header.scss
+++ b/app/assets/stylesheets/framework/header.scss
@@ -37,6 +37,7 @@
}
.header-content {
+ width: 100%;
display: -webkit-flex;
display: flex;
justify-content: space-between;
@@ -91,7 +92,7 @@
border-radius: $border-radius-default;
.tanuki-logo {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
margin-right: 8px;
}
}
@@ -110,7 +111,7 @@
}
&.menu-expanded {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.title-container {
display: none;
}
@@ -133,13 +134,13 @@
border-top: 0;
padding: 0;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
flex: 1 1 auto;
}
.nav {
- > li:not(.hidden-xs) a {
- @media (max-width: $screen-xs-max) {
+ > li:not(.d-none) a {
+ @include media-breakpoint-down(xs) {
margin-left: 0;
min-width: 100%;
}
@@ -156,7 +157,7 @@
}
}
- .navbar-toggle {
+ .navbar-toggler {
right: -10px;
border-radius: 0;
min-width: 45px;
@@ -181,14 +182,14 @@
}
.navbar-nav {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
display: -webkit-flex;
display: flex;
padding-right: 10px;
}
li {
- .badge {
+ .badge.badge-pill {
box-shadow: none;
font-weight: $gl-font-weight-bold;
}
@@ -197,7 +198,7 @@
.nav > li {
&.header-user {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
padding-left: 10px;
}
}
@@ -208,7 +209,7 @@
padding: 6px 8px;
height: 32px;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
padding: 0;
}
@@ -324,8 +325,8 @@
fill: currentColor;
}
-.header-user .dropdown-menu-nav,
-.header-new .dropdown-menu-nav {
+.header-user .dropdown-menu,
+.header-new .dropdown-menu {
margin-top: $dropdown-vertical-offset;
}
@@ -378,7 +379,7 @@
margin-bottom: 0;
line-height: 16px;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
flex-wrap: wrap;
}
@@ -410,7 +411,7 @@
.breadcrumb-item-text {
text-decoration: inherit;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
@include str-truncated(128px);
}
}
@@ -452,7 +453,7 @@
.navbar-nav {
li {
- .badge {
+ .badge.badge-pill {
position: inherit;
font-weight: $gl-font-weight-normal;
margin-left: -6px;
@@ -478,7 +479,7 @@
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.navbar-gitlab .container-fluid {
font-size: 18px;
@@ -493,7 +494,7 @@
margin-left: -8px;
margin-right: -10px;
- .nav > li:not(.hidden-xs) {
+ .nav > li:not(.d-none) {
display: table-cell !important;
width: 25%;
@@ -514,7 +515,7 @@
}
.header-user {
- .dropdown-menu-nav {
+ .dropdown-menu {
width: auto;
min-width: 160px;
margin-top: 4px;
diff --git a/app/assets/stylesheets/framework/issue_box.scss b/app/assets/stylesheets/framework/issue_box.scss
index d8c57a0e2d9..1d247671761 100644
--- a/app/assets/stylesheets/framework/issue_box.scss
+++ b/app/assets/stylesheets/framework/issue_box.scss
@@ -11,7 +11,7 @@
padding: 5px 11px;
margin-top: 4px;
/* Small devices (tablets, 768px and up) */
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
padding: 0 $gl-btn-padding;
margin-top: 5px;
}
diff --git a/app/assets/stylesheets/framework/layout.scss b/app/assets/stylesheets/framework/layout.scss
index d107422e517..0536c39cee7 100644
--- a/app/assets/stylesheets/framework/layout.scss
+++ b/app/assets/stylesheets/framework/layout.scss
@@ -15,7 +15,7 @@ body {
background-color: $white-light !important;
}
- &.card-content {
+ &.board-card-content {
background-color: $gray-darker;
.content-wrapper {
@@ -74,7 +74,7 @@ body {
}
/* Center alert text and alert action links on smaller screens */
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
.alert {
text-align: center;
}
diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss
index 45517416e93..d54490c87c6 100644
--- a/app/assets/stylesheets/framework/lists.scss
+++ b/app/assets/stylesheets/framework/lists.scss
@@ -2,7 +2,7 @@
* Well styled list
*
*/
-.well-list {
+.hover-list {
position: relative;
margin: 0;
padding: 0;
@@ -72,7 +72,7 @@
}
}
- .well-title {
+ .card.card-body-title {
font-size: $list-font-size;
line-height: 18px;
}
@@ -159,7 +159,7 @@ ul.content-list {
&:last-child {
margin-right: 0;
- @media(max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
margin: 0 auto;
}
}
@@ -173,7 +173,7 @@ ul.content-list {
.member-controls {
float: none;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
float: right;
}
}
@@ -228,7 +228,7 @@ ul.content-list {
}
}
- .label-default {
+ .badge-secondary {
color: $gl-text-color-secondary;
}
@@ -237,7 +237,7 @@ ul.content-list {
}
}
-.panel > .content-list > li {
+.card > .content-list > li {
padding: $gl-padding-top $gl-padding;
}
diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss
index 7b5d1c2cf8b..b893151e4fe 100644
--- a/app/assets/stylesheets/framework/markdown_area.scss
+++ b/app/assets/stylesheets/framework/markdown_area.scss
@@ -74,7 +74,7 @@
}
.md-header-tab {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
flex: 1;
width: 100%;
border-bottom: 1px solid $border-color;
@@ -90,7 +90,7 @@
&.active {
display: block;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
flex: none;
display: flex;
justify-content: center;
@@ -192,7 +192,7 @@
margin-left: $gl-padding;
margin-right: -5px;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
margin-left: 0;
margin-right: 0;
}
@@ -268,7 +268,7 @@
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.atwho-view-ul {
width: 350px;
}
diff --git a/app/assets/stylesheets/framework/mobile.scss b/app/assets/stylesheets/framework/mobile.scss
index 9e03bb98b8e..6244fb86fea 100644
--- a/app/assets/stylesheets/framework/mobile.scss
+++ b/app/assets/stylesheets/framework/mobile.scss
@@ -1,5 +1,5 @@
/** Common mobile (screen XS, SM) styles **/
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.container .content {
margin-top: 20px;
}
@@ -14,7 +14,7 @@
font-size: 12px;
margin-right: 3px;
- .badge {
+ .badge.badge-pill {
display: none;
}
}
@@ -86,7 +86,7 @@
}
}
-@media (max-width: $screen-sm-max) {
+@include media-breakpoint-down(sm) {
.issues-filters {
.milestone-filter {
display: none;
diff --git a/app/assets/stylesheets/framework/modal.scss b/app/assets/stylesheets/framework/modal.scss
index eb789cc64b0..ed5a1c91d8f 100644
--- a/app/assets/stylesheets/framework/modal.scss
+++ b/app/assets/stylesheets/framework/modal.scss
@@ -46,7 +46,7 @@
margin-left: $grid-size;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
flex-direction: column;
.btn + .btn {
@@ -55,7 +55,7 @@
}
}
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
.btn:first-of-type {
margin-left: auto;
}
@@ -74,17 +74,11 @@ body.modal-open {
}
}
-@media (min-width: $screen-lg-min) {
- .modal-full {
- width: 98%;
- }
-}
-
.modal {
background-color: $black-transparent;
z-index: 2100;
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
.modal-dialog {
margin: 30px auto;
}
diff --git a/app/assets/stylesheets/framework/page_header.scss b/app/assets/stylesheets/framework/page_header.scss
index 0c879f40930..660e3dcac8d 100644
--- a/app/assets/stylesheets/framework/page_header.scss
+++ b/app/assets/stylesheets/framework/page_header.scss
@@ -3,7 +3,7 @@
padding: 10px 0;
margin-bottom: 0;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: flex;
align-items: center;
@@ -19,7 +19,7 @@
margin-right: 3px;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.btn {
width: 100%;
margin-top: 10px;
@@ -35,7 +35,7 @@
@extend .avatar-inline;
margin-left: 0;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
margin-left: 4px;
}
}
diff --git a/app/assets/stylesheets/framework/pagination.scss b/app/assets/stylesheets/framework/pagination.scss
index c3ec9db0f07..d3e013590b6 100644
--- a/app/assets/stylesheets/framework/pagination.scss
+++ b/app/assets/stylesheets/framework/pagination.scss
@@ -6,6 +6,7 @@
.pagination {
padding: 0;
+ margin: 20px 0;
a {
cursor: pointer;
@@ -30,7 +31,7 @@
}
}
-.panel > .gl-pagination {
+.card > .gl-pagination {
margin: 0;
}
@@ -44,7 +45,7 @@
display: none;
}
- .page {
+ .page-item {
display: none;
&.active {
@@ -57,13 +58,13 @@
/**
* Small screen pagination
*/
-@media (max-width: $screen-xs-min) {
+@include media-breakpoint-down(xs) {
.gl-pagination {
.pagination li a {
padding: 6px 10px;
}
- .page {
+ .page-item {
display: none;
&.active {
@@ -76,9 +77,9 @@
/**
* Medium screen pagination
*/
-@media (min-width: $screen-xs-min) and (max-width: $screen-md-max) {
+@media (min-width: map-get($grid-breakpoints, xs)) and (max-width: map-get($grid-breakpoints, sm)) {
.gl-pagination {
- .page {
+ .page-item {
display: none;
&.active,
diff --git a/app/assets/stylesheets/framework/panels.scss b/app/assets/stylesheets/framework/panels.scss
index e8d69e62194..a8e28104a94 100644
--- a/app/assets/stylesheets/framework/panels.scss
+++ b/app/assets/stylesheets/framework/panels.scss
@@ -1,14 +1,14 @@
-.panel {
+.card {
margin-bottom: $gl-padding;
}
-.panel-slim {
- @extend .panel;
+.card-slim {
+ @extend .card;
margin-bottom: $gl-vert-padding;
}
-.panel-heading {
+.card-header {
padding: $gl-vert-padding $gl-padding;
line-height: 36px;
@@ -21,7 +21,7 @@
line-height: 20px;
}
- .badge {
+ .badge.badge-pill {
margin-top: -2px;
margin-left: 5px;
}
@@ -41,12 +41,13 @@
}
}
-.panel-empty-heading {
+.card-empty-heading {
border-bottom: 0;
}
-.panel-body {
+.card-body {
padding: $gl-padding;
+ background-color: $white-light;
.form-actions {
margin: -$gl-padding;
@@ -54,7 +55,7 @@
}
}
-.panel-title {
+.card-title {
font-size: inherit;
line-height: inherit;
}
diff --git a/app/assets/stylesheets/framework/responsive_tables.scss b/app/assets/stylesheets/framework/responsive_tables.scss
index 34fccf6f0a4..764bebd82c6 100644
--- a/app/assets/stylesheets/framework/responsive_tables.scss
+++ b/app/assets/stylesheets/framework/responsive_tables.scss
@@ -6,7 +6,7 @@
.gl-responsive-table-row-layout {
width: 100%;
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
display: flex;
align-items: center;
@@ -21,7 +21,7 @@
margin-top: 10px;
border: 1px solid $border-color;
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
margin: 0;
padding: $gl-padding 0;
border: 0;
@@ -44,13 +44,13 @@
&.section-#{$width} {
flex: 0 0 #{$width + '%'};
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
max-width: #{$width + '%'};
}
}
}
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
display: flex;
align-self: stretch;
padding: 10px;
@@ -65,7 +65,7 @@
&.section-wrap {
white-space: normal;
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
flex-wrap: wrap;
}
}
@@ -76,11 +76,11 @@
}
.table-button-footer {
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
text-align: right;
}
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
display: block;
align-self: stretch;
min-height: 0;
@@ -122,7 +122,7 @@
.table-row-header {
font-size: 13px;
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
display: none;
}
}
@@ -132,13 +132,13 @@
color: $gl-text-color-secondary;
text-align: left;
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
display: none;
}
}
.table-mobile-content {
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
@include flex-max-width(60);
text-align: right;
}
@@ -154,7 +154,7 @@
overflow: hidden;
text-overflow: ellipsis;
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
flex: 0 0 90%;
}
diff --git a/app/assets/stylesheets/framework/secondary_navigation_elements.scss b/app/assets/stylesheets/framework/secondary_navigation_elements.scss
index 937638d50e8..847fc8c0792 100644
--- a/app/assets/stylesheets/framework/secondary_navigation_elements.scss
+++ b/app/assets/stylesheets/framework/secondary_navigation_elements.scss
@@ -27,17 +27,18 @@
color: $black;
border-bottom: 2px solid $gray-darkest;
- .badge {
+ .badge.badge-pill {
color: $black;
}
}
}
- &.active a {
+ &.active a,
+ a.active {
color: $black;
font-weight: $gl-font-weight-bold;
- .badge {
+ .badge.badge-pill {
color: $black;
}
}
@@ -56,7 +57,7 @@
white-space: normal;
/* Small devices (phones, tablets, 768px and lower) */
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
width: 100%;
}
}
@@ -80,7 +81,7 @@
}
/* Small devices (phones, tablets, 768px and lower) */
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
width: 100%;
&.mobile-separator {
@@ -124,13 +125,13 @@
position: relative;
/* Medium devices (desktops, 992px and up) */
- @media (min-width: $screen-md-min) { width: 200px; }
+ @include media-breakpoint-up(md) { width: 200px; }
/* Large devices (large desktops, 1200px and up) */
- @media (min-width: $screen-lg-min) { width: 250px; }
+ @include media-breakpoint-up(lg) { width: 250px; }
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
padding-bottom: 0;
width: 100%;
@@ -172,7 +173,7 @@
.nav-controls {
width: auto;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
width: 100%;
}
}
@@ -192,7 +193,7 @@
width: 100%;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
flex-flow: row wrap;
.nav-controls {
@@ -352,7 +353,7 @@
max-width: 300px;
width: auto;
- @media(max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
max-width: 250px;
}
}
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index 64fff7463d2..8c716400913 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -31,7 +31,7 @@
.right-sidebar-collapsed {
padding-right: 0;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
&:not(.wiki-sidebar):not(.build-sidebar):not(.issuable-bulk-update-sidebar) .content-wrapper {
padding-right: $gutter_collapsed_width;
}
@@ -65,13 +65,13 @@
display: inline-flex;
}
- @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
+ @include media-breakpoint-only(sm) {
&:not(.wiki-sidebar):not(.build-sidebar):not(.issuable-bulk-update-sidebar) .content-wrapper {
padding-right: $gutter_collapsed_width;
}
}
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
.content-wrapper {
padding-right: $gutter_width;
}
diff --git a/app/assets/stylesheets/framework/snippets.scss b/app/assets/stylesheets/framework/snippets.scss
index 430633bb01b..f80e9b1014b 100644
--- a/app/assets/stylesheets/framework/snippets.scss
+++ b/app/assets/stylesheets/framework/snippets.scss
@@ -40,7 +40,7 @@
}
.snippet-actions {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
float: right;
}
}
diff --git a/app/assets/stylesheets/framework/tables.scss b/app/assets/stylesheets/framework/tables.scss
index 5bde96caf42..a10bd1544c5 100644
--- a/app/assets/stylesheets/framework/tables.scss
+++ b/app/assets/stylesheets/framework/tables.scss
@@ -48,7 +48,7 @@ table {
}
.responsive-table {
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
th {
width: 100%;
}
diff --git a/app/assets/stylesheets/framework/tabs.scss b/app/assets/stylesheets/framework/tabs.scss
index c8ba14b7066..6b60149fbbb 100644
--- a/app/assets/stylesheets/framework/tabs.scss
+++ b/app/assets/stylesheets/framework/tabs.scss
@@ -1,6 +1,7 @@
.gitlab-tabs {
background: $gray-light;
border: 1px solid $border-color;
+ flex-wrap: nowrap;
li {
width: 50%;
diff --git a/app/assets/stylesheets/framework/timeline.scss b/app/assets/stylesheets/framework/timeline.scss
index 373f35e71d8..75c11590547 100644
--- a/app/assets/stylesheets/framework/timeline.scss
+++ b/app/assets/stylesheets/framework/timeline.scss
@@ -4,7 +4,7 @@
padding: 0;
&::before {
- @include notes-media('max', $screen-xs-min) {
+ @include notes-media('max', map-get($grid-breakpoints, xs)) {
background: none;
}
}
@@ -34,7 +34,7 @@
.timeline-entry-inner {
position: relative;
- @include notes-media('max', $screen-xs-min) {
+ @include notes-media('max', map-get($grid-breakpoints, xs)) {
.timeline-icon {
display: none;
}
diff --git a/app/assets/stylesheets/framework/toggle.scss b/app/assets/stylesheets/framework/toggle.scss
index 0cd83df218f..d5cc78a6680 100644
--- a/app/assets/stylesheets/framework/toggle.scss
+++ b/app/assets/stylesheets/framework/toggle.scss
@@ -121,7 +121,7 @@
cursor: not-allowed;
}
- @media (max-width: $screen-xs-min) {
+ @include media-breakpoint-down(xs) {
width: 50px;
&::before,
diff --git a/app/assets/stylesheets/framework/tw_bootstrap.scss b/app/assets/stylesheets/framework/tw_bootstrap.scss
deleted file mode 100644
index 1c6e2bf3074..00000000000
--- a/app/assets/stylesheets/framework/tw_bootstrap.scss
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Twitter bootstrap with GitLab customizations/additions
- *
- */
-
-// Core variables and mixins
-@import "bootstrap/variables";
-@import "bootstrap/mixins";
-
-// Reset
-@import "bootstrap/normalize";
-@import "bootstrap/print";
-
-// Core CSS
-@import "bootstrap/scaffolding";
-@import "bootstrap/type";
-@import "bootstrap/code";
-@import "bootstrap/grid";
-@import "bootstrap/tables";
-@import "bootstrap/forms";
-@import "bootstrap/buttons";
-
-// Components
-@import "bootstrap/component-animations";
-// @import "bootstrap/dropdowns";
-@import "bootstrap/button-groups";
-@import "bootstrap/input-groups";
-@import "bootstrap/navs";
-@import "bootstrap/navbar";
-@import "bootstrap/breadcrumbs";
-@import "bootstrap/pagination";
-@import "bootstrap/pager";
-@import "bootstrap/labels";
-@import "bootstrap/badges";
-@import "bootstrap/alerts";
-@import "bootstrap/progress-bars";
-@import "bootstrap/list-group";
-@import "bootstrap/wells";
-@import "bootstrap/close";
-@import "bootstrap/panels";
-
-// Components w/ JavaScript
-@import "bootstrap/modals";
-@import "bootstrap/tooltip";
-@import "bootstrap/popovers";
-
-// Utility classes
-.clearfix {
- @include clearfix();
-}
-
-.center-block {
- @include center-block();
-}
-
-.pull-right {
- float: right !important;
-}
-
-.pull-left {
- float: left !important;
-}
-
-.hide {
- display: none;
-}
-
-.show {
- display: block !important;
-}
-
-.invisible {
- visibility: hidden;
-}
-
-.text-hide {
- @include text-hide();
-}
-
-.hidden {
- display: none !important;
- visibility: hidden !important;
-}
-
-.affix {
- position: fixed;
-}
-
-/*
- * Fix <summary> elements on firefox
- * See https://github.com/necolas/normalize.css/issues/640
- * and https://github.com/twbs/bootstrap/issues/21060
- *
- */
-summary {
- display: list-item;
-}
-
-@import "bootstrap/responsive-utilities";
-
-// Labels
-.label {
- padding: 4px 5px;
- font-size: 12px;
- font-style: normal;
- font-weight: $gl-font-weight-normal;
- display: inline-block;
-
- &.label-gray {
- background-color: $label-gray-bg;
- color: $gl-text-color;
- text-shadow: none;
- }
-
- &.label-inverse {
- background-color: $label-inverse-bg;
- }
-}
-
-
-/**
- * fix to keep tooltips position in top navigation bar
- *
- */
-.navbar .nav > li {
- position: relative;
- white-space: nowrap;
-}
-
-/**
- * Add some extra stuff to panels
- *
- */
-
-.panel {
- box-shadow: none;
-
- .panel-body {
- form,
- pre {
- margin: 0;
- }
-
- .form-actions {
- margin: -15px;
- margin-top: 18px;
- }
- }
-
- .panel-footer {
- .pagination {
- margin: 0;
- }
-
- .btn {
- min-width: 124px;
- }
-
- .btn-clipboard {
- min-width: 0;
- }
- }
-
- &.panel-small {
- .panel-heading {
- padding: 6px 15px;
- font-size: 13px;
- font-weight: $gl-font-weight-normal;
-
- a {
- color: $panel-heading-link-color;
- }
- }
- }
-
- &.panel-without-border {
- border: 0;
- }
-
- &.panel-without-margin {
- margin: 0;
- }
-}
-
-.panel-succes .panel-heading,
-.panel-info .panel-heading,
-.panel-danger .panel-heading,
-.panel-warning .panel-heading,
-.panel-primary .panel-heading,
-.alert {
- a:not(.btn) {
- @extend .alert-link;
- color: $white-light;
- text-decoration: underline;
- }
-}
-
-// Prevent datetimes on tooltips to break into two lines
-.local-timeago {
- white-space: nowrap;
-}
diff --git a/app/assets/stylesheets/framework/tw_bootstrap_variables.scss b/app/assets/stylesheets/framework/tw_bootstrap_variables.scss
deleted file mode 100644
index d04e555769b..00000000000
--- a/app/assets/stylesheets/framework/tw_bootstrap_variables.scss
+++ /dev/null
@@ -1,199 +0,0 @@
-// Override Bootstrap variables here (defaults from bootstrap-sass v3.3.3):
-// For all variables see https://github.com/twbs/bootstrap-sass/blob/master/templates/project/_bootstrap-variables.sass
-//
-// Variables
-// --------------------------------------------------
-
-
-//== Colors
-//
-//## Gray and brand colors for use across Bootstrap.
-
-// $gray-base: #000
-// $gray-darker: lighten($gray-base, 13.5%) // #222
-// $gray-dark: lighten($gray-base, 20%) // #333
-// $gray: lighten($gray-base, 33.5%) // #555
-// $gray-light: lighten($gray-base, 46.7%) // #777
-// $gray-lighter: lighten($gray-base, 93.5%) // #eee
-
-$brand-primary: $gl-primary;
-$brand-success: $gl-success;
-$brand-info: $gl-info;
-$brand-warning: $gl-warning;
-$brand-danger: $gl-danger;
-
-$border-radius-base: 3px !default;
-$border-radius-large: 3px !default;
-$border-radius-small: 3px !default;
-
-
-//== Scaffolding
-//
-$text-color: $gl-text-color;
-$link-color: $gl-link-color;
-$link-hover-color: $gl-link-hover-color;
-
-
-//== Typography
-//
-//## Font, line-height, and color for body text, headings, and more.
-
-$font-family-sans-serif: $regular_font;
-$font-family-monospace: $monospace_font;
-$font-size-base: $gl-font-size;
-
-
-//== Components
-//
-//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
-
-$padding-base-vertical: $gl-vert-padding;
-$padding-base-horizontal: $gl-padding;
-$component-active-color: $white-light;
-$component-active-bg: $brand-info;
-
-//== Forms
-//
-//##
-
-$input-color: $text-color;
-$input-border: $border-color;
-$input-border-focus: $focus-border-color;
-$legend-color: $text-color;
-
-
-//== Pagination
-//
-//##
-
-$pagination-color: $gl-text-color;
-$pagination-bg: $white-light;
-$pagination-border: $border-color;
-
-$pagination-hover-color: $gl-text-color;
-$pagination-hover-bg: $row-hover;
-$pagination-hover-border: $border-color;
-
-$pagination-active-color: $white-light;
-$pagination-active-bg: $gl-link-color;
-$pagination-active-border: $gl-link-color;
-
-$pagination-disabled-color: #cdcdcd;
-$pagination-disabled-bg: $gray-light;
-$pagination-disabled-border: $border-color;
-
-
-//== Form states and alerts
-//
-//## Define colors for form feedback states and, by default, alerts.
-
-$state-success-text: $white-light;
-$state-success-bg: $brand-success;
-$state-success-border: $brand-success;
-
-$state-info-text: $white-light;
-$state-info-bg: $brand-info;
-$state-info-border: $brand-info;
-
-$state-warning-text: $white-light;
-$state-warning-bg: $brand-warning;
-$state-warning-border: $brand-warning;
-
-$state-danger-text: $white-light;
-$state-danger-bg: $brand-danger;
-$state-danger-border: $brand-danger;
-
-
-//== Alerts
-//
-//## Define alert colors, border radius, and padding.
-
-$alert-border-radius: 0;
-
-
-//== Panels
-//
-//##
-
-$panel-border-radius: 2px;
-$panel-default-text: $text-color;
-$panel-default-border: $border-color;
-$panel-default-heading-bg: $gray-light;
-$panel-footer-bg: $gray-light;
-$panel-inner-border: $border-color;
-
-$badge-bg: $badge-bg;
-$badge-color: $badge-color;
-
-//== Wells
-//
-//##
-
-$well-bg: $gray-light;
-$well-border: #eee;
-
-//== Code
-//
-//##
-
-$code-color: $red-600;
-$code-bg: lighten($red-100, 2%);
-
-$kbd-color: $white-light;
-$kbd-bg: #333;
-
-//== Buttons
-//
-//##
-$btn-default-color: $gl-text-color;
-$btn-default-bg: $white-light;
-$btn-default-border: #e7e9ed;
-
-//== Nav
-//
-//##
-$nav-link-padding: 13px $gl-padding;
-
-//== Code
-//
-//##
-$pre-bg: $gray-light !default;
-$pre-color: $gl-text-color !default;
-$pre-border-color: $border-color;
-
-$table-bg-accent: $gray-light;
-
-$zindex-popover: 900;
-
-//== Modals
-//
-//##
-
-//** Padding applied to the modal body
-$modal-inner-padding: $gl-padding;
-
-//** Padding applied to the modal title
-$modal-title-padding: $gl-padding;
-//** Modal title line-height
-// $modal-title-line-height: $line-height-base
-
-//** Background color of modal content area
-$modal-content-bg: $gray-light;
-$modal-body-bg: $white-light;
-//** Modal content border color
-// $modal-content-border-color: rgba(0,0,0,.2)
-//** Modal content border color **for IE8**
-// $modal-content-fallback-border-color: #999
-
-//** Modal backdrop background color
-// $modal-backdrop-bg: #000
-//** Modal backdrop opacity
-// $modal-backdrop-opacity: .5
-//** Modal header border color
-// $modal-header-border-color: #e5e5e5
-//** Modal footer border color
-// $modal-footer-border-color: $modal-header-border-color
-
-$modal-lg: 860px;
-$modal-md: 540px;
-// $modal-sm: 300px
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index 9e1371648ed..ed0bfbbe08b 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -114,7 +114,7 @@
font-size: 0.95em;
}
- blockquote {
+ .blockquote {
color: $gl-grayish-blue;
font-size: inherit;
padding: 8px 24px;
@@ -122,12 +122,12 @@
border-left: 3px solid $white-dark;
}
- blockquote:dir(rtl) {
+ .blockquote:dir(rtl) {
border-left: 0;
border-right: 3px solid $white-dark;
}
- blockquote p {
+ .blockquote p {
color: $gl-grayish-blue !important;
font-size: inherit;
line-height: 1.5;
@@ -321,6 +321,16 @@ h6 {
/** CODE **/
pre {
font-family: $monospace_font;
+ display: block;
+ padding: $gl-padding-8;
+ margin: 0 0 $gl-padding-8;
+ font-size: 13px;
+ word-break: break-all;
+ word-wrap: break-word;
+ color: $gl-text-color;
+ background-color: $gray-light;
+ border: 1px solid $border-color;
+ border-radius: $border-radius-small;
}
code {
@@ -391,7 +401,7 @@ h4 {
}
.text-right-lg {
- @media (min-width: $screen-lg-min) {
+ @include media-breakpoint-up(lg) {
text-align: right;
}
}
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index b8ea8ee14c5..89b61530ddb 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -142,6 +142,11 @@ $border-gray-normal-dashed: darken($gray-normal, $darken-border-dashed-factor);
$border-gray-dark: darken($white-normal, $darken-border-factor);
/*
+ * Override Bootstrap 4 variables
+ */
+$secondary: $gray-light;
+
+/*
* UI elements
*/
$border-color: #e5e5e5;
@@ -230,7 +235,7 @@ $row-hover: $blue-50;
$row-hover-border: $blue-200;
$progress-color: #c0392b;
$header-height: 40px;
-$ide-statusbar-height: 27px;
+$ide-statusbar-height: 25px;
$fixed-layout-width: 1280px;
$limited-layout-width: 990px;
$limited-layout-width-sm: 790px;
@@ -306,6 +311,11 @@ $gl-warning: $orange-500;
$gl-danger: $red-500;
$gl-btn-active-background: rgba(0, 0, 0, 0.16);
$gl-btn-active-gradient: inset 0 2px 3px $gl-btn-active-background;
+// Bootstrap override states
+$success: $gl-success;
+$info: $gl-info;
+$warning: $gl-warning;
+$danger: $gl-danger;
/*
* Commit Diff Colors
diff --git a/app/assets/stylesheets/framework/wells.scss b/app/assets/stylesheets/framework/wells.scss
index 3fa7a260017..514fac82b1e 100644
--- a/app/assets/stylesheets/framework/wells.scss
+++ b/app/assets/stylesheets/framework/wells.scss
@@ -5,7 +5,7 @@
border-radius: $border-radius-default;
margin-bottom: $gl-padding;
- .well-segment {
+ .card.card-body-segment {
padding: $gl-padding;
&:not(:last-of-type) {
@@ -59,7 +59,7 @@
}
}
- .label.label-gray {
+ .label-gray {
background-color: $well-expand-item;
}
@@ -108,7 +108,7 @@
}
}
-.well-centered {
+.card.card-body-centered {
h1 {
font-weight: $gl-font-weight-normal;
text-align: center;
diff --git a/app/assets/stylesheets/mailers/highlighted_diff_email.scss b/app/assets/stylesheets/mailers/highlighted_diff_email.scss
index 658ac26fca9..b5eda79e5ed 100644
--- a/app/assets/stylesheets/mailers/highlighted_diff_email.scss
+++ b/app/assets/stylesheets/mailers/highlighted_diff_email.scss
@@ -138,7 +138,7 @@ pre {
margin: 0;
}
-blockquote {
+.blockquote {
color: $gl-grayish-blue;
padding: 0 0 0 15px;
margin: 0;
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index 6bb40bae9ed..1c3d312f7ac 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -58,7 +58,7 @@
.boards-app {
position: relative;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
transition: width $sidebar-transition-duration;
width: 100%;
@@ -81,11 +81,11 @@
white-space: nowrap;
min-height: 200px;
- @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
+ @include media-breakpoint-only(sm) {
height: calc(100vh - #{$issue-board-list-difference-sm});
}
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
height: calc(100vh - #{$issue-board-list-difference-md});
}
@@ -94,13 +94,13 @@
100vh - #{$issue-board-list-difference-xs} - #{$performance-bar-height}
);
- @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
+ @include media-breakpoint-only(sm) {
height: calc(
100vh - #{$issue-board-list-difference-sm} - #{$performance-bar-height}
);
}
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
height: calc(
100vh - #{$issue-board-list-difference-md} - #{$performance-bar-height}
);
@@ -117,7 +117,7 @@
white-space: normal;
vertical-align: top;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: 400px;
}
@@ -274,7 +274,7 @@
font-size: (26px / $issue-boards-font-size) * 1em;
}
-.card {
+.board-card {
position: relative;
padding: 11px 10px 11px $gl-padding;
background: $white-light;
@@ -290,7 +290,7 @@
}
&.is-active,
- &.is-active .card-assignee:hover a {
+ &.is-active .board-card-assignee:hover a {
background-color: $row-hover;
&:first-child:not(:only-child) {
@@ -298,7 +298,7 @@
}
}
- .label {
+ .badge {
border: 0;
outline: 0;
}
@@ -310,7 +310,7 @@
}
}
-.card-title {
+.board-card-title {
@include overflow-break-word();
margin: 0 30px 0 0;
font-size: 1em;
@@ -322,11 +322,11 @@
}
}
-.card-header {
+.board-card-header {
display: flex;
min-height: 20px;
- .card-assignee {
+ .board-card-assignee {
display: flex;
justify-content: flex-end;
position: absolute;
@@ -397,16 +397,16 @@
}
}
-.card-footer {
+.board-card-footer {
margin: 0 0 5px;
- .label {
+ .badge {
margin-top: 5px;
margin-right: 6px;
}
}
-.card-number {
+.board-card-number {
font-size: 12px;
color: $gl-text-color-secondary;
}
@@ -564,11 +564,11 @@
.add-issues-list-column {
width: 100%;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: 50%;
}
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
width: (100% / 3);
}
}
@@ -583,11 +583,11 @@
margin-right: -$gl-vert-padding;
overflow-y: scroll;
- .card-parent {
+ .board-card-parent {
padding: 0 5px 5px;
}
- .card {
+ .board-card {
border: 1px solid $border-gray-dark;
box-shadow: 0 1px 2px rgba($issue-boards-card-shadow, 0.3);
cursor: pointer;
@@ -637,7 +637,7 @@
display: none;
margin-right: 10px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: block;
}
}
@@ -645,7 +645,7 @@
.dropdown-menu-toggle {
width: 100px;
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
width: 140px;
}
}
diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss
index 50f32660445..9ee02ca1d83 100644
--- a/app/assets/stylesheets/pages/builds.scss
+++ b/app/assets/stylesheets/pages/builds.scss
@@ -215,7 +215,7 @@
}
.header-action-buttons {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.sidebar-toggle-btn {
margin-top: 0;
margin-left: 10px;
@@ -277,10 +277,6 @@
&.coverage {
padding: 0 16px 11px;
}
-
- .btn-group-justified {
- margin-top: 5px;
- }
}
.block-last {
@@ -305,7 +301,7 @@
background-color: $white-light;
}
- .label {
+ .badge.badge-pill {
margin-left: 2px;
}
@@ -320,7 +316,7 @@
}
}
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
display: block;
.btn {
diff --git a/app/assets/stylesheets/pages/clusters.scss b/app/assets/stylesheets/pages/clusters.scss
index 3fd13078131..2b6d92016d5 100644
--- a/app/assets/stylesheets/pages/clusters.scss
+++ b/app/assets/stylesheets/pages/clusters.scss
@@ -63,7 +63,7 @@
text-decoration: none;
}
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
> div {
display: flex;
align-items: center;
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index 0a27c6e0a25..a4ca82de90e 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -23,7 +23,7 @@
}
.commit-hash-full {
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
width: 80px;
white-space: nowrap;
overflow: hidden;
@@ -183,7 +183,7 @@
}
.commit-actions {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
.fa-spinner {
font-size: 12px;
}
@@ -327,11 +327,11 @@
}
&.invalid {
- @include status-color($gray-dark, $gray, $gray-darkest);
+ @include status-color($gray-dark, color("gray"), $gray-darkest);
border-color: $gray-darkest;
&:not(span):hover {
- color: $gray;
+ color: color("gray");
}
}
}
diff --git a/app/assets/stylesheets/pages/convdev_index.scss b/app/assets/stylesheets/pages/convdev_index.scss
index fb1899284fd..bd338326154 100644
--- a/app/assets/stylesheets/pages/convdev_index.scss
+++ b/app/assets/stylesheets/pages/convdev_index.scss
@@ -53,19 +53,19 @@ $space-between-cards: 8px;
padding: $space-between-cards / 2;
position: relative;
- @media (min-width: $screen-xs-min) {
+ @include media-breakpoint-up(xs) {
width: percentage(1 / 4);
}
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: percentage(1 / 5);
}
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
width: percentage(1 / 6);
}
- @media (min-width: $screen-lg-min) {
+ @include media-breakpoint-up(lg) {
width: percentage(1 / 10);
}
}
@@ -82,7 +82,7 @@ $space-between-cards: 8px;
.convdev-card-low {
border-top-color: $color-low-score;
- .card-score-big {
+ .board-card-score-big {
background-color: $red-50;
}
}
@@ -90,7 +90,7 @@ $space-between-cards: 8px;
.convdev-card-average {
border-top-color: $color-average-score;
- .card-score-big {
+ .board-card-score-big {
background-color: $orange-50;
}
}
@@ -98,7 +98,7 @@ $space-between-cards: 8px;
.convdev-card-high {
border-top-color: $color-high-score;
- .card-score-big {
+ .board-card-score-big {
background-color: $green-50;
}
}
@@ -112,14 +112,14 @@ $space-between-cards: 8px;
margin: 0 0 2px;
}
- .text-light {
+ .light-text {
font-size: 13px;
line-height: 1.25;
color: $gl-text-color-secondary;
}
}
-.card-scores {
+.board-card-scores {
display: flex;
justify-content: space-around;
align-items: center;
@@ -127,22 +127,22 @@ $space-between-cards: 8px;
line-height: 1;
}
-.card-score {
+.board-card-score {
color: $gl-text-color-secondary;
- .card-score-name {
+ .board-card-score-name {
font-size: 13px;
margin-top: 4px;
}
}
-.card-score-value {
+.board-card-score-value {
font-size: 16px;
color: $gl-text-color;
font-weight: $gl-font-weight-normal;
}
-.card-score-big {
+.board-card-score-big {
border-top: 2px solid $border-color;
border-bottom: 1px solid $border-color;
font-size: 22px;
@@ -150,7 +150,7 @@ $space-between-cards: 8px;
font-weight: $gl-font-weight-normal;
}
-.card-buttons {
+.board-card-buttons {
display: flex;
> * {
diff --git a/app/assets/stylesheets/pages/cycle_analytics.scss b/app/assets/stylesheets/pages/cycle_analytics.scss
index cfef6476d4d..a22c666a525 100644
--- a/app/assets/stylesheets/pages/cycle_analytics.scss
+++ b/app/assets/stylesheets/pages/cycle_analytics.scss
@@ -15,7 +15,7 @@
max-width: 480px;
padding: 0 $gl-padding;
- @media (max-width: $screen-sm-min) {
+ @include media-breakpoint-down(sm) {
margin: 0 auto;
}
}
@@ -75,13 +75,13 @@
}
}
- .panel {
+ .card {
.content-block {
padding: 24px 0;
border-bottom: 0;
position: relative;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
padding: 6px 0 24px;
}
}
@@ -89,7 +89,7 @@
.column {
text-align: center;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
padding: 15px 0;
}
@@ -106,7 +106,7 @@
}
&:last-child {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
text-align: center;
}
}
@@ -213,7 +213,7 @@
.stage-panel {
min-width: 968px;
- .panel-heading {
+ .card-header {
padding: 0;
background-color: transparent;
}
@@ -266,7 +266,9 @@
&.issue-title,
&.commit-title,
&.merge-merquest-title {
- @include text-overflow();
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
max-width: 100%;
display: block;
diff --git a/app/assets/stylesheets/pages/detail_page.scss b/app/assets/stylesheets/pages/detail_page.scss
index 2f2c04206e2..7b36bcb3c7d 100644
--- a/app/assets/stylesheets/pages/detail_page.scss
+++ b/app/assets/stylesheets/pages/detail_page.scss
@@ -14,7 +14,7 @@
white-space: nowrap;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
display: block;
}
}
@@ -25,7 +25,7 @@
display: flex;
flex-grow: 1;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
padding-left: 0;
padding-right: 0;
}
@@ -36,7 +36,7 @@
flex-shrink: 0;
flex: 0 0 auto;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
width: 100%;
margin-top: 10px;
diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss
index 70ce5de6a6c..f06c9dcdf8c 100644
--- a/app/assets/stylesheets/pages/diff.scss
+++ b/app/assets/stylesheets/pages/diff.scss
@@ -86,13 +86,13 @@
&.left-side-selected {
td.line_content.parallel.right-side {
- @include user-select(none);
+ user-select: none;
}
}
&.right-side-selected {
td.line_content.parallel.left-side {
- @include user-select(none);
+ user-select: none;
}
}
}
@@ -109,7 +109,7 @@
.old_line,
.new_line {
- @include user-select(none);
+ user-select: none;
margin: 0;
border: 0;
padding: 0 5px;
@@ -592,14 +592,14 @@
}
.commit-stat-summary {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
margin-left: -$gl-padding;
padding-left: $gl-padding;
background-color: $white-light;
}
}
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
position: -webkit-sticky;
position: sticky;
top: 24px;
@@ -610,10 +610,6 @@
top: 76px;
}
- &:not(.is-stuck) .diff-stats-additions-deletions-collapsed {
- display: none;
- }
-
&.is-stuck {
padding-top: 0;
padding-bottom: 0;
@@ -622,13 +618,21 @@
.diff-stats-additions-deletions-expanded,
.inline-parallel-buttons {
- display: none;
+ display: none !important;
+ }
+ }
+ }
+
+ @include media-breakpoint-up(lg) {
+ &.is-stuck {
+ .diff-stats-additions-deletions-collapsed {
+ display: block !important;
}
}
}
}
-@media (min-width: $screen-sm-min) {
+@include media-breakpoint-up(sm) {
.with-performance-bar {
.diff-files-changed.diff-files-changed-merge-request {
top: 76px + $performance-bar-height;
@@ -641,7 +645,7 @@
width: 100%;
z-index: 150;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
left: $gl-padding;
}
@@ -772,9 +776,9 @@
}
}
-.frame .badge,
-.image-diff-avatar-link .badge,
-.notes > .badge {
+.frame .badge.badge-pill,
+.image-diff-avatar-link .badge.badge-pill,
+.notes > .badge.badge-pill {
position: absolute;
background-color: $blue-400;
color: $white-light;
@@ -788,7 +792,7 @@
}
}
-.frame .badge,
+.frame .badge.badge-pill,
.frame .image-comment-badge {
// Center align badges on the frame
transform: translate(-50%, -50%);
@@ -811,14 +815,14 @@
.image-diff-avatar-link {
position: relative;
- .badge,
+ .badge.badge-pill,
.image-comment-badge {
top: 25px;
right: 8px;
}
}
-.notes > .badge {
+.notes > .badge.badge-pill {
display: none;
left: -13px;
}
@@ -840,7 +844,7 @@
display: none;
}
- .notes > .badge {
+ .notes > .badge.badge-pill {
display: block;
}
}
diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss
index 8ecda50602d..437621299e0 100644
--- a/app/assets/stylesheets/pages/editor.scss
+++ b/app/assets/stylesheets/pages/editor.scss
@@ -37,7 +37,7 @@
padding-top: 7px;
padding-bottom: 7px;
- .pull-right {
+ .float-right {
height: 20px;
}
}
@@ -63,11 +63,11 @@
max-width: 450px;
float: left;
- @media(max-width: $screen-md-max) {
+ @media(max-width: map-get($grid-breakpoints, lg)-1) {
width: 280px;
}
- @media(max-width: $screen-sm-max) {
+ @media(max-width: map-get($grid-breakpoints, md)-1) {
width: 180px;
}
}
@@ -111,10 +111,10 @@
}
-@media(max-width: $screen-xs-max){
+@include media-breakpoint-down(xs) {
.file-editor {
.file-title {
- .pull-right {
+ .float-right {
height: auto;
}
}
@@ -153,7 +153,7 @@
vertical-align: top;
display: inline-block;
- @media(max-width: $screen-sm-max) {
+ @media(max-width: map-get($grid-breakpoints, md)-1) {
display: block;
margin: 19px 0 12px;
}
@@ -166,7 +166,7 @@
padding: 0 0 0 14px;
border-left: 1px solid $border-color;
- @media(max-width: $screen-sm-max) {
+ @media(max-width: map-get($grid-breakpoints, md)-1) {
display: block;
width: 100%;
margin: 5px 0;
@@ -181,7 +181,7 @@
margin-top: 6px;
line-height: 21px;
- @media(max-width: $screen-sm-max) {
+ @media(max-width: map-get($grid-breakpoints, md)-1) {
display: block;
margin: 5px 0;
}
@@ -193,7 +193,7 @@
vertical-align: top;
margin: 5px 0 0 8px;
- @media(max-width: $screen-sm-max) {
+ @media(max-width: map-get($grid-breakpoints, md)-1) {
display: block;
width: 100%;
margin: 0 0 16px;
@@ -209,7 +209,7 @@
font-family: $regular_font;
margin-top: -5px;
- @media(max-width: $screen-sm-max) {
+ @media(max-width: map-get($grid-breakpoints, md)-1) {
display: block;
width: 100%;
margin: 5px 0;
@@ -223,7 +223,7 @@
width: 250px;
vertical-align: top;
- @media(max-width: $screen-sm-max) {
+ @media(max-width: map-get($grid-breakpoints, md)-1) {
display: block;
width: 100%;
margin: 5px 0;
@@ -237,7 +237,7 @@
display: inline-block;
margin: 7px 0 0 10px;
- @media(max-width: $screen-sm-max) {
+ @media(max-width: map-get($grid-breakpoints, md)-1) {
display: block;
width: 100%;
margin: 20px 0;
diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss
index 1f406cc1c2d..cd0d67613c3 100644
--- a/app/assets/stylesheets/pages/environments.scss
+++ b/app/assets/stylesheets/pages/environments.scss
@@ -1,4 +1,4 @@
-@media (max-width: $screen-md-max) {
+@include media-breakpoint-down(md) {
.deployments-container {
width: 100%;
overflow: auto;
@@ -138,7 +138,7 @@
border-left: 0;
border-right: 0;
- @media (min-width: $screen-sm-max) {
+ @media (min-width: map-get($grid-breakpoints, md)-1) {
border-top: 0;
}
}
@@ -251,7 +251,7 @@
font-size: 16px;
}
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
min-width: 100%;
}
}
@@ -432,7 +432,7 @@
}
}
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
.label-axis-text,
.text-metric-usage,
.legend-axis-text {
diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss
index d9267f5cdf3..f79586b68b9 100644
--- a/app/assets/stylesheets/pages/events.scss
+++ b/app/assets/stylesheets/pages/events.scss
@@ -70,7 +70,7 @@
.md {
font-size: $gl-font-size;
- .label {
+ .badge.badge-pill {
color: $gl-text-color;
}
@@ -173,7 +173,7 @@
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.event-item {
padding-left: 0;
diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss
index 409b7285f82..c2b42e02eee 100644
--- a/app/assets/stylesheets/pages/groups.scss
+++ b/app/assets/stylesheets/pages/groups.scss
@@ -2,7 +2,7 @@
@include str-truncated(90%);
}
-.dashboard .side .panel .panel-heading .input-group {
+.dashboard .side .card .card-header .input-group {
.form-control {
height: 42px;
@@ -40,7 +40,7 @@
flex: 1;
}
- .dropdown-menu-align-right {
+ .dropdown-menu-right {
margin-top: 0;
}
@@ -102,7 +102,7 @@
}
}
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
&,
.dropdown,
.dropdown .dropdown-toggle,
@@ -149,14 +149,14 @@
padding: 50px 100px;
overflow: hidden;
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
padding: 50px 0;
}
svg {
float: right;
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
float: none;
display: block;
width: 250px;
@@ -171,7 +171,7 @@
width: 460px;
margin-top: 120px;
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
float: none;
margin-top: 60px;
width: auto;
@@ -205,7 +205,7 @@
max-width: 480px;
padding: 0 $gl-padding;
- @media (max-width: $screen-sm-min) {
+ @include media-breakpoint-down(sm) {
margin: 0 auto;
}
}
diff --git a/app/assets/stylesheets/pages/help.scss b/app/assets/stylesheets/pages/help.scss
index 9cc9e11bcd1..0350fe5752e 100644
--- a/app/assets/stylesheets/pages/help.scss
+++ b/app/assets/stylesheets/pages/help.scss
@@ -28,8 +28,8 @@
}
.key {
- @extend .label;
- @extend .label-inverse;
+ @extend .badge.badge-pill;
+ background-color: $label-inverse-bg;
font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
padding: 3px 5px;
}
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index a8110f069d4..4aea9740735 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -373,7 +373,7 @@
/* Extra small devices (phones, less than 768px) */
display: none;
/* Small devices (tablets, 768px and up) */
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: block;
}
@@ -656,7 +656,7 @@
}
.issuable-form-padding-top {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
padding-top: 7px;
}
}
@@ -670,7 +670,7 @@
padding-left: 9px;
padding-right: 9px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: inline-block;
height: auto;
align-self: center;
@@ -678,7 +678,7 @@
}
.issuable-gutter-toggle {
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
margin-left: $btn-side-margin;
}
}
@@ -696,7 +696,7 @@
width: 100%;
}
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
margin-bottom: $gl-padding;
}
}
@@ -737,7 +737,7 @@
}
}
- @media(max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.issuable-meta {
.controls li {
margin-right: 0;
@@ -772,7 +772,7 @@
}
}
- @media(max-width: $screen-md-max) {
+ @media(max-width: map-get($grid-breakpoints, lg)-1) {
.task-status,
.issuable-due-date,
.project-ref-path {
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index 0d17b9bae7e..19fb99bfa93 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -141,7 +141,7 @@ ul.related-merge-requests > li {
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.detail-page-header {
.issuable-meta {
line-height: 18px;
@@ -203,7 +203,7 @@ ul.related-merge-requests > li {
}
}
- .btn-group:not(.hide) {
+ .btn-group:not(.hidden) {
display: flex;
}
@@ -245,7 +245,7 @@ ul.related-merge-requests > li {
display: block;
}
-@media (min-width: $screen-sm-min) {
+@include media-breakpoint-up(sm) {
.emoji-block .row {
display: flex;
@@ -256,8 +256,8 @@ ul.related-merge-requests > li {
}
.create-mr-dropdown-wrap {
- .btn-group:not(.hide) {
- display: inline-block;
+ .btn-group:not(.hidden) {
+ display: inline-flex;
}
}
}
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index d81236c5883..e178371d21f 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -62,13 +62,13 @@
display: inline-block;
margin-bottom: 10px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: 200px;
margin-left: $gl-padding * 2;
margin-bottom: 0;
}
- .label {
+ .badge {
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
@@ -80,7 +80,7 @@
margin-bottom: 10px;
margin-left: 50px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: inline-block;
width: 100px;
margin-left: 10px;
@@ -101,7 +101,7 @@
color: $blue-600;
}
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: inline-block;
max-width: 50%;
margin-left: 10px;
@@ -110,7 +110,7 @@
}
}
- .label {
+ .badge {
padding: 4px $grid-size;
font-size: $label-font-size;
position: relative;
@@ -122,6 +122,7 @@
padding: 0 $grid-size;
line-height: 16px;
border-radius: $label-border-radius;
+ color: $white-light;
}
.dropdown-labels-error {
@@ -132,7 +133,7 @@
}
.manage-labels-list {
- @media(min-width: $screen-md-min) {
+ @media(min-width: map-get($grid-breakpoints, md)) {
&.content-list li {
padding: $gl-padding 0;
}
@@ -171,12 +172,12 @@
}
.dropdown {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
float: right;
}
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.dropdown-menu {
min-width: 100%;
}
@@ -283,7 +284,7 @@
}
.label-subscribe-button {
- @media(min-width: $screen-md-min) {
+ @media(min-width: map-get($grid-breakpoints, md)) {
min-width: 105px;
margin-left: $gl-padding;
}
diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss
index 97303d02666..c1b1d2e028d 100644
--- a/app/assets/stylesheets/pages/login.scss
+++ b/app/assets/stylesheets/pages/login.scss
@@ -191,9 +191,9 @@
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.login-page {
- .col-sm-5.pull-right {
+ .col-md-5.float-right {
float: none !important;
margin-bottom: 45px;
}
@@ -243,7 +243,7 @@
.navless-container {
padding: 65px 15px; // height of footer + bottom padding of email confirmation link
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
padding: 0 15px 65px;
}
}
diff --git a/app/assets/stylesheets/pages/members.scss b/app/assets/stylesheets/pages/members.scss
index d5ae141dd7e..de2b5701e2d 100644
--- a/app/assets/stylesheets/pages/members.scss
+++ b/app/assets/stylesheets/pages/members.scss
@@ -9,9 +9,13 @@
}
}
+.member-sort-dropdown {
+ margin-left: $gl-padding-8;
+}
+
.member {
.list-item-name {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
float: left;
width: 50%;
}
@@ -22,12 +26,12 @@
}
.controls {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: -webkit-flex;
display: flex;
}
- .dropdown-menu.dropdown-menu-align-right {
+ .dropdown-menu.dropdown-menu-right {
margin-top: -2px;
}
}
@@ -35,7 +39,7 @@
.form-horizontal {
margin-top: 20px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: -webkit-flex;
display: flex;
margin-top: 3px;
@@ -45,20 +49,20 @@
.btn-remove {
width: 100%;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: auto;
}
}
&.existing-title {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
float: left;
}
}
}
.member-form-control {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
padding-bottom: 5px;
margin-left: 0;
margin-right: 0;
@@ -73,7 +77,7 @@
.member-search-form {
position: relative;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
float: right;
}
@@ -86,7 +90,7 @@
width: 100%;
}
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
margin-top: 0;
width: 155px;
}
@@ -96,7 +100,7 @@
width: 100%;
padding-right: 35px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: 250px;
}
}
@@ -114,7 +118,7 @@
border: 0;
outline: 0;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
right: 160px;
}
}
@@ -125,7 +129,7 @@
align-items: center;
justify-content: center;
- @media (max-width: $screen-sm-min) {
+ @include media-breakpoint-down(sm) {
display: block;
.flex-project-title {
@@ -141,7 +145,7 @@
text-overflow: ellipsis;
}
- .badge {
+ .badge.badge-pill {
height: 17px;
line-height: 16px;
margin-right: 5px;
@@ -156,14 +160,14 @@
}
}
-.panel {
- .panel-heading {
- .badge {
+.card {
+ .card-header {
+ .badge.badge-pill {
margin-top: 0;
}
- @media (max-width: $screen-sm-min) {
- .badge {
+ @include media-breakpoint-down(sm) {
+ .badge.badge-pill {
margin-right: 0;
margin-left: 0;
}
@@ -207,7 +211,7 @@
margin-right: 0;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
display: block;
.controls > .btn {
@@ -235,7 +239,7 @@
}
}
-.panel-mobile {
+.card-mobile {
.content-list.members-list li {
display: block;
diff --git a/app/assets/stylesheets/pages/merge_conflicts.scss b/app/assets/stylesheets/pages/merge_conflicts.scss
index 3d5ed9ef3c5..e76525fdbf6 100644
--- a/app/assets/stylesheets/pages/merge_conflicts.scss
+++ b/app/assets/stylesheets/pages/merge_conflicts.scss
@@ -291,7 +291,7 @@ $colors: (
}
.resolve-info {
- @media (max-width: $screen-md-max) {
+ @media(max-width: map-get($grid-breakpoints, lg)-1) {
margin-bottom: $gl-padding;
}
}
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 3581dd36a10..9eceb3e9a33 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -131,7 +131,7 @@
color: $gl-text-color;
display: flex;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
flex-wrap: wrap;
}
}
@@ -282,7 +282,7 @@
display: inline-block;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
p {
font-size: 13px;
}
@@ -494,18 +494,18 @@
}
}
-.panel-new-merge-request {
- .panel-heading {
+.card-new-merge-request {
+ .card-header {
padding: 5px 10px;
font-weight: $gl-font-weight-bold;
line-height: 25px;
}
- .panel-body {
+ .card-body {
padding: 10px 5px;
}
- .panel-footer {
+ .card-footer {
padding: 0;
.btn {
@@ -519,7 +519,7 @@
}
.item-title {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: 45%;
}
}
@@ -550,7 +550,7 @@
margin-bottom: 0;
}
- @media (min-width: $screen-xs-min) {
+ @include media-breakpoint-up(xs) {
float: left;
width: 50%;
margin-bottom: 0;
@@ -648,7 +648,7 @@
background-color: $white-light;
border-bottom: 1px solid $border-color;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
position: sticky;
position: -webkit-sticky;
}
@@ -657,7 +657,7 @@
left: 0;
transition: right .15s;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
right: 0;
}
@@ -700,7 +700,7 @@
display: flex;
justify-content: space-between;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
flex-direction: column-reverse;
}
}
@@ -736,7 +736,7 @@
display: flex;
flex-wrap: wrap;
- @media (min-width: $screen-xs) {
+ @include media-breakpoint-up(xs) {
flex-wrap: nowrap;
white-space: nowrap;
}
@@ -753,7 +753,7 @@
min-width: 100px;
max-width: 150px;
- @media (min-width: $screen-xs) {
+ @include media-breakpoint-up(xs) {
min-width: 0;
max-width: 100%;
}
diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss
index bac3b70c734..dba83e56d72 100644
--- a/app/assets/stylesheets/pages/milestone.scss
+++ b/app/assets/stylesheets/pages/milestone.scss
@@ -31,7 +31,7 @@
}
}
- .panel-heading {
+ .card-header {
line-height: $line-height-base;
padding: 14px 16px;
display: -webkit-flex;
@@ -145,7 +145,7 @@
padding: 20px 0;
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.milestone-actions {
@include clearfix();
padding-top: $gl-vert-padding;
@@ -181,7 +181,7 @@
width: 100%;
}
- @media (min-width: $screen-xs-min) {
+ @include media-breakpoint-up(xs) {
.milestone-buttons .verbose {
display: inline;
}
@@ -229,7 +229,7 @@
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.milestone-banner-text,
.milestone-banner-link {
display: inline;
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index 4a528bc2bb1..3b037d066dc 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -51,7 +51,7 @@
}
.note-image-attach {
- @extend .col-md-4;
+ @extend .col-lg-4;
margin-left: 45px;
float: none;
}
@@ -93,7 +93,7 @@
-webkit-flex-flow: row wrap;
width: 100%;
- .pull-right {
+ .float-right {
// Flexbox quirk to make sure right-aligned items stay right-aligned.
margin-left: auto;
}
@@ -185,12 +185,12 @@
}
.notes.notes-form > li.timeline-entry {
- @include notes-media('max', $screen-sm-max) {
+ @include notes-media('max', map-get($grid-breakpoints, md) - 1) {
padding: 0;
}
.timeline-content {
- @include notes-media('max', $screen-sm-max) {
+ @include notes-media('max', map-get($grid-breakpoints, md) - 1) {
margin: 0;
}
}
@@ -326,7 +326,7 @@
outline: 0;
}
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
float: left;
margin-right: $gl-padding;
@@ -350,13 +350,13 @@
line-height: 16px;
margin-top: 2px;
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
float: left;
}
}
.note-form-actions {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.btn {
float: none;
width: 100%;
@@ -375,7 +375,7 @@
left: 127px;
top: 2px;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
position: relative;
top: 0;
left: 0;
@@ -410,7 +410,7 @@
width: 298px;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
display: flex;
width: 100%;
margin-bottom: 10px;
@@ -432,7 +432,7 @@
.uploading-container {
float: right;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
float: left;
margin-top: 5px;
}
@@ -444,7 +444,7 @@
}
.uploading-error-message {
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
&::after {
content: "\a";
white-space: pre;
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index feee964f9bb..299eda53140 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -22,7 +22,7 @@ ul.notes {
.discussion-body {
padding-top: 8px;
- .panel {
+ .card {
margin-bottom: 0;
}
}
@@ -42,7 +42,7 @@ ul.notes {
position: relative;
border-bottom: 0;
- @include notes-media('min', $screen-sm-min) {
+ @include notes-media('min', map-get($grid-breakpoints, sm)) {
padding-left: $note-icon-gutter-width;
}
@@ -66,7 +66,7 @@ ul.notes {
}
.timeline-icon {
- @include notes-media('min', $screen-sm-min) {
+ @include notes-media('min', map-get($grid-breakpoints, sm)) {
margin-left: -$note-icon-gutter-width;
}
}
@@ -74,7 +74,7 @@ ul.notes {
.timeline-content {
margin-left: $note-icon-gutter-width;
- @include notes-media('min', $screen-sm-min) {
+ @include notes-media('min', map-get($grid-breakpoints, sm)) {
margin-left: 0;
}
}
@@ -154,7 +154,7 @@ ul.notes {
.note-header {
- @include notes-media('max', $screen-xs-min) {
+ @include notes-media('max', map-get($grid-breakpoints, xs)) {
.inline {
display: block;
}
@@ -217,7 +217,7 @@ ul.notes {
.timeline-icon {
float: left;
- @include notes-media('min', $screen-sm-min) {
+ @include notes-media('min', map-get($grid-breakpoints, sm)) {
margin-left: 0;
width: auto;
}
@@ -231,7 +231,7 @@ ul.notes {
}
.timeline-content {
- @include notes-media('min', $screen-sm-min) {
+ @include notes-media('min', map-get($grid-breakpoints, sm)) {
margin-left: 30px;
}
}
@@ -423,7 +423,7 @@ ul.notes {
}
.note-header-author-name {
- @include notes-media('max', $screen-xs-max) {
+ @include notes-media('max', map-get($grid-breakpoints, sm) - 1) {
display: none;
}
}
@@ -431,7 +431,7 @@ ul.notes {
.note-headline-light {
display: inline;
- @include notes-media('max', $screen-xs-min) {
+ @include notes-media('max', map-get($grid-breakpoints, xs)) {
display: block;
}
}
@@ -486,7 +486,7 @@ ul.notes {
margin-left: 10px;
color: $gray-darkest;
- @include notes-media('max', $screen-xs-max) {
+ @include notes-media('max', map-get($grid-breakpoints, sm) - 1) {
float: none;
margin-left: 0;
}
@@ -634,6 +634,10 @@ ul.notes {
margin-left: -55px;
position: absolute;
z-index: 10;
+
+ .new & {
+ margin-top: -10px;
+ }
}
.discussion-body,
@@ -668,7 +672,7 @@ ul.notes {
}
.line-resolve-all-container {
- @include notes-media('min', $screen-sm-min) {
+ @include notes-media('min', map-get($grid-breakpoints, sm)) {
margin-right: 0;
padding-left: $gl-padding;
}
diff --git a/app/assets/stylesheets/pages/notifications.scss b/app/assets/stylesheets/pages/notifications.scss
index bdf07a99daf..e98cb444f0a 100644
--- a/app/assets/stylesheets/pages/notifications.scss
+++ b/app/assets/stylesheets/pages/notifications.scss
@@ -2,7 +2,7 @@
line-height: 34px;
.dropdown-menu {
- @extend .dropdown-menu-align-right;
+ @extend .dropdown-menu-right;
}
}
diff --git a/app/assets/stylesheets/pages/pipeline_schedules.scss b/app/assets/stylesheets/pages/pipeline_schedules.scss
index bc7fa8a26d9..86e70955389 100644
--- a/app/assets/stylesheets/pages/pipeline_schedules.scss
+++ b/app/assets/stylesheets/pages/pipeline_schedules.scss
@@ -69,7 +69,7 @@
.cron-preset-radio-input {
display: inline-block;
- @media (max-width: $screen-md-max) {
+ @include media-breakpoint-down(md) {
display: block;
margin: 0 0 5px 5px;
}
diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss
index 1264d977b2f..f85f66b9c0b 100644
--- a/app/assets/stylesheets/pages/pipelines.scss
+++ b/app/assets/stylesheets/pages/pipelines.scss
@@ -1,3 +1,30 @@
+@mixin flat-connector-before($length: 44px) {
+ &::before {
+ content: '';
+ position: absolute;
+ top: 48%;
+ left: -$length;
+ border-top: 2px solid $border-color;
+ width: $length;
+ height: 1px;
+ }
+}
+
+@mixin build-content($border-radius: 30px) {
+ display: inline-block;
+ padding: 8px 10px 9px;
+ width: 100%;
+ border: 1px solid $border-color;
+ border-radius: $border-radius;
+ background-color: $white-light;
+
+ &:hover {
+ background-color: $stage-hover-bg;
+ border: 1px solid $dropdown-toggle-active-border-color;
+ color: $gl-text-color;
+ }
+}
+
.pipelines {
.stage {
max-width: 90px;
@@ -16,13 +43,13 @@
margin: 0;
white-space: normal;
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
justify-content: flex-end;
}
}
.ci-table {
- .label {
+ .badge {
margin-bottom: 3px;
}
@@ -82,7 +109,7 @@
}
}
-@media (max-width: $screen-md-max) {
+@include media-breakpoint-down(md) {
.content-list {
&.builds-content-list {
width: 100%;
@@ -150,14 +177,14 @@
color: $gl-link-color;
}
- .label {
+ .badge {
margin-right: 4px;
}
.label-container {
font-size: 0;
- .label {
+ .badge {
margin-top: 5px;
}
}
@@ -226,7 +253,7 @@
.stage-cell {
&.table-section {
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
min-width: 160px; /* Hack alert: Without this the mini graph pipeline won't work properly*/
margin-right: -4px;
}
@@ -357,14 +384,8 @@
&:not(:first-child) {
margin-left: 44px;
- .left-connector::before {
- content: '';
- position: absolute;
- top: 48%;
- left: -44px;
- border-top: 2px solid $border-color;
- width: 44px;
- height: 1px;
+ .left-connector {
+ @include flat-connector-before;
}
}
}
@@ -479,12 +500,7 @@
}
.build-content {
- display: inline-block;
- padding: 8px 10px 9px;
- width: 100%;
- border: 1px solid $border-color;
- border-radius: 30px;
- background-color: $white-light;
+ @include build-content();
}
a.build-content:hover,
@@ -622,8 +638,7 @@
}
}
-// Dropdown button in mini pipeline graph
-button.mini-pipeline-graph-dropdown-toggle {
+@mixin mini-pipeline-item() {
border-radius: 100px;
background-color: $white-light;
border-width: 1px;
@@ -636,30 +651,6 @@ button.mini-pipeline-graph-dropdown-toggle {
position: relative;
vertical-align: middle;
- > .fa.fa-caret-down {
- position: absolute;
- left: 20px;
- top: 5px;
- display: inline-block;
- visibility: hidden;
- opacity: 0;
- color: inherit;
- font-size: 12px;
- transition: visibility 0.1s, opacity 0.1s linear;
- }
-
- &:active,
- &:focus,
- &:hover {
- outline: none;
- width: 35px;
-
- .fa.fa-caret-down {
- visibility: visible;
- opacity: 1;
- }
- }
-
// Dropdown button animation in mini pipeline graph
&.ci-status-icon-success {
@include mini-pipeline-graph-color($green-100, $green-500, $green-600);
@@ -691,6 +682,35 @@ button.mini-pipeline-graph-dropdown-toggle {
}
}
+// Dropdown button in mini pipeline graph
+button.mini-pipeline-graph-dropdown-toggle {
+ @include mini-pipeline-item();
+
+ > .fa.fa-caret-down {
+ position: absolute;
+ left: 20px;
+ top: 5px;
+ display: inline-block;
+ visibility: hidden;
+ opacity: 0;
+ color: inherit;
+ font-size: 12px;
+ transition: visibility 0.1s, opacity 0.1s linear;
+ }
+
+ &:active,
+ &:focus,
+ &:hover {
+ outline: none;
+ width: 35px;
+
+ .fa.fa-caret-down {
+ visibility: visible;
+ opacity: 1;
+ }
+ }
+}
+
/**
Action icons inside dropdowns:
- mini graph in pipelines table
@@ -744,7 +764,7 @@ button.mini-pipeline-graph-dropdown-toggle {
}
}
- // SVGs in the commit widget and mr widget
+ // SVGs in the commit widget and mr widget
a.ci-action-icon-container.ci-action-icon-wrapper svg {
top: 2px;
}
@@ -800,7 +820,7 @@ button.mini-pipeline-graph-dropdown-toggle {
display: block;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
max-width: 60%;
}
}
@@ -887,7 +907,7 @@ button.mini-pipeline-graph-dropdown-toggle {
transform: translate(-50%, 0);
border-width: 0 5px 6px;
- @media (max-width: $screen-sm-max) {
+ @include media-breakpoint-down(sm) {
left: 100%;
margin-left: -12px;
}
@@ -909,7 +929,7 @@ button.mini-pipeline-graph-dropdown-toggle {
&.dropdown-menu {
transform: translate(-80%, 0);
- @media (min-width: $screen-md-min) {
+ @media(min-width: map-get($grid-breakpoints, md)) {
transform: translate(-50%, 0);
right: auto;
left: 50%;
diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss
index b199f9876d3..5d0d59e12f2 100644
--- a/app/assets/stylesheets/pages/profile.scss
+++ b/app/assets/stylesheets/pages/profile.scss
@@ -5,7 +5,7 @@
}
.avatar-image {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
float: left;
margin-bottom: 0;
}
@@ -119,7 +119,7 @@
.key-list-item {
.key-list-item-info {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
float: left;
}
}
@@ -188,7 +188,7 @@
.modal-dialog {
width: 380px;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
width: auto;
}
@@ -242,7 +242,7 @@
left: 0;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.cover-block {
padding-top: 20px;
}
@@ -352,7 +352,7 @@ table.u2f-registrations {
}
}
- @media(max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
text-align: center;
.bordered-box {
@@ -405,7 +405,7 @@ table.u2f-registrations {
margin-right: $gl-padding / 4;
}
- .label-verification-status {
+ .badge-verification-status {
border-width: 1px;
border-style: solid;
@@ -414,7 +414,7 @@ table.u2f-registrations {
}
&.unverified {
- @include status-color($gray-dark, $gray, $common-gray-dark);
+ @include status-color($gray-dark, color("gray"), $common-gray-dark);
}
}
}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 53d021086bf..22964163e95 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -9,7 +9,7 @@
.new_project,
.edit-project,
.import-project {
- .help-block {
+ .form-text.text-muted {
margin-bottom: 10px;
}
@@ -34,7 +34,7 @@
}
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.input-group > div {
&:last-child {
margin-bottom: 0;
@@ -46,7 +46,8 @@
}
}
- .input-group-addon {
+ .input-group-prepend,
+ .input-group-append {
overflow: hidden;
text-overflow: ellipsis;
line-height: unset;
@@ -82,7 +83,7 @@
border: 1px solid $border-color;
padding: 10px 32px;
- @media (max-width: $screen-xs-min) {
+ @include media-breakpoint-down(xs) {
padding: 10px 20px;
}
}
@@ -134,7 +135,7 @@
max-width: 400px;
}
- @media (max-width: $screen-xs-min) {
+ @include media-breakpoint-down(xs) {
padding-left: 20px;
}
}
@@ -144,7 +145,7 @@
padding-top: 24px;
padding-bottom: 24px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
border-bottom: 1px solid $border-color;
}
@@ -230,11 +231,11 @@
}
.notification-dropdown .dropdown-menu {
- @extend .dropdown-menu-align-right;
+ @extend .dropdown-menu-right;
}
.download-button {
- @media (max-width: $screen-md-max) {
+ @include media-breakpoint-down(md) {
margin-left: 0;
}
}
@@ -444,11 +445,11 @@
height: 200px;
width: calc((100% / 2) - #{$gl-padding * 2});
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
width: calc((100% / 4) - #{$gl-padding * 2});
}
- @media (min-width: $screen-lg-min) {
+ @include media-breakpoint-up(lg) {
width: calc((100% / 5) - #{$gl-padding * 2});
}
@@ -537,11 +538,12 @@
.template-input-group {
position: relative;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: flex;
}
- .input-group-addon {
+ .input-group-prepend,
+ .input-group-append {
flex: 1;
text-align: left;
padding-left: ($gl-padding * 3);
@@ -601,12 +603,12 @@
margin: 0 auto 4px;
font-size: 24px;
- @media (min-width: $screen-xs-max) {
+ @media (min-width: map-get($grid-breakpoints, sm)-1) {
top: 0;
}
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.btn-template-icon {
display: inline-block;
height: 14px;
@@ -625,31 +627,31 @@
.create-project-options {
display: flex;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
display: block;
}
.first-column {
- @media (min-width: $screen-xs-min) {
+ @include media-breakpoint-up(xs) {
max-width: 50%;
padding-right: 30px;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
max-width: 100%;
width: 100%;
}
}
.second-column {
- @media (min-width: $screen-xs-min) {
+ @include media-breakpoint-up(xs) {
width: 50%;
flex: 1;
padding-left: 30px;
position: relative;
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
max-width: 100%;
width: 100%;
padding-left: 0;
@@ -657,7 +659,7 @@
}
// Mobile
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
padding-top: 30px;
}
@@ -677,7 +679,7 @@
line-height: 20px;
// Mobile
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
left: 50%;
top: 0;
transform: translateX(-50%);
@@ -697,7 +699,7 @@
top: 0;
// Mobile
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
top: 10px;
left: 10px;
right: 10px;
@@ -735,7 +737,7 @@
vertical-align: top;
margin-top: 0;
- @media (min-width: $screen-lg-min) {
+ @include media-breakpoint-up(lg) {
float: right;
}
}
@@ -866,13 +868,14 @@ pre.light-well {
}
}
-.panel .projects-list li {
+.card .projects-list li {
padding: 10px 15px;
margin: 0;
}
.git-clone-holder {
width: 380px;
+ height: 28px;
.btn-clipboard {
border: 1px solid $border-color;
@@ -888,11 +891,11 @@ pre.light-well {
.form-control {
@extend .monospace;
- background: $white-light;
+ background-color: $white-light;
+ border-color: $border-color;
font-size: 14px;
margin-left: -1px;
cursor: auto;
- width: 101%;
}
}
@@ -921,7 +924,8 @@ pre.light-well {
}
.project-tip-command {
- > .input-group-btn:first-child {
+ > .input-group-prepend:first-child,
+ > .input-group-append:first-child {
width: auto;
}
}
@@ -972,7 +976,7 @@ pre.light-well {
.dropdown-menu-projects {
width: 300px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: 500px;
}
@@ -986,7 +990,7 @@ pre.light-well {
.inline-input-group {
width: 100%;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: 300px;
}
}
@@ -997,8 +1001,8 @@ pre.light-well {
text-align: center;
margin-top: -20px;
- @media (min-width: $screen-sm-min) {
- margin-top: 0;
+ @include media-breakpoint-up(sm) {
+ margin: 0 $gl-padding-8;
width: auto;
}
}
@@ -1036,7 +1040,7 @@ pre.light-well {
}
&.form-group {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
margin-bottom: 0;
}
}
@@ -1064,12 +1068,12 @@ pre.light-well {
.project-feature {
padding-top: 10px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
padding-left: 45px;
}
&.nested {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
padding-left: 90px;
}
}
diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss
index 175d2779bb7..d5c6048037a 100644
--- a/app/assets/stylesheets/pages/repo.scss
+++ b/app/assets/stylesheets/pages/repo.scss
@@ -22,7 +22,6 @@
height: calc(100vh - #{$header-height});
margin-top: 0;
border-top: 1px solid $white-dark;
- border-bottom: 1px solid $white-dark;
padding-bottom: $ide-statusbar-height;
&.is-collapsed {
@@ -380,7 +379,7 @@
.ide-status-bar {
border-top: 1px solid $white-dark;
- padding: $gl-bar-padding $gl-padding;
+ padding: 2px $gl-padding-8 0;
background: $white-light;
display: flex;
justify-content: space-between;
@@ -391,12 +390,19 @@
left: 0;
width: 100%;
+ font-size: 12px;
+ line-height: 22px;
+
+ * {
+ font-size: inherit;
+ }
+
> div + div {
padding-left: $gl-padding;
}
svg {
- vertical-align: middle;
+ vertical-align: sub;
}
}
@@ -540,7 +546,7 @@
margin-right: 0;
}
- &.help-block {
+ &.form-text.text-muted {
margin-left: 0;
right: 0;
}
@@ -848,7 +854,7 @@
}
}
- .help-block {
+ .form-text.text-muted {
margin-top: 0;
line-height: 0;
}
@@ -946,7 +952,7 @@
height: 30px;
}
- .help-block {
+ .form-text.text-muted {
margin-top: 2px;
color: $blue-500;
cursor: pointer;
@@ -1082,10 +1088,6 @@
font-size: 12px;
}
-.ide-new-modal-label {
- line-height: 34px;
-}
-
.multi-file-commit-panel-success-message {
position: absolute;
top: 61px;
diff --git a/app/assets/stylesheets/pages/runners.scss b/app/assets/stylesheets/pages/runners.scss
index 5fb97b13470..2734faec558 100644
--- a/app/assets/stylesheets/pages/runners.scss
+++ b/app/assets/stylesheets/pages/runners.scss
@@ -51,7 +51,7 @@
}
}
-@media (max-width: $screen-md-max) {
+@include media-breakpoint-down(md) {
.runners-content {
width: 100%;
overflow: auto;
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index dbde0720993..a35c4ff7c80 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -47,6 +47,7 @@ input[type="checkbox"]:hover {
}
.location-badge {
+ white-space: nowrap;
height: 32px;
font-size: 12px;
margin: -4px 4px -4px -4px;
@@ -166,7 +167,7 @@ input[type="checkbox"]:hover {
}
.search-holder {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: -webkit-flex;
display: flex;
}
@@ -178,7 +179,7 @@ input[type="checkbox"]:hover {
position: relative;
margin-right: 0;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
margin-right: 5px;
}
}
@@ -202,7 +203,7 @@ input[type="checkbox"]:hover {
width: 100%;
margin-top: 5px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: auto;
margin-top: 0;
margin-left: 5px;
@@ -210,7 +211,7 @@ input[type="checkbox"]:hover {
}
.dropdown {
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
margin-left: 5px;
margin-right: 5px;
}
@@ -220,7 +221,7 @@ input[type="checkbox"]:hover {
width: 100%;
margin-top: 5px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: 180px;
margin-top: 0;
}
diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss
index c410049bc0b..2b3773eebad 100644
--- a/app/assets/stylesheets/pages/settings.scss
+++ b/app/assets/stylesheets/pages/settings.scss
@@ -70,7 +70,7 @@
animation: none;
}
- @media(max-width: $screen-sm-max) {
+ @media(max-width: map-get($grid-breakpoints, md)-1) {
padding-right: 20px;
}
@@ -98,8 +98,8 @@
}
.bs-callout,
- .checkbox:first-child,
- .help-block {
+ .form-check:first-child,
+ .form-text.text-muted {
margin-top: 0;
}
@@ -131,12 +131,12 @@
color: $gl-danger;
}
-.service-settings .control-label {
+.service-settings .form-control-label {
padding-top: 0;
}
.integration-settings-form {
- .well {
+ .card.card-body {
padding: $gl-padding / 2;
box-shadow: none;
}
@@ -158,7 +158,7 @@
}
.visibility-level-setting {
- .radio {
+ .form-check {
margin-bottom: 10px;
i.fa {
@@ -174,7 +174,7 @@
.option-description,
.option-disabled-reason {
- margin-left: 29px;
+ margin-left: 45px;
color: $project-option-descr-color;
}
@@ -199,22 +199,22 @@
}
.prometheus-metrics-monitoring {
- .panel {
- .panel-toggle {
+ .card {
+ .card-toggle {
width: 14px;
}
- .badge {
+ .badge.badge-pill {
font-size: 12px;
line-height: 12px;
}
- .panel-heading .badge-count {
+ .card-header .label-count {
color: $white-light;
background: $common-gray-dark;
}
- .panel-body {
+ .card-body {
padding: 0;
}
@@ -249,7 +249,7 @@
li {
padding: $gl-padding;
- .badge {
+ .badge.badge-pill {
margin-left: 5px;
background: $badge-bg;
}
diff --git a/app/assets/stylesheets/pages/stat_graph.scss b/app/assets/stylesheets/pages/stat_graph.scss
index 8e2c42c1bd3..3f6f5f06075 100644
--- a/app/assets/stylesheets/pages/stat_graph.scss
+++ b/app/assets/stylesheets/pages/stat_graph.scss
@@ -14,7 +14,10 @@
}
#contributors-master {
- @include make-md-column(12);
+ @include media-breakpoint-up(md) {
+ @include make-col-ready();
+ @include make-col(12);
+ }
svg {
width: 100%;
@@ -33,10 +36,14 @@
}
.person {
- @include make-md-column(6);
+ @include media-breakpoint-up(md) {
+ @include make-col-ready();
+ @include make-col(6);
+ }
+
margin-top: 10px;
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
width: 100%;
}
diff --git a/app/assets/stylesheets/pages/status.scss b/app/assets/stylesheets/pages/status.scss
index ade5ddd147b..620297e589d 100644
--- a/app/assets/stylesheets/pages/status.scss
+++ b/app/assets/stylesheets/pages/status.scss
@@ -58,7 +58,7 @@
}
}
-.visible-xs-inline {
+.d-block.d-sm-none-inline {
.ci-status-link {
position: relative;
top: 2px;
diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss
index 4b9824fab0c..e5d7dd13915 100644
--- a/app/assets/stylesheets/pages/todos.scss
+++ b/app/assets/stylesheets/pages/todos.scss
@@ -126,7 +126,7 @@
color: $gl-grayish-blue;
font-size: $gl-font-size;
- .label {
+ .badge.badge-pill {
color: $gl-text-color;
}
@@ -162,7 +162,7 @@
}
}
-@media (max-width: $screen-sm-max) {
+@include media-breakpoint-down(sm) {
.todos-filters {
.dropdown-menu-toggle {
width: 130px;
@@ -174,7 +174,7 @@
}
}
-@media (max-width: $screen-xs-max) {
+@include media-breakpoint-down(xs) {
.todo {
.avatar {
display: none;
@@ -214,7 +214,7 @@
margin-left: auto;
margin-right: auto;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
-webkit-flex-direction: row;
flex-direction: row;
padding-top: 80px;
@@ -233,7 +233,7 @@
margin-left: auto;
margin-right: auto;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
width: 300px;
margin-right: 0;
-webkit-order: 2;
@@ -244,7 +244,7 @@
.todos-all-done {
padding-top: 20px;
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
padding-top: 50px;
}
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index e0ee7e9aa3d..efd26cb1f81 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -7,7 +7,7 @@
color: $gl-text-color-secondary;
}
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
display: flex;
.tree-ref-container {
@@ -41,15 +41,10 @@
position: relative;
}
}
-
- .add-to-tree-dropdown {
- position: absolute;
- left: 18px;
- }
}
}
- @media (max-width: $screen-xs-max) {
+ @include media-breakpoint-down(xs) {
.repo-breadcrumb {
margin-top: 10px;
position: relative;
@@ -121,7 +116,7 @@
margin-left: 5px;
}
- @media (min-width: $screen-md-min) and (max-width: $screen-md-max) {
+ @include media-breakpoint-only(md) {
@include str-truncated(450px);
}
diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss
index e70a57c2a67..800f5c68e39 100644
--- a/app/assets/stylesheets/pages/wiki.scss
+++ b/app/assets/stylesheets/pages/wiki.scss
@@ -65,7 +65,7 @@
display: block;
}
- @media (min-width: $screen-sm-min) {
+ @include media-breakpoint-up(sm) {
&.has-sidebar-toggle {
padding-right: 40px;
}
@@ -81,7 +81,7 @@
}
}
- @media (min-width: $screen-md-min) {
+ @include media-breakpoint-up(md) {
&.has-sidebar-toggle {
padding-right: 0;
}