diff options
author | Mike Greiling <mike@pixelcog.com> | 2017-11-03 14:02:52 -0500 |
---|---|---|
committer | Mike Greiling <mike@pixelcog.com> | 2017-11-03 14:02:52 -0500 |
commit | 72157766a2c5b65bece2077c8b3eddcb8af5b374 (patch) | |
tree | 5b9c3d0d9d1392d4859c22b2584a03332b3b48c3 | |
parent | 817c7fb1b0cbd0d008706e060c4cecd0401b5f0c (diff) | |
parent | 4841c3cb4565996b1a54ef045f9f84548dcc5d6a (diff) | |
download | gitlab-ce-72157766a2c5b65bece2077c8b3eddcb8af5b374.tar.gz |
Merge branch 'master' into sh-headless-chrome-support
* master: (33 commits)
Ignore SQL CACHE hits in Sherlock
Fix SQL timings for the performance bar
Find the LFS-objects for a fork within a the fork network
Remove bottom-border from last responsive table row
Add system hooks user_rename and group_rename
Unlink a project from a fork network when it's source was deleted.
Make sure the settings page renders when root of a fork is deleted
Remove Peek's original keyboard shortcut (numpad 0, keycode 96)
Add application setting to Auto DevOps docs
Enable MergeableSelector in scss-lint (for !14567)
Enable MergeableSelector in scss-lint (for !14055)
Enable MergeableSelector in scss-lint (for !14062)
Enable MergeableSelector in scss-lint (for !14398)
Enable MergeableSelector in scss-lint (for !13480)
Enable MergeableSelector in scss-lint (for !13473)
Enable MergeableSelector in scss-lint (for !13600)
Enable MergeableSelector in scss-lint
Resolve ""To do" should be "Todos" on Todos list page"
Avoid regenerating the ref path for the environment
Remove white space at bottom of issue boards
...
102 files changed, 1294 insertions, 834 deletions
diff --git a/.scss-lint.yml b/.scss-lint.yml index d2c972fa9c4..16a168b7c60 100644 --- a/.scss-lint.yml +++ b/.scss-lint.yml @@ -112,7 +112,7 @@ linters: # Reports when you define the same selector twice in a single sheet. MergeableSelector: - enabled: false + enabled: true # Functions, mixins, variables, and placeholders should be declared # with all lowercase letters and hyphens instead of underscores. diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bca9944bb1..8ede091ec08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,30 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 10.1.1 (2017-10-31) + +- [FIXED] Auto Devops kubernetes default namespace is now correctly built out of gitlab project group-name. !14642 (Mircea Danila Dumitrescu) +- [FIXED] Forbid the usage of `Redis#keys`. !14889 +- [FIXED] Make the circuitbreaker more robust by adding higher thresholds, and multiple access attempts. !14933 +- [FIXED] Only cache last push event for existing projects when pushing to a fork. !14989 +- [FIXED] Fix bug preventing secondary emails from being confirmed. !15010 +- [FIXED] Fix broken wiki pages that link to a wiki file. !15019 +- [FIXED] Don't rename paths that were freed up when upgrading. !15029 +- [FIXED] Fix bitbucket login. !15051 +- [FIXED] Update gitaly in Gitlab 10.1 to 0.43.1 for temp file cleanup. !15055 +- [FIXED] Use the correct visibility attribute for projects in system hooks. !15065 +- [FIXED] Normalize LDAP DN when looking up identity. +- [FIXED] Adds callback functions for initial request in clusters page. +- [FIXED] Fix missing Import/Export issue assignees. +- [FIXED] Allow boards as top level route. +- [FIXED] Fix widget of locked merge requests not being presented. +- [FIXED] Fix editing issue description in mobile view. +- [FIXED] Fix deletion of container registry or images returning an error. +- [FIXED] Fix the writing of invalid environment refs. +- [CHANGED] Store circuitbreaker settings in the database instead of config. !14842 +- [CHANGED] Update default disabled merge request widget message to reflect a general failure. !14960 +- [PERFORMANCE] Stop merge requests with thousands of commits from timing out. !15063 + ## 10.1.0 (2017-10-22) - [SECURITY] Use a timeout on certain git operations. !14872 diff --git a/app/assets/javascripts/clusters.js b/app/assets/javascripts/clusters.js index 661870c226c..c9fef94efea 100644 --- a/app/assets/javascripts/clusters.js +++ b/app/assets/javascripts/clusters.js @@ -1,6 +1,7 @@ /* globals Flash */ import Visibility from 'visibilityjs'; import axios from 'axios'; +import setAxiosCsrfToken from './lib/utils/axios_utils'; import Poll from './lib/utils/poll'; import { s__ } from './locale'; import initSettingsPanels from './settings_panels'; @@ -17,6 +18,7 @@ import Flash from './flash'; class ClusterService { constructor(options = {}) { this.options = options; + setAxiosCsrfToken(); } fetchData() { return axios.get(this.options.endpoint); diff --git a/app/assets/javascripts/lib/utils/axios_utils.js b/app/assets/javascripts/lib/utils/axios_utils.js new file mode 100644 index 00000000000..45bff245827 --- /dev/null +++ b/app/assets/javascripts/lib/utils/axios_utils.js @@ -0,0 +1,6 @@ +import axios from 'axios'; +import csrf from './csrf'; + +export default function setAxiosCsrfToken() { + axios.defaults.headers.common[csrf.headerKey] = csrf.token; +} diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index 8819a0c20f4..def986180fc 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -40,6 +40,10 @@ &.top-block { border-top: none; + + .container-fluid { + background-color: inherit; + } } &.middle-block { @@ -98,10 +102,6 @@ background-color: $white-light; border-top: none; } - - &.top-block .container-fluid { - background-color: inherit; - } } .sub-header-block { diff --git a/app/assets/stylesheets/framework/callout.scss b/app/assets/stylesheets/framework/callout.scss index e0e46dd73af..1bd94c0acba 100644 --- a/app/assets/stylesheets/framework/callout.scss +++ b/app/assets/stylesheets/framework/callout.scss @@ -12,15 +12,15 @@ border-left: 3px solid $border-color; color: $text-color; background: $gray-light; -} -.bs-callout h4 { - margin-top: 0; - margin-bottom: 5px; -} + h4 { + margin-top: 0; + margin-bottom: 5px; + } -.bs-callout p:last-child { - margin-bottom: 0; + p:last-child { + margin-bottom: 0; + } } /* Variations */ diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index ed84b17af6a..ea3007f5e08 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -53,6 +53,14 @@ hr { .str-truncated { @include str-truncated; + + &-60 { + @include str-truncated(60%); + } + + &-100 { + @include str-truncated(100%); + } } .block-truncated { @@ -78,10 +86,17 @@ hr { font-size: 14px; } -table a code { - position: relative; - top: -2px; - margin-right: 3px; +table { + a code { + position: relative; + top: -2px; + margin-right: 3px; + } + + td.permission-x { + background: $table-permission-x-bg !important; + text-align: center; + } } .loading { @@ -266,13 +281,6 @@ img.emoji { margin-bottom: 10px; } -table { - td.permission-x { - background: $table-permission-x-bg !important; - text-align: center; - } -} - .btn-sign-in { text-shadow: none; @@ -338,10 +346,11 @@ table { .dropzone .dz-preview .dz-progress { border-color: $border-color !important; -} -.dropzone .dz-preview .dz-progress .dz-upload { - background: $gl-success !important; + .dz-upload { + background: $gl-success !important; + } + } .dz-message { @@ -402,16 +411,6 @@ table { border-radius: $border-radius-default; } -.str-truncated { - &-60 { - @include str-truncated(60%); - } - - &-100 { - @include str-truncated(100%); - } -} - .tooltip { .tooltip-inner { word-wrap: break-word; diff --git a/app/assets/stylesheets/framework/contextual-sidebar.scss b/app/assets/stylesheets/framework/contextual-sidebar.scss index 2905cfe643f..320f458630a 100644 --- a/app/assets/stylesheets/framework/contextual-sidebar.scss +++ b/app/assets/stylesheets/framework/contextual-sidebar.scss @@ -141,15 +141,15 @@ svg { fill: $gl-text-color-secondary; } - } - .nav-item-name { - flex: 1; - } + .nav-item-name { + flex: 1; + } - li.active { - > a { - font-weight: $gl-font-weight-bold; + &.active { + > a { + font-weight: $gl-font-weight-bold; + } } } diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 1aa53b8f8cf..08c603edd23 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -727,11 +727,11 @@ .pika-single.animate-picker.is-bound { @include set-visible; -} -.pika-single.animate-picker.is-bound.is-hidden { - @include set-invisible; - overflow: hidden; + &.is-hidden { + @include set-invisible; + overflow: hidden; + } } @mixin dropdown-item-hover { @@ -938,9 +938,7 @@ header.header-content .dropdown-menu.projects-dropdown-menu { border-right: 0; } } -} -.projects-dropdown-container { .projects-list-frequent-container, .projects-list-search-container, { padding: 8px 0; @@ -951,11 +949,6 @@ header.header-content .dropdown-menu.projects-dropdown-menu { .projects-list-frequent-container li.section-empty, .projects-list-search-container li.section-empty { padding: 0 15px; - } - - .section-header, - .projects-list-frequent-container li.section-empty, - .projects-list-search-container li.section-empty { color: $gl-text-color-secondary; font-size: $gl-font-size; } diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss index 5833ef939e9..6382551fcc9 100644 --- a/app/assets/stylesheets/framework/files.scss +++ b/app/assets/stylesheets/framework/files.scss @@ -165,22 +165,36 @@ &:last-child { border-right: none; } - } - td.blame-commit { - padding: 5px 10px; - min-width: 400px; - max-width: 400px; - background: $gray-light; - border-left: 3px solid; + &.blame-commit { + padding: 5px 10px; + min-width: 400px; + max-width: 400px; + background: $gray-light; + border-left: 3px solid; + + .commit-row-title { + display: flex; + } + + .item-title { + flex: 1; + margin-right: 0.5em; + } + } + + &.line-numbers { + float: none; + border-left: 1px solid $blame-line-numbers-border; - .commit-row-title { - display: flex; + i { + float: none; + margin-right: 0; + } } - .item-title { - flex: 1; - margin-right: 0.5em; + &.lines { + padding: 0; } } @@ -195,20 +209,6 @@ border-left-color: mix($blame-gray, $blame-cyan, $i / 4.0 * 100%); } } - - td.line-numbers { - float: none; - border-left: 1px solid $blame-line-numbers-border; - - i { - float: none; - margin-right: 0; - } - } - - td.lines { - padding: 0; - } } &.logs { diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index e5e85daf1e8..a7333925f80 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -463,10 +463,10 @@ word-break: break-all; } } -} -.filter-dropdown-item.droplab-item-active .btn { - @extend %filter-dropdown-item-btn-hover; + &.droplab-item-active .btn { + @extend %filter-dropdown-item-btn-hover; + } } .filter-dropdown-loading { diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 62ba74ff582..5d777f0d468 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -352,7 +352,77 @@ .header-user .dropdown-menu-nav, .header-new .dropdown-menu-nav { - margin-top: $dropdown-vertical-offset; + margin-top: 4px; +} + +.search { + margin: 4px 8px 0; + + form { + height: 32px; + border: 0; + border-radius: $border-radius-default; + transition: border-color ease-in-out 0.15s, background-color ease-in-out 0.15s; + + &:hover { + box-shadow: none; + } + } + + .search-input { + color: $white-light; + background: none; + transition: color ease-in-out 0.15s; + } + + .search-input::placeholder { + transition: color ease-in-out 0.15s; + } + + .location-badge { + font-size: 12px; + margin: -4px 4px -4px -4px; + line-height: 25px; + padding: 4px 8px; + border-radius: 2px 0 0 2px; + height: 32px; + transition: border-color ease-in-out 0.15s; + } + + &.search-active { + form { + background-color: rgba($indigo-200, .3); + box-shadow: none; + + .search-input { + color: $gl-text-color; + transition: color ease-in-out 0.15s; + } + + .search-input::placeholder { + color: $gl-text-color-tertiary; + } + + .search-input-wrap { + .search-icon, + .clear-icon { + color: $gl-text-color-tertiary; + transition: color ease-in-out 0.15s; + } + } + } + + .location-badge { + background-color: $nav-badge-bg; + border-color: $border-color; + } + + .search-input-wrap { + .clear-icon { + color: $white-light; + } + } + } } .breadcrumbs { diff --git a/app/assets/stylesheets/framework/layout.scss b/app/assets/stylesheets/framework/layout.scss index 69d19ea2962..cb324ccc440 100644 --- a/app/assets/stylesheets/framework/layout.scss +++ b/app/assets/stylesheets/framework/layout.scss @@ -30,10 +30,10 @@ body { .container { padding-top: 0; z-index: 5; -} -.container .content { - margin: 0; + .content { + margin: 0; + } } .navless-container { @@ -82,26 +82,26 @@ body { transition: background-color 0.15s, border-color 0.15s; background-color: $orange-500; border-color: $orange-500; - } - .alert-warning + .alert-warning { - background-color: $orange-600; - border-color: $orange-600; - } + &:only-of-type { + background-color: $orange-500; + border-color: $orange-500; + } - .alert-warning + .alert-warning + .alert-warning { - background-color: $orange-700; - border-color: $orange-700; - } + + .alert-warning { + background-color: $orange-600; + border-color: $orange-600; - .alert-warning + .alert-warning + .alert-warning + .alert-warning { - background-color: $orange-800; - border-color: $orange-800; - } + + .alert-warning { + background-color: $orange-700; + border-color: $orange-700; - .alert-warning:only-of-type { - background-color: $orange-500; - border-color: $orange-500; + + .alert-warning { + background-color: $orange-800; + border-color: $orange-800; + } + } + } } } diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index d43f998cb82..511608c618c 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -299,40 +299,40 @@ ul.indent-list { } } -.group-list-tree .avatar-container.content-loading { - position: relative; +.group-list-tree { + .avatar-container.content-loading { + position: relative; - > a, - > a .avatar { - height: 100%; - border-radius: 50%; - } + > a, + > a .avatar { + height: 100%; + border-radius: 50%; + } - > a { - padding: 2px; - } + > a { + padding: 2px; - > a .avatar { - border: 2px solid $white-normal; + .avatar { + border: 2px solid $white-normal; - &.identicon { - line-height: 30px; + &.identicon { + line-height: 30px; + } + } } - } - &::after { - content: ""; - position: absolute; - height: 100%; - width: 100%; - background-color: transparent; - border: 2px outset $kdb-border; - border-radius: 50%; - animation: spin-avatar 3s infinite linear; + &::after { + content: ""; + position: absolute; + height: 100%; + width: 100%; + background-color: transparent; + border: 2px outset $kdb-border; + border-radius: 50%; + animation: spin-avatar 3s infinite linear; + } } -} -.group-list-tree { .folder-toggle-wrap { float: left; line-height: $list-text-height; diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss index e3920b5d3d9..0a5a16c09b0 100644 --- a/app/assets/stylesheets/framework/markdown_area.scss +++ b/app/assets/stylesheets/framework/markdown_area.scss @@ -173,21 +173,8 @@ ul > li { white-space: nowrap; } -} - -@media(max-width: $screen-xs-max) { - .atwho-view-ul { - width: 350px; - } - - .atwho-view ul li { - overflow: hidden; - text-overflow: ellipsis; - } -} -// TODO: fallback to global style -.atwho-view { + // TODO: fallback to global style .atwho-view-ul { padding: 8px 1px; @@ -220,3 +207,14 @@ } } } + +@media(max-width: $screen-xs-max) { + .atwho-view-ul { + width: 350px; + } + + .atwho-view ul li { + overflow: hidden; + text-overflow: ellipsis; + } +} diff --git a/app/assets/stylesheets/framework/responsive_tables.scss b/app/assets/stylesheets/framework/responsive_tables.scss index 7adb2f113bb..8b7afdbe1a5 100644 --- a/app/assets/stylesheets/framework/responsive_tables.scss +++ b/app/assets/stylesheets/framework/responsive_tables.scss @@ -25,7 +25,10 @@ margin: 0; padding: $gl-padding 0; border: none; - border-bottom: 1px solid $white-normal; + + &:not(:last-child) { + border-bottom: 1px solid $white-normal; + } } } diff --git a/app/assets/stylesheets/framework/secondary-navigation-elements.scss b/app/assets/stylesheets/framework/secondary-navigation-elements.scss index 3fd2549b143..9e1f77e5726 100644 --- a/app/assets/stylesheets/framework/secondary-navigation-elements.scss +++ b/app/assets/stylesheets/framework/secondary-navigation-elements.scss @@ -340,11 +340,64 @@ } } -.project-item-select-holder.btn-group { - display: flex; - max-width: 350px; - overflow: hidden; - float: right; +.page-with-layout-nav { + .right-sidebar { + top: ($header-height + 1) * 2; + } + + &.page-with-sub-nav { + .right-sidebar { + top: ($header-height + 1) * 3; + + &.affix { + top: $header-height; + } + } + } +} + +.with-performance-bar .page-with-layout-nav { + .right-sidebar { + top: ($header-height + 1) * 2 + $performance-bar-height; + } + + &.page-with-sub-nav { + .right-sidebar { + top: ($header-height + 1) * 3 + $performance-bar-height; + + &.affix { + top: $header-height + $performance-bar-height; + } + } + } +} + +@media (max-width: $screen-xs-max) { + .top-area { + flex-flow: row wrap; + + .nav-controls { + $controls-margin: $btn-xs-side-margin - 2px; + flex: 0 0 100%; + + &.controls-flex { + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: center; + padding: 0 0 $gl-padding-top; + } + + .controls-item, + .controls-item-full, + .controls-item:last-child { + flex: 1 1 35%; + display: block; + width: 100%; + margin: $controls-margin; + } + } + } .new-project-item-link { white-space: nowrap; diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss index 621eec4f158..aa35cd9bea4 100644 --- a/app/assets/stylesheets/framework/selects.scss +++ b/app/assets/stylesheets/framework/selects.scss @@ -60,22 +60,12 @@ border-radius: $border-radius-base; border: 1px solid $dropdown-border-color; min-width: 175px; - color: $gl-text-color; - z-index: 999; + color: $gl-grayish-blue; } -.select2-drop-mask { - z-index: 998; -} - -.select2-drop.select2-drop-above.select2-drop-active { - border-top: 1px solid $dropdown-border-color; - margin-top: -6px; -} - -.select2-results li.select2-result-with-children > .select2-result-label { - font-weight: $gl-font-weight-bold; - color: $gl-text-color; +.select2-results .select2-result-label, +.select2-more-results { + padding: 10px 15px; } .select2-container-active { @@ -144,58 +134,46 @@ .select2-drop-auto-width & { padding: 15px 15px 5px; } -} -.select2-search input { - padding: 2px 25px 2px 5px; - background: $white-light image-url('select2.png'); - background-repeat: no-repeat; - background-position: right 0 bottom 6px; - border: 1px solid $input-border; - border-radius: $border-radius-default; - transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; - - &:focus { - border-color: $input-border-focus; + input { + padding: 2px 25px 2px 5px; + background: $white-light image-url('select2.png'); + background-repeat: no-repeat; + background-position: right 0 bottom 6px; + border: 1px solid $input-border; + border-radius: $border-radius-default; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + + &:focus { + border-color: $input-border-focus; + } + + &.select2-active { + background-color: $white-light; + background-image: image-url('select2-spinner.gif') !important; + background-repeat: no-repeat; + background-position: right 5px center !important; + background-size: 16px 16px !important; + } } } -.select2-search input.select2-active { - background-color: $white-light; - background-image: image-url('select2-spinner.gif') !important; - background-repeat: no-repeat; - background-position: right 5px center !important; - background-size: 16px 16px !important; +.select2-results .select2-no-results, +.select2-results .select2-searching, +.select2-results .select2-ajax-error, +.select2-results .select2-selection-limit { + background: $gray-light; + display: list-item; + padding: 10px 15px; } .select2-results { margin: 0; - padding: #{$gl-padding / 2} 0; - - .select2-no-results, - .select2-searching, - .select2-ajax-error, - .select2-selection-limit { - background: transparent; - padding: #{$gl-padding / 2} $gl-padding; - } - - .select2-result-label, - .select2-more-results { - padding: #{$gl-padding / 2} $gl-padding; - } + padding: 10px 0; - .select2-highlighted { - background: transparent; + li.select2-result-with-children > .select2-result-label { + font-weight: $gl-font-weight-bold; color: $gl-text-color; - - .select2-result-label { - background: $dropdown-item-hover-bg; - } - } - - .select2-result { - padding: 0 1px; } } @@ -212,6 +190,8 @@ } .select2-highlighted { + background: $gl-link-color !important; + .group-result { .group-path { color: $white-light; diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss index 65b140cd7f8..c3d8f0c61a2 100644 --- a/app/assets/stylesheets/highlight/white.scss +++ b/app/assets/stylesheets/highlight/white.scss @@ -217,13 +217,31 @@ $white-gc-bg: #eaf2f5; .cp { color: $white-cp; font-weight: $gl-font-weight-bold; } .c1 { color: $white-c1; font-style: italic; } .cs { color: $white-cs; font-weight: $gl-font-weight-bold; font-style: italic; } - .gd { color: $white-gd; background-color: $white-gd-bg; } - .gd .x { color: $white-gd-x; background-color: $white-gd-x-bg; } + + .gd { + color: $white-gd; + background-color: $white-gd-bg; + + .x { + color: $white-gd-x; + background-color: $white-gd-x-bg; + } + } + .ge { font-style: italic; } .gr { color: $white-gr; } .gh { color: $white-gh; } - .gi { color: $white-gi; background-color: $white-gi-bg; } - .gi .x { color: $white-gi-x; background-color: $white-gi-x-bg; } + + .gi { + color: $white-gi; + background-color: $white-gi-bg; + + .x { + color: $white-gi-x; + background-color: $white-gi-x-bg; + } + } + .go { color: $white-go; } .gp { color: $white-gp; } .gs { font-weight: $gl-font-weight-bold; } diff --git a/app/assets/stylesheets/mailers/highlighted_diff_email.scss b/app/assets/stylesheets/mailers/highlighted_diff_email.scss index fbe538ad1d7..658ac26fca9 100644 --- a/app/assets/stylesheets/mailers/highlighted_diff_email.scss +++ b/app/assets/stylesheets/mailers/highlighted_diff_email.scss @@ -158,13 +158,31 @@ span.highlight_word { .cp { color: $highlighted-cp; font-weight: $gl-font-weight-bold; } .c1 { color: $highlighted-c1; font-style: italic; } .cs { color: $highlighted-cs; font-weight: $gl-font-weight-bold; font-style: italic; } -.gd { color: $highlighted-gd; background-color: $highlighted-gd-bg; } -.gd .x { color: $highlighted-gd; background-color: $highlighted-gd-x-bg; } + +.gd { + color: $highlighted-gd; + background-color: $highlighted-gd-bg; + + .x { + color: $highlighted-gd; + background-color: $highlighted-gd-x-bg; + } +} + .ge { font-style: italic; } .gr { color: $highlighted-gr; } .gh { color: $highlighted-gh; } -.gi { color: $highlighted-gi; background-color: $highlighted-gi-bg; } -.gi .x { color: $highlighted-gi; background-color: $highlighted-gi-x-bg; } + +.gi { + color: $highlighted-gi; + background-color: $highlighted-gi-bg; + + .x { + color: $highlighted-gi; + background-color: $highlighted-gi-x-bg; + } +} + .go { color: $highlighted-go; } .gp { color: $highlighted-gp; } .gs { font-weight: $gl-font-weight-bold; } diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss index 1409503d8e7..3683afa07de 100644 --- a/app/assets/stylesheets/pages/boards.scss +++ b/app/assets/stylesheets/pages/boards.scss @@ -72,7 +72,7 @@ } .boards-list { - height: calc(100vh - 152px); + height: calc(100vh - 105px); width: 100%; padding-top: 25px; padding-bottom: 25px; @@ -81,8 +81,12 @@ overflow-x: scroll; white-space: nowrap; - @media (min-width: $screen-sm-min) { - height: calc(100vh - 222px); + @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) { + height: calc(100vh - 90px); + } + + @media (min-width: $screen-md-min) { + height: calc(100vh - 160px); min-height: 475px; } } diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index e87ffe4f374..46978be8ba0 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -68,18 +68,18 @@ &.affix { top: $header-height; - } - // with sidebar - &.affix.sidebar-expanded { - right: 306px; - left: 16px; - } + // with sidebar + &.sidebar-expanded { + right: 306px; + left: 16px; + } - // without sidebar - &.affix.sidebar-collapsed { - right: 16px; - left: 16px; + // without sidebar + &.sidebar-collapsed { + right: 16px; + left: 16px; + } } &.affix-top { diff --git a/app/assets/stylesheets/pages/cycle_analytics.scss b/app/assets/stylesheets/pages/cycle_analytics.scss index 2a92673d9fa..82d9be29201 100644 --- a/app/assets/stylesheets/pages/cycle_analytics.scss +++ b/app/assets/stylesheets/pages/cycle_analytics.scss @@ -22,6 +22,11 @@ } } } + + svg { + width: 136px; + height: 136px; + } } .col-headers { @@ -155,11 +160,6 @@ } } - .landing svg { - width: 136px; - height: 136px; - } - .fa-spinner { font-size: 28px; position: relative; diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 09f831dcb29..faa3d1fb4d5 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -380,6 +380,10 @@ } } } + + .line_content { + white-space: pre-wrap; + } } .file-content .diff-file { @@ -387,10 +391,6 @@ border: none; } -.diff-file .line_content { - white-space: pre-wrap; -} - .diff-wrap-lines .line_content { white-space: pre-wrap; } diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index 6c1d32bed2f..b5b0f3d9dfa 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -255,23 +255,6 @@ width: 100%; padding: 0; padding-bottom: 100%; -} - -.prometheus-svg-container > svg { - position: absolute; - height: 100%; - width: 100%; - left: 0; - top: 0; - - text { - fill: $gl-text-color; - stroke-width: 0; - } - - .text-metric-bold { - font-weight: $gl-font-weight-bold; - } .label-axis-text { fill: $black; @@ -286,42 +269,51 @@ font-size: 12px; } - .legend-axis-text { - fill: $black; - } + > svg { + position: absolute; + height: 100%; + width: 100%; + left: 0; + top: 0; - .tick { - > line { - stroke: $gray-darker; + .label-axis-text, + .text-metric-usage { + fill: $black; + font-weight: $gl-font-weight-normal; + font-size: 12px; } - > text { - font-size: 12px; + .legend-axis-text { + fill: $black; } - } - .text-metric-title { - font-size: 12px; - } + .tick > text { + font-size: 12px; + } - .y-label-text, - .x-label-text { - fill: $gray-darkest; - } + .text-metric-title { + font-size: 12px; + } - .axis-tick { - stroke: $gray-darker; - } + .y-label-text, + .x-label-text { + fill: $gray-darkest; + } - @media (max-width: $screen-sm-max) { - .label-axis-text, - .text-metric-usage, - .legend-axis-text { - font-size: 8px; + .axis-tick { + stroke: $gray-darker; } - .tick > text { - font-size: 8px; + @media (max-width: $screen-sm-max) { + .label-axis-text, + .text-metric-usage, + .legend-axis-text { + font-size: 8px; + } + + .tick > text { + font-size: 8px; + } } } } diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 88600a0e6d3..7059a4cfe85 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -127,7 +127,16 @@ } .right-sidebar { - a:not(.btn-retry), + position: absolute; + top: $header-height; + bottom: 0; + right: 0; + transition: width .3s; + background: $gray-light; + z-index: 200; + overflow: hidden; + + a, .btn-link { color: inherit; } @@ -228,17 +237,6 @@ .btn-clipboard:hover { color: $gl-text-color; } -} - -.right-sidebar { - position: absolute; - top: $header-height; - bottom: 0; - right: 0; - transition: width $right-sidebar-transition-duration; - background: $gray-light; - z-index: 200; - overflow: hidden; .issuable-sidebar { width: calc(100% + 100px); diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index cf5f933a762..92d49bd864a 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -109,6 +109,30 @@ border-top-right-radius: $border-radius-default; border-top-left-radius: $border-radius-default; + // Ldap configurations may need more tabs & the tab labels are user generated (arbitrarily long). + // These styles prevent this from breaking the layout, and only applied when providers are configured. + &.custom-provider-tabs { + flex-wrap: wrap; + + li { + min-width: 85px; + flex-basis: auto; + + // This styles tab elements that have wrapped to a second line. We cannot easily predict when this will happen. + // We are making somewhat of an assumption about the configuration here: that users do not have more than + // 3 LDAP servers configured (in addition to standard login) and they are not using especially long names for any + // of them. If either condition is false, this will work as expected. If both are true, there may be a missing border + // above one of the bottom row elements. If you know a better way, please implement it! + &:nth-child(n+5) { + border-top: 1px solid $border-color; + } + } + + a { + font-size: 16px; + } + } + li { flex: 1; text-align: center; @@ -154,32 +178,6 @@ } } - // Ldap configurations may need more tabs & the tab labels are user generated (arbitrarily long). - // These styles prevent this from breaking the layout, and only applied when providers are configured. - - .new-session-tabs.custom-provider-tabs { - flex-wrap: wrap; - - li { - min-width: 85px; - flex-basis: auto; - - // This styles tab elements that have wrapped to a second line. We cannot easily predict when this will happen. - // We are making somewhat of an assumption about the configuration here: that users do not have more than - // 3 LDAP servers configured (in addition to standard login) and they are not using especially long names for any - // of them. If either condition is false, this will work as expected. If both are true, there may be a missing border - // above one of the bottom row elements. If you know a better way, please implement it! - &:nth-child(n+5) { - border-top: 1px solid $border-color; - } - } - - a { - font-size: 16px; - } - } - - .form-control { &:active, &:focus { @@ -231,35 +229,35 @@ margin: 0; padding: 0; height: 100%; -} -// Fixes footer container to bottom of viewport -.devise-layout-html body { - // offset height of fixed header + 1 to avoid scroll - height: calc(100% - 51px); - margin: 0; - padding: 0; + // Fixes footer container to bottom of viewport + body { + // offset height of fixed header + 1 to avoid scroll + height: calc(100% - 51px); + margin: 0; + padding: 0; - .page-wrap { - min-height: 100%; - position: relative; - } + .page-wrap { + min-height: 100%; + position: relative; + } - .footer-container, - hr.footer-fixed { - position: absolute; - bottom: 0; - left: 0; - right: 0; - height: 40px; - background: $white-light; - } + .footer-container, + hr.footer-fixed { + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 40px; + background: $white-light; + } - .navless-container { - padding: 65px 15px; // height of footer + bottom padding of email confirmation link + .navless-container { + padding: 65px 15px; // height of footer + bottom padding of email confirmation link - @media (max-width: $screen-xs-max) { - padding: 0 15px 65px; + @media (max-width: $screen-xs-max) { + padding: 0 15px 65px; + } } } } diff --git a/app/assets/stylesheets/pages/members.scss b/app/assets/stylesheets/pages/members.scss index 692acf74a58..18c48405ecd 100644 --- a/app/assets/stylesheets/pages/members.scss +++ b/app/assets/stylesheets/pages/members.scss @@ -49,9 +49,17 @@ width: auto; } } + + &.existing-title { + @media (min-width: $screen-sm-min) { + float: left; + } + } } .member-form-control { + @include new-style-dropdown; + @media (max-width: $screen-xs-max) { padding-bottom: 5px; margin-left: 0; @@ -64,12 +72,6 @@ line-height: 43px; } -.member.existing-title { - @media (min-width: $screen-sm-min) { - float: left; - } -} - .member-search-form { @include new-style-dropdown; @@ -281,7 +283,3 @@ } } } - -.member-form-control { - @include new-style-dropdown; -} diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 645fc1f3ebb..6e485ebad1b 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -156,6 +156,10 @@ &.media > *:first-child { margin-right: 10px; } + + .approve-btn { + margin-right: 5px; + } } .mr-widget-pipeline-graph { @@ -191,6 +195,10 @@ overflow: hidden; word-break: break-all; + &.media > *:first-child { + margin-right: 10px; + } + &.label-truncated { position: relative; display: inline-block; @@ -208,14 +216,7 @@ background-color: $gray-light; } } - } - .mr-widget-help { - padding: 10px 16px 10px 48px; - font-style: italic; - } - - .mr-widget-body { h4 { float: left; font-weight: $gl-font-weight-bold; @@ -238,6 +239,10 @@ margin-right: 7px; } + .approve-btn { + margin-right: 5px; + } + label { font-weight: $gl-font-weight-normal; } @@ -337,6 +342,22 @@ } } + .mini-pipeline-graph-dropdown-menu .mini-pipeline-graph-dropdown-item { + display: flex; + align-items: center; + + .ci-status-text, + .ci-status-icon { + top: 0; + margin-right: 10px; + } + } + + .mr-widget-help { + padding: 10px 16px 10px 48px; + font-style: italic; + } + .ci-coverage { float: right; } @@ -351,12 +372,6 @@ } } -.mr-state-widget .mr-widget-body { - .approve-btn { - margin-right: 5px; - } -} - .mr-widget-body-controls { flex-wrap: wrap; } @@ -470,16 +485,16 @@ padding-bottom: 0; } } -} -.mr-info-list.mr-memory-usage { - p { - float: left; - } + &.mr-memory-usage { + p { + float: left; + } - .memory-graph-container { - float: left; - margin-left: 5px; + .memory-graph-container { + float: left; + margin-left: 5px; + } } } diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss index 32039936be7..ae8fa45a2d7 100644 --- a/app/assets/stylesheets/pages/milestone.scss +++ b/app/assets/stylesheets/pages/milestone.scss @@ -66,6 +66,15 @@ height: 6px; margin: 0; } + + .sidebar-collapsed-icon { + clear: both; + padding: 15px 5px 5px; + + .progress { + margin: 5px 0; + } + } } .collapsed-milestone-date { @@ -93,17 +102,6 @@ margin-right: 0; } - .milestone-progress { - .sidebar-collapsed-icon { - clear: both; - padding: 15px 5px 5px; - - .progress { - margin: 5px 0; - } - } - } - .right-sidebar-collapsed & { .reference { border-top: 1px solid $border-gray-normal; @@ -156,18 +154,16 @@ .status-box { margin-top: 0; - } - - .milestone-buttons { - margin-left: auto; - } - - .status-box { order: 1; } .milestone-buttons { + margin-left: auto; order: 2; + + .verbose { + display: none; + } } .header-text-content { @@ -175,10 +171,6 @@ width: 100%; } - .milestone-buttons .verbose { - display: none; - } - @media (min-width: $screen-xs-min) { .milestone-buttons .verbose { display: inline; diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index f0cad30f4f3..5127307c5e7 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -111,24 +111,9 @@ margin: auto; align-items: center; - .icon { - margin-right: $issuable-warning-icon-margin; - } -} - -.disabled-comment .issuable-note-warning { - border: none; - border-radius: $label-border-radius; - padding-top: $gl-vert-padding; - padding-bottom: $gl-vert-padding; - - .icon svg { - position: relative; - top: 2px; - margin-right: $btn-xs-side-margin; - width: $gl-font-size; - height: $gl-font-size; - fill: $orange-600; + + .md-area { + border-top-left-radius: 0; + border-top-right-radius: 0; } } @@ -155,11 +140,6 @@ } } -.issuable-note-warning + .md-area { - border-top-left-radius: 0; - border-top-right-radius: 0; -} - .discussion-form { background-color: $white-light; } diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index f2d3e3d5cb6..ca363c6eac4 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -312,57 +312,72 @@ ul.notes { } } -.diff-file .notes_holder { - font-family: $regular_font; +.diff-file { + .is-over { + .add-diff-note { + display: inline-block; + } + } - td { - border: 1px solid $white-normal; - border-left: none; + // Merge request notes in diffs + // Diff is inline + .notes_content .note-header .note-headline-light { + display: inline-block; + position: relative; + } - &.notes_line { - vertical-align: middle; - text-align: center; - padding: 10px 0; - background: $gray-light; - color: $text-color; - } + .notes_holder { + font-family: $regular_font; - &.notes_line2 { - text-align: center; - padding: 10px 0; - border-left: 1px solid $note-line2-border !important; - } + td { + border: 1px solid $white-normal; + border-left: none; - &.notes_content { - background-color: $gray-light; - border-width: 1px 0; - padding: 0; - vertical-align: top; - white-space: normal; + &.notes_line { + vertical-align: middle; + text-align: center; + padding: 10px 0; + background: $gray-light; + color: $text-color; + } - &.parallel { - border-width: 1px; + &.notes_line2 { + text-align: center; + padding: 10px 0; + border-left: 1px solid $note-line2-border !important; } - .discussion-notes { - &:not(:first-child) { - border-top: 1px solid $white-normal; - margin-top: 20px; + &.notes_content { + background-color: $gray-light; + border-width: 1px 0; + padding: 0; + vertical-align: top; + white-space: normal; + + &.parallel { + border-width: 1px; } - &:not(:last-child) { - border-bottom: 1px solid $white-normal; - margin-bottom: 20px; + .discussion-notes { + &:not(:first-child) { + border-top: 1px solid $white-normal; + margin-top: 20px; + } + + &:not(:last-child) { + border-bottom: 1px solid $white-normal; + margin-bottom: 20px; + } } - } - .notes { - background-color: $white-light; - } + .notes { + background-color: $white-light; + } - a code { - top: 0; - margin-right: 0; + a code { + top: 0; + margin-right: 0; + } } } } @@ -457,8 +472,9 @@ ul.notes { margin-left: 10px; color: $gray-darkest; - .btn-group > .discussion-next-btn { - margin-left: -1px; + @include notes-media('max', $screen-md-max) { + float: none; + margin-left: 0; } } @@ -499,13 +515,6 @@ ul.notes { min-width: 180px; } -.discussion-actions { - @include notes-media('max', $screen-md-max) { - float: none; - margin-left: 0; - } -} - .note-actions-item { margin-left: 12px; display: flex; @@ -662,14 +671,6 @@ ul.notes { } } -.diff-file { - .is-over { - .add-diff-note { - display: inline-block; - } - } -} - .disabled-comment { background-color: $gray-light; border-radius: $border-radius-base; @@ -711,20 +712,20 @@ ul.notes { svg path { fill: $gray-darkest; } - } - .btn.discussion-create-issue-btn { - margin-left: -4px; - border-radius: 0; - border-right: 0; + &.discussion-create-issue-btn { + margin-left: -4px; + border-radius: 0; + border-right: 0; - a { - padding: 0; - line-height: 0; + a { + padding: 0; + line-height: 0; - &:hover { - text-decoration: none; - border: 0; + &:hover { + text-decoration: none; + border: 0; + } } } } @@ -798,12 +799,3 @@ ul.notes { .line-resolve-text { vertical-align: middle; } - -// Merge request notes in diffs -.diff-file { - // Diff is inline - .notes_content .note-header .note-headline-light { - display: inline-block; - position: relative; - } -} diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 6604b471560..2a8cbc61af7 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -175,6 +175,25 @@ } } + /** + * Play button with icon in dropdowns + */ + .no-btn { + border: none; + background: none; + outline: none; + width: 100%; + text-align: left; + + .icon-play { + position: relative; + top: 2px; + margin-right: 5px; + height: 13px; + width: 12px; + } + } + .duration, .finished-at { color: $gl-text-color-secondary; @@ -450,48 +469,48 @@ @extend .build-content:hover; } - // Action Icons in big pipeline-graph nodes - .ci-action-icon-container.ci-action-icon-wrapper { - height: 30px; - width: 30px; - background: $white-light; - border: 1px solid $border-color; - border-radius: 100%; - display: block; + .ci-action-icon-container { + position: absolute; + right: 5px; + top: 5px; - &:hover { - background-color: $stage-hover-bg; - border: 1px solid $dropdown-toggle-active-border-color; - } + // Action Icons in big pipeline-graph nodes + &.ci-action-icon-wrapper { + height: 30px; + width: 30px; + background: $white-light; + border: 1px solid $border-color; + border-radius: 100%; + display: block; - svg { - fill: $gl-text-color-secondary; - position: relative; - left: 5px; - top: 2px; - width: 18px; - height: 18px; - } + &:hover { + background-color: $stage-hover-bg; + border: 1px solid $dropdown-toggle-active-border-color; + + svg { + fill: $gl-text-color; + } + } - &.play { svg { - width: #{$ci-action-icon-size - 8}; - height: #{$ci-action-icon-size - 8}; - left: 8px; + fill: $gl-text-color-secondary; + position: relative; + left: 5px; + top: 2px; + width: 18px; + height: 18px; } - } - &:hover svg { - fill: $gl-text-color; + &.play { + svg { + width: #{$ci-action-icon-size - 8}; + height: #{$ci-action-icon-size - 8}; + left: 8px; + } + } } } - .ci-action-icon-container { - position: absolute; - right: 5px; - top: 5px; - } - .ci-status-icon svg { height: 20px; width: 20px; @@ -735,6 +754,28 @@ button.mini-pipeline-graph-dropdown-toggle { left: -3px; position: relative; top: -2px; + + &.icon-action-stop, + &.icon-action-cancel { + width: 12px; + height: 12px; + top: 1px; + left: -1px; + } + + &.icon-action-play { + width: 11px; + height: 11px; + top: 1px; + left: 1px; + } + + &.icon-action-retry { + width: 16px; + height: 16px; + top: 0; + left: -3px; + } } &:hover svg, @@ -751,27 +792,6 @@ button.mini-pipeline-graph-dropdown-toggle { } } - svg.icon-action-stop, - svg.icon-action-cancel { - width: 12px; - height: 12px; - top: 1px; - left: -1px; - } - - svg.icon-action-play { - width: 11px; - height: 11px; - top: 1px; - left: 1px; - } - - svg.icon-action-retry { - width: 16px; - height: 16px; - top: 0; - left: -3px; - } } @@ -840,13 +860,10 @@ button.mini-pipeline-graph-dropdown-toggle { left: 100%; top: -10px; box-shadow: 0 1px 5px $black-transparent; -} - -/** - * Top arrow in the dropdown in the big pipeline graph - */ -.big-pipeline-graph-dropdown-menu { + /** + * Top arrow in the dropdown in the big pipeline graph + */ &::before, &::after { content: ''; @@ -908,22 +925,23 @@ button.mini-pipeline-graph-dropdown-toggle { margin-top: 1px; border-bottom-color: $white-light; } -} -/** - * Center dropdown menu in mini graph - */ -.mini-pipeline-graph-dropdown-menu.dropdown-menu { - transform: translate(-80%, 0); - min-width: 150px; + /** + * Center dropdown menu in mini graph + */ + &.dropdown-menu { + transform: translate(-80%, 0); + min-width: 150px; - @media(min-width: $screen-md-min) { - transform: translate(-50%, 0); - right: auto; - left: 50%; - min-width: 240px; + @media(min-width: $screen-md-min) { + transform: translate(-50%, 0); + right: auto; + left: 50%; + min-width: 240px; + } } } + /** * Terminal */ @@ -947,25 +965,6 @@ button.mini-pipeline-graph-dropdown-toggle { } } -/** - * Play button with icon in dropdowns - */ -.ci-table .no-btn { - border: none; - background: none; - outline: none; - width: 100%; - text-align: left; - - .icon-play { - position: relative; - top: 2px; - margin-right: 5px; - height: 13px; - width: 12px; - } -} - .ci-header-container { min-height: 55px; diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index bd385db9692..b0c3474e3d5 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -88,7 +88,8 @@ transition: background 2s ease-out; &:disabled { - opacity: 0.75; + opacity: 0.5; + pointer-events: none; } .highlight-changes & { @@ -778,35 +779,35 @@ a.deploy-project-label { .nav { padding-top: 12px; padding-bottom: 12px; - } - .nav > li { - display: inline-block; + > li { + display: inline-block; - &:not(:last-child) { - margin-right: $gl-padding; - } + &:not(:last-child) { + margin-right: $gl-padding; + } - &.right { - vertical-align: top; - margin-top: 0; + &.right { + vertical-align: top; + margin-top: 0; - @media (min-width: $screen-lg-min) { - float: right; + @media (min-width: $screen-lg-min) { + float: right; + } } - } - } - .nav > li > a { - padding: 0; - background-color: transparent; - font-size: 14px; - line-height: 29px; - color: $notes-light-color; + > a { + padding: 0; + background-color: transparent; + font-size: 14px; + line-height: 29px; + color: $notes-light-color; - &:hover, - &:focus { - color: $gl-text-color; + &:hover, + &:focus { + color: $gl-text-color; + } + } } } @@ -1160,13 +1161,6 @@ pre.light-well { } } -.project-repo-select { - &.disabled { - opacity: 0.5; - pointer-events: none; - } -} - .variables-table { table-layout: fixed; diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index db0a04a5eb3..eed711b1b66 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -78,6 +78,10 @@ input[type="checkbox"]:hover { } .search-input-wrap { + // Fallback if flexbox is not supported + display: inline-block; + width: 100%; + .search-icon, .clear-icon { position: absolute; diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss index 968a94c68cf..8b9b47a41bc 100644 --- a/app/assets/stylesheets/pages/settings.scss +++ b/app/assets/stylesheets/pages/settings.scss @@ -241,11 +241,11 @@ margin-left: 5px; background: $badge-bg; } - } - /* Ensure we don't add border if there's only single li */ - li + li { - border-top: 1px solid $border-color; + /* Ensure we don't add border if there's only single li */ + + li { + border-top: 1px solid $border-color; + } } } } diff --git a/app/assets/stylesheets/pages/sherlock.scss b/app/assets/stylesheets/pages/sherlock.scss index bfe065dbbaf..2bf0bedb1f5 100644 --- a/app/assets/stylesheets/pages/sherlock.scss +++ b/app/assets/stylesheets/pages/sherlock.scss @@ -5,10 +5,10 @@ table .sherlock-code { .sherlock-code { pre { word-wrap: normal; - } - pre code { - white-space: pre; + code { + white-space: pre; + } } } @@ -21,13 +21,13 @@ table .sherlock-code { text-align: right; padding: 0 10px !important; } + + .slow { + color: $red-500; + font-weight: $gl-font-weight-bold; + } } .sherlock-file-sample pre { padding-top: 28px !important; } - -.sherlock-line-samples-table .slow { - color: $red-500; - font-weight: $gl-font-weight-bold; -} diff --git a/app/assets/stylesheets/pages/stat_graph.scss b/app/assets/stylesheets/pages/stat_graph.scss index dfa4d033fb8..cede147d559 100644 --- a/app/assets/stylesheets/pages/stat_graph.scss +++ b/app/assets/stylesheets/pages/stat_graph.scss @@ -40,16 +40,16 @@ @media (max-width: $screen-xs-max) { width: 100%; } - } - .person .spark { - display: block; - background: $stat-graph-common-bg; - width: 100%; - } + .spark { + display: block; + background: $stat-graph-common-bg; + width: 100%; + } - .person .area-contributor { - fill: $stat-graph-orange-fill; + .area-contributor { + fill: $stat-graph-orange-fill; + } } } diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss index b7d4e7bf582..e150f96f3fa 100644 --- a/app/assets/stylesheets/pages/wiki.scss +++ b/app/assets/stylesheets/pages/wiki.scss @@ -161,10 +161,10 @@ ul.wiki-pages-list.content-list { list-style: none; margin-left: 0; padding-left: 15px; - } - ul li { - padding: 5px 0; + li { + padding: 5px 0; + } } } diff --git a/app/controllers/admin/applications_controller.rb b/app/controllers/admin/applications_controller.rb index fb6d8c0bb81..5be23c76a95 100644 --- a/app/controllers/admin/applications_controller.rb +++ b/app/controllers/admin/applications_controller.rb @@ -19,10 +19,12 @@ class Admin::ApplicationsController < Admin::ApplicationController end def create - @application = Doorkeeper::Application.new(application_params) + @application = Applications::CreateService.new(current_user, application_params).execute(request) - if @application.save - redirect_to_admin_page + if @application.persisted? + flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create]) + + redirect_to admin_application_url(@application) else render :new end @@ -41,13 +43,6 @@ class Admin::ApplicationsController < Admin::ApplicationController redirect_to admin_applications_url, status: 302, notice: 'Application was successfully destroyed.' end - protected - - def redirect_to_admin_page - flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create]) - redirect_to admin_application_url(@application) - end - private def set_application diff --git a/app/controllers/concerns/lfs_request.rb b/app/controllers/concerns/lfs_request.rb index 2b6afaa6233..738afd612f0 100644 --- a/app/controllers/concerns/lfs_request.rb +++ b/app/controllers/concerns/lfs_request.rb @@ -94,10 +94,9 @@ module LfsRequest @storage_project ||= begin result = project - loop do - break unless result.forked? - result = result.forked_from_project - end + # TODO: Make this go to the fork_network root immeadiatly + # dependant on the discussion in: https://gitlab.com/gitlab-org/gitlab-ce/issues/39769 + result = result.fork_source while result.forked? result end diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb index b02e64a132b..2443f529c7b 100644 --- a/app/controllers/oauth/applications_controller.rb +++ b/app/controllers/oauth/applications_controller.rb @@ -16,25 +16,18 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController end def create - @application = Doorkeeper::Application.new(application_params) + @application = Applications::CreateService.new(current_user, create_application_params).execute(request) - @application.owner = current_user + if @application.persisted? + flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create]) - if @application.save - redirect_to_oauth_application_page + redirect_to oauth_application_url(@application) else set_index_vars render :index end end - protected - - def redirect_to_oauth_application_page - flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create]) - redirect_to oauth_application_url(@application) - end - private def verify_user_oauth_applications_enabled @@ -61,4 +54,10 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController rescue_from ActiveRecord::RecordNotFound do |exception| render "errors/not_found", layout: "errors", status: 404 end + + def create_application_params + application_params.tap do |params| + params[:owner] = current_user + end + end end diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb index 069e6a810f2..f0e5d2aa94e 100644 --- a/app/controllers/profiles/keys_controller.rb +++ b/app/controllers/profiles/keys_controller.rb @@ -11,10 +11,10 @@ class Profiles::KeysController < Profiles::ApplicationController end def create - @key = Keys::CreateService.new(current_user, key_params).execute + @key = Keys::CreateService.new(current_user, key_params.merge(ip_address: request.remote_ip)).execute if @key.persisted? - redirect_to_profile_key_path + redirect_to profile_key_path(@key) else @keys = current_user.keys.select(&:persisted?) render :index @@ -50,12 +50,6 @@ class Profiles::KeysController < Profiles::ApplicationController end end - protected - - def redirect_to_profile_key_path - redirect_to profile_key_path(@key) - end - private def key_params diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index d085c1a0e57..f48d47953e4 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -110,7 +110,15 @@ module ProjectsHelper def remove_fork_project_message(project) _("You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?") % - { forked_from_project: @project.forked_from_project.name_with_namespace } + { forked_from_project: fork_source_name(project) } + end + + def fork_source_name(project) + if @project.fork_source + @project.fork_source.full_name + else + @project.fork_network&.deleted_root_project_name + end end def project_nav_tabs @@ -140,8 +148,8 @@ module ProjectsHelper def can_change_visibility_level?(project, current_user) return false unless can?(current_user, :change_visibility_level, project) - if project.forked? - project.forked_from_project.visibility_level > Gitlab::VisibilityLevel::PRIVATE + if project.fork_source + project.fork_source.visibility_level > Gitlab::VisibilityLevel::PRIVATE else true end diff --git a/app/models/environment.rb b/app/models/environment.rb index e613d21add6..8d6b0a32c13 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -110,7 +110,7 @@ class Environment < ActiveRecord::Base end def ref_path - "refs/#{Repository::REF_ENVIRONMENTS}/#{generate_slug}" + "refs/#{Repository::REF_ENVIRONMENTS}/#{slug}" end def formatted_external_url @@ -164,6 +164,10 @@ class Environment < ActiveRecord::Base end end + def slug + super.presence || generate_slug + end + # An environment name is not necessarily suitable for use in URLs, DNS # or other third-party contexts, so provide a slugified version. A slug has # the following properties: diff --git a/app/models/epic.rb b/app/models/epic.rb index 0d5f21fb617..62898a02e2d 100644 --- a/app/models/epic.rb +++ b/app/models/epic.rb @@ -1,8 +1,6 @@ # Placeholder class for model that is implemented in EE # It will reserve (ee#3853) '&' as a reference prefix, but the table does not exists in CE class Epic < ActiveRecord::Base - prepend EE::Epic - # TODO: this will be implemented as part of #3853 def to_reference end diff --git a/app/models/fork_network.rb b/app/models/fork_network.rb index 218e37a5312..7f1728e8c77 100644 --- a/app/models/fork_network.rb +++ b/app/models/fork_network.rb @@ -12,4 +12,8 @@ class ForkNetwork < ActiveRecord::Base def find_forks_in(other_projects) projects.where(id: other_projects) end + + def merge_requests + MergeRequest.where(target_project: projects) + end end diff --git a/app/models/group.rb b/app/models/group.rb index 4e8023cdb7f..c660de7fcb6 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -42,6 +42,7 @@ class Group < Namespace after_create :post_create_hook after_destroy :post_destroy_hook after_save :update_two_factor_requirement + after_update :path_changed_hook, if: :path_changed? class << self def supports_nested_groups? @@ -295,6 +296,12 @@ class Group < Namespace list_of_ids.reverse.map { |group| variables[group.id] }.compact.flatten end + def full_path_was + return path_was unless has_parent? + + "#{parent.full_path}/#{path_was}" + end + private def update_two_factor_requirement @@ -303,6 +310,10 @@ class Group < Namespace users.find_each(&:update_two_factor_requirement) end + def path_changed_hook + system_hook_service.execute_hooks_for(self, :rename) + end + def visibility_level_allowed_by_parent return if visibility_level_allowed_by_parent? diff --git a/app/models/project.rb b/app/models/project.rb index 413866b994a..2f9b80d0514 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1040,6 +1040,10 @@ class Project < ActiveRecord::Base !(forked_project_link.nil? || forked_project_link.forked_from_project.nil?) end + def fork_source + forked_from_project || fork_network&.root_project + end + def personal? !group end diff --git a/app/models/user.rb b/app/models/user.rb index 6c9349ed9dd..bcda4564595 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -168,6 +168,7 @@ class User < ActiveRecord::Base before_save :skip_reconfirmation!, if: ->(user) { user.email_changed? && user.read_only_attribute?(:email) } before_save :check_for_verified_email, if: ->(user) { user.email_changed? && !user.new_record? } after_save :ensure_namespace_correct + after_update :username_changed_hook, if: :username_changed? after_destroy :post_destroy_hook after_commit :update_emails_with_primary_email, on: :update, if: -> { previous_changes.key?('email') } after_commit :update_invalid_gpg_signatures, on: :update, if: -> { previous_changes.key?('email') } @@ -871,6 +872,10 @@ class User < ActiveRecord::Base end end + def username_changed_hook + system_hook_service.execute_hooks_for(self, :rename) + end + def post_destroy_hook log_info("User \"#{name}\" (#{email}) was removed") system_hook_service.execute_hooks_for(self, :destroy) diff --git a/app/services/applications/create_service.rb b/app/services/applications/create_service.rb new file mode 100644 index 00000000000..35d45f25a71 --- /dev/null +++ b/app/services/applications/create_service.rb @@ -0,0 +1,13 @@ +module Applications + class CreateService + def initialize(current_user, params) + @current_user = current_user + @params = params + @ip_address = @params.delete(:ip_address) + end + + def execute(request = nil) + Doorkeeper::Application.create(@params) + end + end +end diff --git a/app/services/keys/base_service.rb b/app/services/keys/base_service.rb index 545832d0bd4..f78791932a7 100644 --- a/app/services/keys/base_service.rb +++ b/app/services/keys/base_service.rb @@ -4,6 +4,7 @@ module Keys def initialize(user, params) @user, @params = user, params + @ip_address = @params.delete(:ip_address) end def notification_service diff --git a/app/services/projects/unlink_fork_service.rb b/app/services/projects/unlink_fork_service.rb index 2b82e5732e4..c499f384426 100644 --- a/app/services/projects/unlink_fork_service.rb +++ b/app/services/projects/unlink_fork_service.rb @@ -3,18 +3,24 @@ module Projects def execute return unless @project.forked? - @project.forked_from_project.lfs_objects.find_each do |lfs_object| - lfs_object.projects << @project + if fork_source = @project.fork_source + fork_source.lfs_objects.find_each do |lfs_object| + lfs_object.projects << @project + end + + refresh_forks_count(fork_source) end - merge_requests = @project.forked_from_project.merge_requests.opened.from_project(@project) + merge_requests = @project.fork_network + .merge_requests + .opened + .where.not(target_project: @project) + .from_project(@project) merge_requests.each do |mr| ::MergeRequests::CloseService.new(@project, @current_user).execute(mr) end - refresh_forks_count(@project.forked_from_project) - @project.fork_network_member.destroy @project.forked_project_link.destroy end diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb index 5d275967821..911cc919bb8 100644 --- a/app/services/system_hooks_service.rb +++ b/app/services/system_hooks_service.rb @@ -35,24 +35,22 @@ class SystemHooksService data[:old_path_with_namespace] = model.old_path_with_namespace end when User - data.merge!({ - name: model.name, - email: model.email, - user_id: model.id, - username: model.username - }) + data.merge!(user_data(model)) + + if event == :rename + data[:old_username] = model.username_was + end when ProjectMember data.merge!(project_member_data(model)) when Group - owner = model.owner + data.merge!(group_data(model)) - data.merge!( - name: model.name, - path: model.path, - group_id: model.id, - owner_name: owner.respond_to?(:name) ? owner.name : nil, - owner_email: owner.respond_to?(:email) ? owner.email : nil - ) + if event == :rename + data.merge!( + old_path: model.path_was, + old_full_path: model.full_path_was + ) + end when GroupMember data.merge!(group_member_data(model)) end @@ -104,6 +102,19 @@ class SystemHooksService } end + def group_data(model) + owner = model.owner + + { + name: model.name, + path: model.path, + full_path: model.full_path, + group_id: model.id, + owner_name: owner.try(:name), + owner_email: owner.try(:email) + } + end + def group_member_data(model) { group_name: model.group.name, @@ -116,4 +127,13 @@ class SystemHooksService group_access: model.human_access } end + + def user_data(model) + { + name: model.name, + email: model.email, + user_id: model.id, + username: model.username + } + end end diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml index f62a0cd681e..a5686002328 100644 --- a/app/views/dashboard/todos/index.html.haml +++ b/app/views/dashboard/todos/index.html.haml @@ -8,7 +8,7 @@ %li.todos-pending{ class: active_when(params[:state].blank? || params[:state] == 'pending') }> = link_to todos_filter_path(state: 'pending') do %span - To do + Todos %span.badge = number_with_delimiter(todos_pending_count) %li.todos-done{ class: active_when(params[:state] == 'done') }> diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index 619b632918e..1d644dda177 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -1,6 +1,5 @@ - empty_repo = @project.empty_repo? - fork_network = @project.fork_network -- forked_from_project = @project.forked_from_project || fork_network&.root_project .project-home-panel.text-center{ class: ("empty-project" if empty_repo) } .limit-container-width{ class: container_class } .avatar-container.s70.project-avatar @@ -16,13 +15,13 @@ - if @project.forked? %p - - if forked_from_project + - if @project.fork_source #{ s_('ForkedFromProjectPath|Forked from') } - = link_to project_path(forked_from_project) do - = forked_from_project.full_name + = link_to project_path(@project.fork_source) do + = fork_source_name(@project) - else - deleted_message = s_('ForkedFromProjectPath|Forked from %{project_name} (deleted)') - = deleted_message % { project_name: fork_network.deleted_root_project_name } + = deleted_message % { project_name: fork_source_name(@project) } .project-repo-buttons .count-buttons diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 5703ef1d4bb..5ebeae5c35f 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -173,7 +173,10 @@ %p This will remove the fork relationship to source project = succeed "." do - = link_to @project.forked_from_project.name_with_namespace, project_path(@project.forked_from_project) + - if @project.fork_source + = link_to(fork_source_name(@project), project_path(@project.fork_source)) + - else + = fork_source_name(@project) = form_for([@project.namespace.becomes(Namespace), @project], url: remove_fork_project_path(@project), method: :delete, remote: true, html: { class: 'transfer-project' }) do |f| %p %strong Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source. diff --git a/changelogs/unreleased/39054-activerecord-statementinvalid-pg-querycanceled-error-canceling-statement-due-to-statement-timeout.yml b/changelogs/unreleased/39054-activerecord-statementinvalid-pg-querycanceled-error-canceling-statement-due-to-statement-timeout.yml deleted file mode 100644 index 47bf30ecb5a..00000000000 --- a/changelogs/unreleased/39054-activerecord-statementinvalid-pg-querycanceled-error-canceling-statement-due-to-statement-timeout.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Stop merge requests with thousands of commits from timing out -merge_request: 15063 -author: -type: performance diff --git a/changelogs/unreleased/39188-change-default-disabled-merge-message.yml b/changelogs/unreleased/39188-change-default-disabled-merge-message.yml deleted file mode 100644 index 7de65f5c3f6..00000000000 --- a/changelogs/unreleased/39188-change-default-disabled-merge-message.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Update default disabled merge request widget message to reflect a general failure -merge_request: 14960 -author: -type: changed diff --git a/changelogs/unreleased/39366-email-confirmation-fails.yml b/changelogs/unreleased/39366-email-confirmation-fails.yml deleted file mode 100644 index a5568670c70..00000000000 --- a/changelogs/unreleased/39366-email-confirmation-fails.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Fix bug preventing secondary emails from being confirmed' -merge_request: 15010 -author: -type: fixed diff --git a/changelogs/unreleased/39417-todos-spelled-correctly-on-todos-list-page.yml b/changelogs/unreleased/39417-todos-spelled-correctly-on-todos-list-page.yml new file mode 100644 index 00000000000..edf142f0311 --- /dev/null +++ b/changelogs/unreleased/39417-todos-spelled-correctly-on-todos-list-page.yml @@ -0,0 +1,5 @@ +--- +title: Todos spelled correctly on Todos list page +merge_request: 15015 +author: +type: changed diff --git a/changelogs/unreleased/39441-bring-edit-form-back.yml b/changelogs/unreleased/39441-bring-edit-form-back.yml deleted file mode 100644 index 025417e4da9..00000000000 --- a/changelogs/unreleased/39441-bring-edit-form-back.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix editing issue description in mobile view -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/39495-fix-bitbucket-login.yml b/changelogs/unreleased/39495-fix-bitbucket-login.yml deleted file mode 100644 index b48d557108b..00000000000 --- a/changelogs/unreleased/39495-fix-bitbucket-login.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix bitbucket login -merge_request: 15051 -author: -type: fixed diff --git a/changelogs/unreleased/39639-clusters-poll.yml b/changelogs/unreleased/39639-clusters-poll.yml deleted file mode 100644 index f0a82f58b19..00000000000 --- a/changelogs/unreleased/39639-clusters-poll.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Adds callback functions for initial request in clusters page -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/39776-remove-responsive-table-bottom-border.yml b/changelogs/unreleased/39776-remove-responsive-table-bottom-border.yml new file mode 100644 index 00000000000..52b6a267ced --- /dev/null +++ b/changelogs/unreleased/39776-remove-responsive-table-bottom-border.yml @@ -0,0 +1,5 @@ +--- +title: Fix double border UI bug on pipelines/environments table and pagination +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/bvl-circuitbreaker-backoff.yml b/changelogs/unreleased/bvl-circuitbreaker-backoff.yml deleted file mode 100644 index 5cb90e7c085..00000000000 --- a/changelogs/unreleased/bvl-circuitbreaker-backoff.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Make the circuitbreaker more robust by adding higher thresholds, and multiple - access attempts. -merge_request: 14933 -author: -type: fixed diff --git a/changelogs/unreleased/bvl-circuitbreaker-improvements.yml b/changelogs/unreleased/bvl-circuitbreaker-improvements.yml deleted file mode 100644 index 15cbd5592e9..00000000000 --- a/changelogs/unreleased/bvl-circuitbreaker-improvements.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Store circuitbreaker settings in the database instead of config -merge_request: 14842 -author: -type: changed diff --git a/changelogs/unreleased/bvl-do-not-use-redis-keys.yml b/changelogs/unreleased/bvl-do-not-use-redis-keys.yml deleted file mode 100644 index f703aad2065..00000000000 --- a/changelogs/unreleased/bvl-do-not-use-redis-keys.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Forbid the usage of `Redis#keys` -merge_request: 14889 -author: -type: fixed diff --git a/changelogs/unreleased/bvl-dont-rename-free-names.yml b/changelogs/unreleased/bvl-dont-rename-free-names.yml deleted file mode 100644 index 60a4ec8afbe..00000000000 --- a/changelogs/unreleased/bvl-dont-rename-free-names.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Don't rename paths that were freed up when upgrading -merge_request: 15029 -author: -type: fixed diff --git a/changelogs/unreleased/bvl-fix-push-event-service-for-forks.yml b/changelogs/unreleased/bvl-fix-push-event-service-for-forks.yml deleted file mode 100644 index 2a7d80270ac..00000000000 --- a/changelogs/unreleased/bvl-fix-push-event-service-for-forks.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Only cache last push event for existing projects when pushing to a fork -merge_request: 14989 -author: -type: fixed diff --git a/changelogs/unreleased/bvl-fix-system-hook-project-visibility.yml b/changelogs/unreleased/bvl-fix-system-hook-project-visibility.yml deleted file mode 100644 index a17ed51c9b8..00000000000 --- a/changelogs/unreleased/bvl-fix-system-hook-project-visibility.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Use the correct visibility attribute for projects in system hooks -merge_request: 15065 -author: -type: fixed diff --git a/changelogs/unreleased/bvl-unlink-fixes.yml b/changelogs/unreleased/bvl-unlink-fixes.yml new file mode 100644 index 00000000000..685d78f479d --- /dev/null +++ b/changelogs/unreleased/bvl-unlink-fixes.yml @@ -0,0 +1,5 @@ +--- +title: Fix issues with forked projects of which the source was deleted +merge_request: 15150 +author: +type: fixed diff --git a/changelogs/unreleased/dm-ldap-identity-normalize-dn.yml b/changelogs/unreleased/dm-ldap-identity-normalize-dn.yml deleted file mode 100644 index 7ab25f79143..00000000000 --- a/changelogs/unreleased/dm-ldap-identity-normalize-dn.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Normalize LDAP DN when looking up identity -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/enable-scss-lint-mergeable-selector.yml b/changelogs/unreleased/enable-scss-lint-mergeable-selector.yml new file mode 100644 index 00000000000..5f6e0cafe88 --- /dev/null +++ b/changelogs/unreleased/enable-scss-lint-mergeable-selector.yml @@ -0,0 +1,4 @@ +--- +title: Enable MergeableSelector in scss-lint +merge_request: 12810 +author: Takuya Noguchi diff --git a/changelogs/unreleased/fix-add-path-attr-to-wiki-file.yml b/changelogs/unreleased/fix-add-path-attr-to-wiki-file.yml deleted file mode 100644 index 0847b5f6733..00000000000 --- a/changelogs/unreleased/fix-add-path-attr-to-wiki-file.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix broken wiki pages that link to a wiki file -merge_request: 15019 -author: -type: fixed diff --git a/changelogs/unreleased/fix-import-issue-assignees.yml b/changelogs/unreleased/fix-import-issue-assignees.yml deleted file mode 100644 index 063b6afaf08..00000000000 --- a/changelogs/unreleased/fix-import-issue-assignees.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix missing Import/Export issue assignees -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/fix_global_board_routes_39073.yml b/changelogs/unreleased/fix_global_board_routes_39073.yml deleted file mode 100644 index cc9ae8592db..00000000000 --- a/changelogs/unreleased/fix_global_board_routes_39073.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Allow boards as top level route -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/make-merge-jid-handling-less-stateful.yml b/changelogs/unreleased/make-merge-jid-handling-less-stateful.yml deleted file mode 100644 index fe945e822fd..00000000000 --- a/changelogs/unreleased/make-merge-jid-handling-less-stateful.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix widget of locked merge requests not being presented -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/mr-14642.yml b/changelogs/unreleased/mr-14642.yml deleted file mode 100644 index 048cc79e323..00000000000 --- a/changelogs/unreleased/mr-14642.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Auto Devops kubernetes default namespace is now correctly built out of gitlab - project group-name -merge_request: 14642 -author: Mircea Danila Dumitrescu -type: fixed diff --git a/changelogs/unreleased/sh-fix-container-registry-destroy.yml b/changelogs/unreleased/sh-fix-container-registry-destroy.yml deleted file mode 100644 index 21a463da62a..00000000000 --- a/changelogs/unreleased/sh-fix-container-registry-destroy.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix deletion of container registry or images returning an error -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/sh-fix-environment-slug-generation.yml b/changelogs/unreleased/sh-fix-environment-slug-generation.yml new file mode 100644 index 00000000000..8a9c670c52c --- /dev/null +++ b/changelogs/unreleased/sh-fix-environment-slug-generation.yml @@ -0,0 +1,5 @@ +--- +title: Avoid regenerating the ref path for the environment +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/sh-fix-environment-write-ref.yml b/changelogs/unreleased/sh-fix-environment-write-ref.yml deleted file mode 100644 index 8f291843ebe..00000000000 --- a/changelogs/unreleased/sh-fix-environment-write-ref.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix the writing of invalid environment refs -merge_request: -author: -type: fixed diff --git a/changelogs/unreleased/winh-namespace-rename-hooks.yml b/changelogs/unreleased/winh-namespace-rename-hooks.yml new file mode 100644 index 00000000000..f5090b03b74 --- /dev/null +++ b/changelogs/unreleased/winh-namespace-rename-hooks.yml @@ -0,0 +1,5 @@ +--- +title: Add system hooks user_rename and group_rename +merge_request: 15123 +author: +type: changed diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 4bfa5be0136..7547ba4a8fa 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -501,7 +501,7 @@ production: &base # Gitaly settings gitaly: # Path to the directory containing Gitaly client executables. - client_path: /home/git/gitaly + client_path: /home/git/gitaly/bin # Default Gitaly authentication token. Can be overriden per storage. Can # be left blank when Gitaly is running locally on a Unix socket, which # is the normal way to deploy Gitaly. diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md index a45a4eb9e49..f2a9b1d769b 100644 --- a/doc/system_hooks/system_hooks.md +++ b/doc/system_hooks/system_hooks.md @@ -1,6 +1,24 @@ # System hooks -Your GitLab instance can perform HTTP POST requests on the following events: `project_create`, `project_destroy`, `project_rename`, `project_transfer`, `project_update`, `user_add_to_team`, `user_remove_from_team`, `user_create`, `user_destroy`, `key_create`, `key_destroy`, `group_create`, `group_destroy`, `user_add_to_group` and `user_remove_from_group`. +Your GitLab instance can perform HTTP POST requests on the following events: + +- `project_create` +- `project_destroy` +- `project_rename` +- `project_transfer` +- `project_update` +- `user_add_to_team` +- `user_remove_from_team` +- `user_create` +- `user_destroy` +- `user_rename` +- `key_create` +- `key_destroy` +- `group_create` +- `group_destroy` +- `group_rename` +- `user_add_to_group` +- `user_remove_from_group` The triggers for most of these are self-explanatory, but `project_update` and `project_rename` deserve some clarification: `project_update` is fired any time an attribute of a project is changed (name, description, tags, etc.) *unless* the `path` attribute is also changed. In that case, a `project_rename` is triggered instead (so that, for instance, if all you care about is the repo URL, you can just listen for `project_rename`). @@ -72,6 +90,9 @@ X-Gitlab-Event: System Hook } ``` +Note that `project_rename` is not triggered if the namespace changes. +Please refer to `group_rename` and `user_rename` for that case. + **Project transferred:** ```json @@ -175,6 +196,21 @@ X-Gitlab-Event: System Hook } ``` +**User renamed:** + +```json +{ + "event_name": "user_rename", + "created_at": "2017-11-01T11:21:04Z", + "updated_at": "2017-11-01T14:04:47Z", + "name": "new-name", + "email": "best-email@example.tld", + "user_id": 58, + "username": "new-exciting-name", + "old_username": "old-boring-name" +} +``` + **Key added** ```json @@ -209,13 +245,15 @@ X-Gitlab-Event: System Hook "updated_at": "2012-07-21T07:38:22Z", "event_name": "group_create", "name": "StoreCloud", - "owner_email": "johnsmith@gmail.com", - "owner_name": "John Smith", + "owner_email": null, + "owner_name": null, "path": "storecloud", "group_id": 78 } ``` +`owner_name` and `owner_email` are always `null`. Please see https://gitlab.com/gitlab-org/gitlab-ce/issues/39675. + **Group removed:** ```json @@ -224,13 +262,35 @@ X-Gitlab-Event: System Hook "updated_at": "2012-07-21T07:38:22Z", "event_name": "group_destroy", "name": "StoreCloud", - "owner_email": "johnsmith@gmail.com", - "owner_name": "John Smith", + "owner_email": null, + "owner_name": null, "path": "storecloud", "group_id": 78 } ``` +`owner_name` and `owner_email` are always `null`. Please see https://gitlab.com/gitlab-org/gitlab-ce/issues/39675. + +**Group renamed:** + +```json +{ + "event_name": "group_rename", + "created_at": "2017-10-30T15:09:00Z", + "updated_at": "2017-11-01T10:23:52Z", + "name": "Better Name", + "path": "better-name", + "full_path": "parent-group/better-name", + "group_id": 64, + "owner_name": null, + "owner_email": null, + "old_path": "old-name", + "old_full_path": "parent-group/old-name" +} +``` + +`owner_name` and `owner_email` are always `null`. Please see https://gitlab.com/gitlab-org/gitlab-ce/issues/39675. + **New Group Member:** ```json diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md index 042cde3f01e..1cfdabac248 100644 --- a/doc/topics/autodevops/index.md +++ b/doc/topics/autodevops/index.md @@ -144,6 +144,12 @@ has a `.gitlab-ci.yml` or not: All you need to do is remove your existing `.gitlab-ci.yml`, and you can even do that in a branch to test Auto DevOps before committing to `master`. +NOTE: **Note:** +If you are a GitLab Administrator, you can enable Auto DevOps instance wide +in **Admin Area > Settings > Continuous Integration and Deployment**. Doing that, +all the projects that haven't explicitly set an option will have Auto DevOps +enabled by default. + ## Stages of Auto DevOps The following sections describe the stages of Auto DevOps. Read them carefully diff --git a/lib/gitlab/performance_bar/peek_query_tracker.rb b/lib/gitlab/performance_bar/peek_query_tracker.rb index 69e117f1da9..f2825db59ae 100644 --- a/lib/gitlab/performance_bar/peek_query_tracker.rb +++ b/lib/gitlab/performance_bar/peek_query_tracker.rb @@ -36,7 +36,7 @@ module Gitlab end def track_query(raw_query, bindings, start, finish) - duration = finish - start + duration = (finish - start) * 1000.0 query_info = { duration: duration.round(3), sql: raw_query } PEEK_DB_CLIENT.query_details << query_info diff --git a/lib/gitlab/sherlock/transaction.rb b/lib/gitlab/sherlock/transaction.rb index 3489fb251b6..400a552bf99 100644 --- a/lib/gitlab/sherlock/transaction.rb +++ b/lib/gitlab/sherlock/transaction.rb @@ -89,7 +89,9 @@ module Gitlab ActiveSupport::Notifications.subscribe('sql.active_record') do |_, start, finish, _, data| next unless same_thread? - track_query(data[:sql].strip, data[:binds], start, finish) + unless data.fetch(:cached, data[:name] == 'CACHE') + track_query(data[:sql].strip, data[:binds], start, finish) + end end end diff --git a/spec/controllers/concerns/lfs_request_spec.rb b/spec/controllers/concerns/lfs_request_spec.rb new file mode 100644 index 00000000000..33b23db302a --- /dev/null +++ b/spec/controllers/concerns/lfs_request_spec.rb @@ -0,0 +1,50 @@ +require 'spec_helper' + +describe LfsRequest do + include ProjectForksHelper + + controller(Projects::GitHttpClientController) do + # `described_class` is not available in this context + include LfsRequest # rubocop:disable RSpec/DescribedClass + + def show + storage_project + + render nothing: true + end + + def project + @project ||= Project.find(params[:id]) + end + + def download_request? + true + end + + def ci? + false + end + end + + let(:project) { create(:project, :public) } + + before do + stub_lfs_setting(enabled: true) + end + + describe '#storage_project' do + it 'assigns the project as storage project' do + get :show, id: project.id + + expect(assigns(:storage_project)).to eq(project) + end + + it 'assigns the source of a forked project' do + forked_project = fork_project(project) + + get :show, id: forked_project.id + + expect(assigns(:storage_project)).to eq(project) + end + end +end diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb index 9611f4d3869..6f916078b1a 100644 --- a/spec/features/dashboard/todos/todos_spec.rb +++ b/spec/features/dashboard/todos/todos_spec.rb @@ -52,7 +52,7 @@ feature 'Dashboard Todos' do end it 'updates todo count' do - expect(page).to have_content 'To do 0' + expect(page).to have_content 'Todos 0' expect(page).to have_content 'Done 1' end @@ -81,7 +81,7 @@ feature 'Dashboard Todos' do end it 'updates todo count' do - expect(page).to have_content 'To do 1' + expect(page).to have_content 'Todos 1' expect(page).to have_content 'Done 0' end end @@ -200,7 +200,7 @@ feature 'Dashboard Todos' do end it 'updates todo count' do - expect(page).to have_content 'To do 1' + expect(page).to have_content 'Todos 1' expect(page).to have_content 'Done 0' end end @@ -256,7 +256,7 @@ feature 'Dashboard Todos' do end it 'shows "All done" message!' do - expect(page).to have_content 'To do 0' + expect(page).to have_content 'Todos 0' expect(page).to have_content "You're all done!" expect(page).not_to have_selector('.gl-pagination') end @@ -283,7 +283,7 @@ feature 'Dashboard Todos' do it 'updates todo count' do mark_all_and_undo - expect(page).to have_content 'To do 2' + expect(page).to have_content 'Todos 2' expect(page).to have_content 'Done 0' end diff --git a/spec/features/projects/settings/forked_project_settings_spec.rb b/spec/features/projects/settings/forked_project_settings_spec.rb new file mode 100644 index 00000000000..28954a4fb40 --- /dev/null +++ b/spec/features/projects/settings/forked_project_settings_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +feature 'Settings for a forked project', :js do + include ProjectForksHelper + let(:user) { create(:user) } + let(:original_project) { create(:project) } + let(:forked_project) { fork_project(original_project, user) } + + before do + original_project.add_master(user) + forked_project.add_master(user) + sign_in(user) + end + + shared_examples 'project settings for a forked projects' do + it 'allows deleting the link to the forked project' do + visit edit_project_path(forked_project) + + click_button 'Remove fork relationship' + + wait_for_requests + + fill_in('confirm_name_input', with: forked_project.name) + click_button('Confirm') + + expect(page).to have_content('The fork relationship has been removed.') + expect(forked_project.reload.forked?).to be_falsy + end + end + + it_behaves_like 'project settings for a forked projects' + + context 'when the original project is deleted' do + before do + original_project.destroy! + end + + it_behaves_like 'project settings for a forked projects' + end +end diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb index ab8773b7ede..3106207811a 100644 --- a/spec/models/concerns/routable_spec.rb +++ b/spec/models/concerns/routable_spec.rb @@ -134,6 +134,7 @@ describe Group, 'Routable' do context 'with RequestStore active', :request_store do it 'does not load the route table more than once' do + group.expires_full_path_cache expect(group).to receive(:uncached_full_path).once.and_call_original 3.times { group.full_path } diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index e1be23541e8..f75de0a0d88 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -547,6 +547,15 @@ describe Environment do expect(environment.slug).to eq(original_slug) end + + it "regenerates the slug if nil" do + environment = build(:environment, slug: nil) + + new_slug = environment.slug + + expect(new_slug).not_to be_nil + expect(environment.slug).to eq(new_slug) + end end describe '#generate_slug' do @@ -583,6 +592,12 @@ describe Environment do it 'returns a path that uses the slug and does not have spaces' do expect(environment.ref_path).to start_with('refs/environments/staging-review-1-') end + + it "doesn't change when the slug is nil initially" do + environment.slug = nil + + expect(environment.ref_path).to eq(environment.ref_path) + end end describe '#external_url_for' do diff --git a/spec/models/fork_network_spec.rb b/spec/models/fork_network_spec.rb index 605ccd6db06..a43baf1820a 100644 --- a/spec/models/fork_network_spec.rb +++ b/spec/models/fork_network_spec.rb @@ -24,6 +24,16 @@ describe ForkNetwork do end end + describe '#merge_requests' do + it 'finds merge requests within the fork network' do + project = create(:project) + forked_project = fork_project(project) + merge_request = create(:merge_request, source_project: forked_project, target_project: project) + + expect(project.fork_network.merge_requests).to include(merge_request) + end + end + context 'for a deleted project' do it 'keeps the fork network' do project = create(:project, :public) diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index f36d6eeb327..0e1a7fdce0b 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -488,6 +488,47 @@ describe Group do end end + describe '#path_changed_hook' do + let(:system_hook_service) { SystemHooksService.new } + + context 'for a new group' do + let(:group) { build(:group) } + + before do + expect(group).to receive(:system_hook_service).and_return(system_hook_service) + end + + it 'does not trigger system hook' do + expect(system_hook_service).to receive(:execute_hooks_for).with(group, :create) + + group.save! + end + end + + context 'for an existing group' do + let(:group) { create(:group, path: 'old-path') } + + context 'when the path is changed' do + let(:new_path) { 'very-new-path' } + + it 'triggers the rename system hook' do + expect(group).to receive(:system_hook_service).and_return(system_hook_service) + expect(system_hook_service).to receive(:execute_hooks_for).with(group, :rename) + + group.update_attributes!(path: new_path) + end + end + + context 'when the path is not changed' do + it 'does not trigger system hook' do + expect(group).not_to receive(:system_hook_service) + + group.update_attributes!(name: 'new name') + end + end + end + end + describe '#secret_variables_for' do let(:project) { create(:project, group: group) } diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index ed6e42d476e..e8588975118 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1923,6 +1923,20 @@ describe Project do expect(forked_project.in_fork_network_of?(other_project)).to be_falsy end end + + describe '#fork_source' do + let!(:second_fork) { fork_project(forked_project) } + + it 'returns the direct source if it exists' do + expect(second_fork.fork_source).to eq(forked_project) + end + + it 'returns the root of the fork network when the directs source was deleted' do + forked_project.destroy + + expect(second_fork.fork_source).to eq(project) + end + end end describe '#pushes_since_gc' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index fb03e320734..e0896d64c8f 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -2217,6 +2217,42 @@ describe User do end end + describe '#username_changed_hook' do + context 'for a new user' do + let(:user) { build(:user) } + + it 'does not trigger system hook' do + expect(user).not_to receive(:system_hook_service) + + user.save! + end + end + + context 'for an existing user' do + let(:user) { create(:user, username: 'old-username') } + + context 'when the username is changed' do + let(:new_username) { 'very-new-name' } + + it 'triggers the rename system hook' do + system_hook_service = SystemHooksService.new + expect(system_hook_service).to receive(:execute_hooks_for).with(user, :rename) + expect(user).to receive(:system_hook_service).and_return(system_hook_service) + + user.update_attributes!(username: new_username) + end + end + + context 'when the username is not changed' do + it 'does not trigger system hook' do + expect(user).not_to receive(:system_hook_service) + + user.update_attributes!(email: 'asdf@asdf.com') + end + end + end + end + describe '#sync_attribute?' do let(:user) { described_class.new } diff --git a/spec/services/applications/create_service_spec.rb b/spec/services/applications/create_service_spec.rb new file mode 100644 index 00000000000..47a2a9d6403 --- /dev/null +++ b/spec/services/applications/create_service_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe ::Applications::CreateService do + let(:user) { create(:user) } + let(:params) { attributes_for(:application) } + let(:request) { ActionController::TestRequest.new(remote_ip: '127.0.0.1') } + + subject { described_class.new(user, params) } + + it 'creates an application' do + expect { subject.execute(request) }.to change { Doorkeeper::Application.count }.by(1) + end +end diff --git a/spec/services/projects/unlink_fork_service_spec.rb b/spec/services/projects/unlink_fork_service_spec.rb index 50d3a4ec982..2bba71fef4f 100644 --- a/spec/services/projects/unlink_fork_service_spec.rb +++ b/spec/services/projects/unlink_fork_service_spec.rb @@ -12,6 +12,9 @@ describe Projects::UnlinkForkService do context 'with opened merge request on the source project' do let(:merge_request) { create(:merge_request, source_project: forked_project, target_project: fork_link.forked_from_project) } + let(:merge_request2) { create(:merge_request, source_project: forked_project, target_project: fork_project(project)) } + let(:merge_request_in_fork) { create(:merge_request, source_project: forked_project, target_project: forked_project) } + let(:mr_close_service) { MergeRequests::CloseService.new(forked_project, user) } before do @@ -22,9 +25,14 @@ describe Projects::UnlinkForkService do it 'close all pending merge requests' do expect(mr_close_service).to receive(:execute).with(merge_request) + expect(mr_close_service).to receive(:execute).with(merge_request2) subject.execute end + + it 'does not close merge requests for the project being unlinked' do + expect(mr_close_service).not_to receive(:execute).with(merge_request_in_fork) + end end it 'remove fork relation' do @@ -53,4 +61,14 @@ describe Projects::UnlinkForkService do expect(source.forks_count).to be_zero end + + context 'when the original project was deleted' do + it 'does not fail when the original project is deleted' do + source = forked_project.forked_from_project + source.destroy + forked_project.reload + + expect { subject.execute }.not_to raise_error + end + end end diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb index 8f7aea533dc..46cd10cdc12 100644 --- a/spec/services/system_hooks_service_spec.rb +++ b/spec/services/system_hooks_service_spec.rb @@ -69,11 +69,48 @@ describe SystemHooksService do expect(data[:project_visibility]).to eq('private') end + + context 'group_rename' do + it 'contains old and new path' do + allow(group).to receive(:path_was).and_return('old-path') + + data = event_data(group, :rename) + + expect(data).to include(:event_name, :name, :created_at, :updated_at, :full_path, :path, :group_id, :old_path, :old_full_path) + expect(data[:path]).to eq(group.path) + expect(data[:full_path]).to eq(group.path) + expect(data[:old_path]).to eq(group.path_was) + expect(data[:old_full_path]).to eq(group.path_was) + end + + it 'contains old and new full_path for subgroup' do + subgroup = create(:group, parent: group) + allow(subgroup).to receive(:path_was).and_return('old-path') + + data = event_data(subgroup, :rename) + + expect(data[:full_path]).to eq(subgroup.full_path) + expect(data[:old_path]).to eq('old-path') + end + end + + context 'user_rename' do + it 'contains old and new username' do + allow(user).to receive(:username_was).and_return('old-username') + + data = event_data(user, :rename) + + expect(data).to include(:event_name, :name, :created_at, :updated_at, :email, :user_id, :username, :old_username) + expect(data[:username]).to eq(user.username) + expect(data[:old_username]).to eq(user.username_was) + end + end end context 'event names' do it { expect(event_name(user, :create)).to eq "user_create" } it { expect(event_name(user, :destroy)).to eq "user_destroy" } + it { expect(event_name(user, :rename)).to eq 'user_rename' } it { expect(event_name(project, :create)).to eq "project_create" } it { expect(event_name(project, :destroy)).to eq "project_destroy" } it { expect(event_name(project, :rename)).to eq "project_rename" } @@ -85,6 +122,7 @@ describe SystemHooksService do it { expect(event_name(key, :destroy)).to eq 'key_destroy' } it { expect(event_name(group, :create)).to eq 'group_create' } it { expect(event_name(group, :destroy)).to eq 'group_destroy' } + it { expect(event_name(group, :rename)).to eq 'group_rename' } it { expect(event_name(group_member, :create)).to eq 'user_add_to_group' } it { expect(event_name(group_member, :destroy)).to eq 'user_remove_from_group' } end diff --git a/spec/support/stub_configuration.rb b/spec/support/stub_configuration.rb index 4d448a55978..4ead78529c3 100644 --- a/spec/support/stub_configuration.rb +++ b/spec/support/stub_configuration.rb @@ -38,6 +38,10 @@ module StubConfiguration allow(Gitlab.config.backup).to receive_messages(to_settings(messages)) end + def stub_lfs_setting(messages) + allow(Gitlab.config.lfs).to receive_messages(to_settings(messages)) + end + def stub_storage_settings(messages) # Default storage is always required messages['default'] ||= Gitlab.config.repositories.storages.default diff --git a/vendor/assets/javascripts/peek.js b/vendor/assets/javascripts/peek.js index f7e77de34ff..6a341a3f0fe 100644 --- a/vendor/assets/javascripts/peek.js +++ b/vendor/assets/javascripts/peek.js @@ -1,5 +1,14 @@ +/* + * This is a modified version of https://github.com/peek/peek/blob/master/app/assets/javascripts/peek.js + * + * - Removed the dependency on jquery.tipsy + * - Removed the initializeTipsy and toggleBar functions + * - Customized updatePerformanceBar to handle SQL queries report specificities + * - Changed /peek/results to /-/peek/results + * - Removed the keypress, pjax:end, page:change, and turbolinks:load handlers + */ (function($) { - var fetchRequestResults, getRequestId, peekEnabled, toggleBar, updatePerformanceBar; + var fetchRequestResults, getRequestId, peekEnabled, updatePerformanceBar; getRequestId = function() { return $('#peek').data('request-id'); }; @@ -41,22 +50,6 @@ }); return $(document).trigger('peek:render', [getRequestId(), results]); }; - toggleBar = function(event) { - var wrapper; - if ($(event.target).is(':input')) { - return; - } - if (event.which === 96 && !event.metaKey) { - wrapper = $('#peek'); - if (wrapper.hasClass('disabled')) { - wrapper.removeClass('disabled'); - return document.cookie = "peek=true; path=/"; - } else { - wrapper.addClass('disabled'); - return document.cookie = "peek=false; path=/"; - } - } - }; fetchRequestResults = function() { return $.ajax('/-/peek/results', { data: { @@ -68,7 +61,6 @@ error: function(xhr, textStatus, error) {} }); }; - $(document).on('keypress', toggleBar); $(document).on('peek:update', fetchRequestResults); return $(function() { if (peekEnabled()) { |