diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue
index 795db42d1e3..53c893e0734 100644
--- a/app/assets/javascripts/boards/components/board_card.vue
+++ b/app/assets/javascripts/boards/components/board_card.vue
@@ -54,7 +54,7 @@ export default {
if (e.target.closest('.js-no-trigger')) return;
const isMultiSelect = e.ctrlKey || e.metaKey;
- if (isMultiSelect) {
+ if (isMultiSelect && gon?.features?.boardMultiSelect) {
this.toggleBoardItemMultiSelection(this.item);
} else {
this.toggleBoardItem({ boardItem: this.item });
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index f83ba89daae..2ec2df4b817 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -45,6 +45,7 @@ input[type='checkbox']:hover {
margin: 0 8px;
form {
+ display: block;
margin: 0;
padding: 4px;
width: $search-input-width;
diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss
index 9f7a8860e4d..79c5b24c041 100644
--- a/app/assets/stylesheets/startup/startup-dark.scss
+++ b/app/assets/stylesheets/startup/startup-dark.scss
@@ -1,4 +1,24 @@
+// DO NOT EDIT! This is auto-generated from "yarn run generate:startup_css"
+// Please see the feedback issue for more details and help:
+// https://gitlab.com/gitlab-org/gitlab/-/issues/331812
@charset "UTF-8";
+body.gl-dark {
+ --gray-50: #303030;
+ --gray-100: #404040;
+ --gray-200: #525252;
+ --gray-950: #fff;
+ --green-100: #0d532a;
+ --green-400: #108548;
+ --green-700: #91d4a8;
+ --blue-200: #0b5cad;
+ --blue-400: #1f75cb;
+ --orange-400: #ab6100;
+ --gl-text-color: #fafafa;
+ --border-color: #4f4f4f;
+}
+:root {
+ --white: #333;
+}
*,
*::before,
*::after {
@@ -8,68 +28,46 @@ html {
font-family: sans-serif;
line-height: 1.15;
}
- header, nav, section {
+aside,
+header,
+nav {
display: block;
}
body {
margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans", Ubuntu, Cantarell, "Helvetica Neue", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ "Noto Sans", Ubuntu, Cantarell, "Helvetica Neue", sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #fafafa;
text-align: left;
- background-color: #2e2e2e;
+ background-color: #1f1f1f;
}
-h1, h2, h3 {
+h1 {
margin-top: 0;
margin-bottom: 0.25rem;
}
-p {
- margin-top: 0;
- margin-bottom: 1rem;
-}
-
ul {
margin-top: 0;
margin-bottom: 1rem;
}
-
ul ul {
margin-bottom: 0;
}
-
strong {
font-weight: bolder;
}
-sub {
- position: relative;
- font-size: 75%;
- line-height: 0;
- vertical-align: baseline;
-}
-sub {
- bottom: -.25em;
-}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
-a:not([href]) {
+a:not([href]):not([class]) {
color: inherit;
text-decoration: none;
}
-pre,
-code {
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
- font-size: 1em;
-}
-pre {
- margin-top: 0;
- margin-bottom: 1rem;
- overflow: auto;
-}
img {
vertical-align: middle;
border-style: none;
@@ -78,18 +76,11 @@ svg {
overflow: hidden;
vertical-align: middle;
}
-table {
- border-collapse: collapse;
-}
-th {
- text-align: inherit;
-}
button {
border-radius: 0;
}
input,
-button,
-textarea {
+button {
margin: 0;
font-family: inherit;
font-size: inherit;
@@ -102,21 +93,20 @@ input {
button {
text-transform: none;
}
+[role="button"] {
+ cursor: pointer;
+}
button:not(:disabled),
[type="button"]:not(:disabled),
-[type="reset"]:not(:disabled) {
+[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
-[type="reset"]::-moz-focus-inner {
+[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
-textarea {
- overflow: auto;
- resize: vertical;
-}
[type="search"] {
outline-offset: -2px;
}
@@ -130,75 +120,21 @@ template {
[hidden] {
display: none !important;
}
-h1, h2, h3,
-.h1, .h2, .h3 {
+h1,
+.h1 {
margin-bottom: 0.25rem;
font-weight: 600;
line-height: 1.2;
color: #fafafa;
}
-h1, .h1 {
+h1,
+.h1 {
font-size: 2.1875rem;
}
-h2, .h2 {
- font-size: 1.75rem;
-}
-h3, .h3 {
- font-size: 1.53125rem;
-}
.list-unstyled {
padding-left: 0;
list-style: none;
}
-code {
- font-size: 90%;
- color: #fff;
- word-wrap: break-word;
-}
-a > code {
- color: inherit;
-}
-pre {
- display: block;
- font-size: 90%;
- color: #fafafa;
-}
-pre code {
- font-size: inherit;
- color: inherit;
- word-break: normal;
-}
-.container {
- width: 100%;
- padding-right: 15px;
- padding-left: 15px;
- margin-right: auto;
- margin-left: auto;
-}
-
-@media (min-width: 576px) {
- .container {
- max-width: 540px;
- }
-}
-
-@media (min-width: 768px) {
- .container {
- max-width: 720px;
- }
-}
-
-@media (min-width: 992px) {
- .container {
- max-width: 960px;
- }
-}
-
-@media (min-width: 1200px) {
- .container {
- max-width: 1140px;
- }
-}
.container-fluid {
width: 100%;
padding-right: 15px;
@@ -206,48 +142,7 @@ pre code {
margin-right: auto;
margin-left: auto;
}
-
-@media (min-width: 576px) {
- .container {
- max-width: 540px;
- }
-}
-
-@media (min-width: 768px) {
- .container {
- max-width: 720px;
- }
-}
-
-@media (min-width: 992px) {
- .container {
- max-width: 960px;
- }
-}
-
-@media (min-width: 1200px) {
- .container {
- max-width: 1140px;
- }
-}
-.row {
- display: flex;
- flex-wrap: wrap;
- margin-right: -15px;
- margin-left: -15px;
-}
-.table {
- width: 100%;
- margin-bottom: 0.5rem;
- color: #fafafa;
-}
-.table th,
-.table td {
- padding: 0.75rem;
- vertical-align: top;
- border-top: 1px solid #4f4f4f;
-}
- .search form {
+.form-control {
display: block;
width: 100%;
height: 34px;
@@ -256,24 +151,27 @@ pre code {
font-weight: 400;
line-height: 1.5;
color: #fafafa;
- background-color: #4f4f4f;
+ background-color: #333;
background-clip: padding-box;
- border: 1px solid #4f4f4f;
+ border: 1px solid #404040;
border-radius: 0.25rem;
}
-
@media (prefers-reduced-motion: reduce) {
}
- .search form:-moz-focusring {
+.form-control:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #fafafa;
}
- .search form::placeholder {
- color: #ccc;
+.form-control::-ms-input-placeholder {
+ color: #bfbfbf;
opacity: 1;
}
- .search form:disabled {
- background-color: #2e2e2e;
+.form-control::placeholder {
+ color: #bfbfbf;
+ opacity: 1;
+}
+.form-control:disabled {
+ background-color: #303030;
opacity: 1;
}
.form-inline {
@@ -281,9 +179,8 @@ pre code {
flex-flow: row wrap;
align-items: center;
}
-
@media (min-width: 576px) {
- .form-inline .search form, .search .form-inline form {
+ .form-inline .form-control {
display: inline-block;
width: auto;
vertical-align: middle;
@@ -295,7 +192,7 @@ pre code {
color: #fafafa;
text-align: center;
vertical-align: middle;
- cursor: pointer;
+ -moz-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
@@ -304,26 +201,35 @@ pre code {
line-height: 20px;
border-radius: 0.25rem;
}
-
@media (prefers-reduced-motion: reduce) {
}
-.btn.disabled, .btn:disabled {
+.btn:disabled {
opacity: 0.65;
}
-a.btn.disabled {
+.btn:not(:disabled):not(.disabled) {
+ cursor: pointer;
+}
+.btn-link {
+ font-weight: 400;
+ color: #007bff;
+ text-decoration: none;
+}
+.btn-link:disabled {
+ color: #bfbfbf;
pointer-events: none;
}
.collapse:not(.show) {
display: none;
}
-
.dropdown {
position: relative;
}
- .dropdown-menu-toggle {
+.dropdown-toggle,
+.dropdown-menu-toggle {
white-space: nowrap;
}
- .dropdown-menu-toggle::after {
+.dropdown-toggle::after,
+.dropdown-menu-toggle::after {
display: inline-block;
margin-left: 0.255em;
vertical-align: 0.255em;
@@ -333,7 +239,8 @@ a.btn.disabled {
border-bottom: 0;
border-left: 0.3em solid transparent;
}
- .dropdown-menu-toggle:empty::after {
+.dropdown-toggle:empty::after,
+.dropdown-menu-toggle:empty::after {
margin-left: 0;
}
.dropdown-menu {
@@ -358,16 +265,18 @@ a.btn.disabled {
.dropdown-menu-right {
right: 0;
left: auto;
-}
- .divider {
- height: 0;
- margin: 4px 0;
- overflow: hidden;
- border-top: 1px solid #4f4f4f;
}
.dropdown-menu.show {
display: block;
}
+.dropdown-header {
+ display: block;
+ padding: 0.5rem 12px;
+ margin-bottom: 0;
+ font-size: 0.875rem;
+ color: #bfbfbf;
+ white-space: nowrap;
+}
.nav {
display: flex;
flex-wrap: wrap;
@@ -375,6 +284,10 @@ a.btn.disabled {
margin-bottom: 0;
list-style: none;
}
+.nav-link {
+ display: block;
+ padding: 0.5rem 1rem;
+}
.navbar {
position: relative;
display: flex;
@@ -383,7 +296,6 @@ a.btn.disabled {
justify-content: space-between;
padding: 0.25rem 0.5rem;
}
-.navbar .container,
.navbar .container-fluid {
display: flex;
flex-wrap: wrap;
@@ -397,6 +309,10 @@ a.btn.disabled {
margin-bottom: 0;
list-style: none;
}
+.navbar-nav .nav-link {
+ padding-right: 0;
+ padding-left: 0;
+}
.navbar-nav .dropdown-menu {
position: static;
float: none;
@@ -414,15 +330,12 @@ a.btn.disabled {
border: 1px solid transparent;
border-radius: 0.25rem;
}
-
@media (max-width: 575.98px) {
- .navbar-expand-sm > .container,
.navbar-expand-sm > .container-fluid {
padding-right: 0;
padding-left: 0;
}
}
-
@media (min-width: 576px) {
.navbar-expand-sm {
flex-flow: row nowrap;
@@ -434,7 +347,10 @@ a.btn.disabled {
.navbar-expand-sm .navbar-nav .dropdown-menu {
position: absolute;
}
- .navbar-expand-sm > .container,
+ .navbar-expand-sm .navbar-nav .nav-link {
+ padding-right: 0.5rem;
+ padding-left: 0.5rem;
+ }
.navbar-expand-sm > .container-fluid {
flex-wrap: nowrap;
}
@@ -454,7 +370,7 @@ a.btn.disabled {
word-wrap: break-word;
background-color: #333;
background-clip: border-box;
- border: 1px solid #4f4f4f;
+ border: 1px solid #404040;
border-radius: 0.25rem;
}
.badge {
@@ -468,7 +384,6 @@ a.btn.disabled {
vertical-align: baseline;
border-radius: 0.25rem;
}
-
@media (prefers-reduced-motion: reduce) {
}
.badge:empty {
@@ -483,9 +398,9 @@ a.btn.disabled {
padding-left: 0.6em;
border-radius: 10rem;
}
-.media {
- display: flex;
- align-items: flex-start;
+.badge-dark {
+ color: #303030;
+ background-color: #f0f0f0;
}
.close {
float: right;
@@ -494,55 +409,15 @@ a.btn.disabled {
line-height: 1;
color: #fff;
text-shadow: 0 1px 0 #333;
- opacity: .5;
+ opacity: 0.5;
}
button.close {
padding: 0;
background-color: transparent;
border: 0;
- appearance: none;
}
-a.close.disabled {
- pointer-events: none;
-}
-.modal-dialog {
- position: relative;
- width: auto;
- margin: 0.5rem;
- pointer-events: none;
-}
-
-@media (min-width: 576px) {
- .modal-dialog {
- max-width: 500px;
- margin: 1.75rem auto;
- }
-}
-.bg-transparent {
- background-color: transparent !important;
-}
-.border {
- border: 1px solid #4f4f4f !important;
-}
-.border-top {
- border-top: 1px solid #4f4f4f !important;
-}
-.border-right {
- border-right: 1px solid #4f4f4f !important;
-}
-.border-bottom {
- border-bottom: 1px solid #4f4f4f !important;
-}
-.border-left {
- border-left: 1px solid #4f4f4f !important;
-}
-.rounded {
- border-radius: 0.25rem !important;
-}
-.clearfix::after {
- display: block;
- clear: both;
- content: "";
+.rounded-circle {
+ border-radius: 50% !important;
}
.d-none {
display: none !important;
@@ -553,19 +428,19 @@ a.close.disabled {
.d-block {
display: block !important;
}
-
@media (min-width: 576px) {
.d-sm-none {
display: none !important;
}
}
-
@media (min-width: 768px) {
+ .d-md-none {
+ display: none !important;
+ }
.d-md-block {
display: block !important;
}
}
-
@media (min-width: 992px) {
.d-lg-none {
display: none !important;
@@ -574,15 +449,14 @@ a.close.disabled {
display: block !important;
}
}
-
@media (min-width: 1200px) {
+ .d-xl-none {
+ display: none !important;
+ }
.d-xl-block {
display: block !important;
}
}
-.flex-wrap {
- flex-wrap: wrap !important;
-}
.float-right {
float: right !important;
}
@@ -603,15 +477,13 @@ a.close.disabled {
.text-nowrap {
white-space: nowrap !important;
}
-.visible {
- visibility: visible !important;
-}
- .search form.focus {
- color: #fafafa;
- background-color: #4f4f4f;
- border-color: #80bdff;
- outline: 0;
- box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
+@keyframes gl-spinner-rotate {
+ 0% {
+ transform: rotate(0);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
}
.gl-badge {
display: inline-flex;
@@ -623,49 +495,147 @@ a.close.disabled {
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
- outline: none;
}
-body, .search form,
+.gl-badge.sm {
+ padding-top: 0;
+ padding-bottom: 0;
+}
+.gl-badge.badge-muted {
+ background-color: #303030;
+ color: #999;
+}
+a.gl-badge.badge-muted.active,
+a.gl-badge.badge-muted:active {
+ color: #f0f0f0;
+ background-color: #404040;
+}
+.gl-new-dropdown .dropdown-menu {
+ background-color: #333;
+ border-width: 1px;
+ border-color: #525252;
+ margin-top: 0.25rem;
+ margin-bottom: 0.25rem;
+ padding: 0;
+ border-radius: 0.25rem;
+ box-shadow: 0 2px 4px 0 rgba(255, 255, 255, 0.1);
+ width: 15rem;
+}
+.gl-new-dropdown .dropdown-menu li {
+ padding: 0;
+}
+.gl-new-dropdown .dropdown-toggle::after,
+.gl-new-dropdown .dropdown-menu-toggle::after {
+ display: none;
+}
+.gl-new-dropdown .dropdown-toggle.gl-button,
+.gl-new-dropdown .gl-button.dropdown-menu-toggle {
+ padding-right: 0.5rem;
+}
+.gl-new-dropdown.dropdown .gl-button .dropdown-chevron,
+.gl-new-dropdown.dropdown .dropdown-chevron {
+ margin-left: 0.25rem;
+ margin-right: 0;
+}
+.gl-new-dropdown .dropdown-icon {
+ margin-right: 0.25rem;
+}
+.gl-spinner-container {
+ line-height: 0;
+ text-align: center;
+}
+.gl-spinner {
+ position: relative;
+ display: inline-flex;
+ border-radius: 50%;
+ border-style: solid;
+ margin-left: auto;
+ margin-right: auto;
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 0.875rem;
+ animation-name: gl-spinner-rotate;
+ animation-duration: 0.6s;
+ animation-timing-function: linear;
+ animation-iteration-count: infinite;
+ width: 1rem;
+ height: 1rem;
+ border-width: 2px;
+ transform-origin: 50% 50% calc((1rem / 2) + 2px);
+ border-color: rgba(219, 219, 219, 0.25);
+ border-top-color: #dbdbdb;
+}
+.gl-spinner.gl-spinner-md {
+ width: 1.5rem;
+ height: 1.5rem;
+ border-width: 3px;
+ transform-origin: 50% 50% calc((1.5rem / 2) + 3px);
+}
+.gl-button {
+ display: inline-flex;
+}
+.gl-button.gl-button {
+ border-width: 0;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+ background-color: transparent;
+ line-height: 1rem;
+ color: #fafafa;
+ fill: currentColor;
+ box-shadow: inset 0 0 0 1px #525252;
+ justify-content: center;
+ align-items: center;
+ font-size: 0.875rem;
+ border-radius: 0.25rem;
+}
+.gl-button.gl-button.btn-default {
+ background-color: #333;
+}
+.gl-button.gl-button.btn-default:active,
+.gl-button.gl-button.btn-default.active {
+ box-shadow: inset 0 0 0 2px #bfbfbf, 0 0 0 1px rgba(51, 51, 51, 0.4),
+ 0 0 0 4px rgba(66, 143, 220, 0.48);
+ outline: none;
+ background-color: #404040;
+}
+.gl-button.gl-button.btn-link {
+ background-color: transparent;
+ border-width: 0;
+ font-size: 0.875rem;
+ line-height: 1rem;
+ color: #428fdc;
+ padding-top: 0;
+ padding-bottom: 0;
+ padding-left: 0;
+ padding-right: 0;
+ box-shadow: none;
+}
+.gl-button.gl-button.btn-link:active {
+ color: #9dc7f1;
+ text-decoration: underline;
+}
+body,
+.form-control,
.search form {
font-size: 0.875rem;
}
button,
-html [type='button'],
-[type='reset'],
-[role='button'] {
+html [type="button"],
+[type="submit"],
+[role="button"] {
cursor: pointer;
}
h1,
-.h1,
-h2,
-.h2,
-h3,
-.h3 {
+.h1 {
margin-top: 20px;
margin-bottom: 10px;
}
-input[type='file'] {
- line-height: 1;
-}
-
strong {
font-weight: bold;
}
a {
- color: #418cd8;
-}
-code {
- padding: 2px 4px;
- color: #fff;
- background-color: #2e2e2e;
- border-radius: 4px;
-}
-.code > code {
- background-color: inherit;
- padding: unset;
-}
-table {
- border-spacing: 0;
+ color: #63a6e9;
}
.hidden {
display: none !important;
@@ -674,7 +644,8 @@ table {
.hide {
display: none;
}
- .dropdown-menu-toggle::after {
+.dropdown-toggle::after,
+.dropdown-menu-toggle::after {
display: none;
}
.badge:not(.gl-badge) {
@@ -684,13 +655,16 @@ table {
font-weight: 400;
display: inline-block;
}
-pre code {
- white-space: pre-wrap;
+.divider {
+ height: 0;
+ margin: 4px 0;
+ overflow: hidden;
+ border-top: 1px solid #404040;
}
.toggle-sidebar-button .collapse-text,
.toggle-sidebar-button .icon-chevron-double-lg-left,
.toggle-sidebar-button .icon-chevron-double-lg-right {
- color: #bababa;
+ color: #999;
}
svg {
vertical-align: baseline;
@@ -701,28 +675,20 @@ html {
body {
text-decoration-skip: ink;
}
-.content-wrapper {
- margin-top: 40px;
- padding-bottom: 100px;
-}
-.container {
- padding-top: 0;
- z-index: 5;
-}
-.container .content {
- margin: 0;
-}
-
-@media (max-width: 575.98px) {
- .container .content {
- margin-top: 20px;
+@keyframes spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
}
}
-
-@media (max-width: 575.98px) {
- .container .container .title {
- padding-left: 15px !important;
- }
+.gl-spinner {
+ animation-name: spin;
+ animation-iteration-count: infinite;
+ animation-timing-function: linear;
+ animation-duration: 1s;
+ transform-origin: 50% 50%;
}
.btn {
border-radius: 4px;
@@ -730,13 +696,13 @@ body {
font-weight: 400;
padding: 6px 10px;
background-color: #333;
- border-color: #4f4f4f;
+ border-color: #404040;
color: #fafafa;
color: #fafafa;
white-space: nowrap;
}
-.btn:active, .btn.active {
- box-shadow: rgba(0, 0, 0, 0.16);
+.btn:active,
+.btn.active {
background-color: #444;
border-color: #fafafa;
color: #fafafa;
@@ -745,64 +711,35 @@ body {
height: 15px;
width: 15px;
}
-.btn svg:not(:last-child),
-.btn .fa:not(:last-child) {
+.btn svg:not(:last-child) {
margin-right: 5px;
}
+.btn-link {
+ padding: 0;
+ background-color: transparent;
+ color: #63a6e9;
+ font-weight: normal;
+ border-radius: 0;
+ border-color: transparent;
+ border-width: 0;
+}
.badge.badge-pill:not(.gl-badge) {
font-weight: 400;
- background-color: rgba(0, 0, 0, 0.07);
- color: #dfdfdf;
+ background-color: rgba(255, 255, 255, 0.07);
+ color: #dbdbdb;
vertical-align: baseline;
}
-.hint {
- font-style: italic;
- color: #707070;
-}
-.bold {
- font-weight: 600;
-}
-pre.wrap {
- word-break: break-word;
- white-space: pre-wrap;
-}
-table a code {
- position: relative;
- top: -2px;
- margin-right: 3px;
-}
-.loading {
- margin: 20px auto;
- height: 40px;
- color: #dfdfdf;
- font-size: 32px;
- text-align: center;
-}
-.highlight {
- text-shadow: none;
-}
.chart {
overflow: hidden;
height: 220px;
}
-.break-word {
- word-wrap: break-word;
-}
-.center {
- text-align: center;
-}
-.block {
- display: block;
-}
-.flex {
- display: flex;
-}
-.flex-grow {
- flex-grow: 1;
-}
.dropdown {
position: relative;
}
+.dropdown.gl-new-dropdown button.dropdown-toggle,
+.dropdown.gl-new-dropdown button.dropdown-menu-toggle {
+ display: inline-flex;
+}
.show.dropdown .dropdown-menu {
transform: translateY(0);
display: block;
@@ -810,47 +747,57 @@ table a code {
max-height: 312px;
overflow-y: auto;
}
-
+.show.dropdown .dropdown-menu.dropdown-extended-height {
+ max-height: 400px;
+}
@media (max-width: 575.98px) {
.show.dropdown .dropdown-menu {
width: 100%;
}
}
- .show.dropdown .dropdown-menu-toggle,
+.show.dropdown .dropdown-menu.frequent-items-dropdown-menu {
+ padding: 0;
+ overflow-y: initial;
+ max-height: initial;
+}
+.show.dropdown .dropdown-toggle,
+.show.dropdown .dropdown-menu-toggle,
.show.dropdown .dropdown-menu-toggle {
border-color: #c4c4c4;
}
-.show.dropdown [data-toggle='dropdown'] {
+.show.dropdown [data-toggle="dropdown"] {
outline: 0;
}
.search-input-container .dropdown-menu {
margin-top: 11px;
}
- .dropdown-menu-toggle {
+.dropdown-toggle,
+.dropdown-menu-toggle {
padding: 6px 8px 6px 10px;
background-color: #333;
color: #fafafa;
font-size: 14px;
text-align: left;
- border: 1px solid #4f4f4f;
+ border: 1px solid #404040;
border-radius: 0.25rem;
white-space: nowrap;
}
- .no-outline.dropdown-menu-toggle {
+.dropdown-toggle.no-outline,
+.no-outline.dropdown-menu-toggle {
outline: 0;
}
- .dropdown-menu-toggle .fa {
- color: #c4c4c4;
-}
-.dropdown-menu-toggle {
+.dropdown-menu-toggle.dropdown-menu-toggle {
+ justify-content: flex-start;
+ overflow: hidden;
padding-right: 25px;
position: relative;
- width: 160px;
text-overflow: ellipsis;
- overflow: hidden;
+ width: 160px;
}
-.dropdown-menu-toggle .fa {
+.dropdown-menu-toggle.dropdown-menu-toggle .gl-spinner {
position: absolute;
+ top: 9px;
+ right: 8px;
}
.dropdown-menu {
display: none;
@@ -866,7 +813,7 @@ table a code {
font-weight: 400;
padding: 8px 0;
background-color: #333;
- border: 1px solid #4f4f4f;
+ border: 1px solid #404040;
border-radius: 0.25rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
@@ -881,7 +828,9 @@ table a code {
padding: 0 1px;
}
.dropdown-menu li > a,
-.dropdown-menu li button {
+.dropdown-menu li button,
+.dropdown-menu li .gl-button.btn-link,
+.dropdown-menu li .menu-item {
background: transparent;
border: 0;
border-radius: 0;
@@ -901,7 +850,19 @@ table a code {
height: 1px;
margin: 0.25rem 0;
padding: 0;
- background-color: #4f4f4f;
+ background-color: #404040;
+}
+.dropdown-menu .dropdown-header {
+ color: #fff;
+ font-size: 13px;
+ font-weight: 600;
+ line-height: 16px;
+ padding: 8px 12px;
+}
+.dropdown-menu .dropdown-bold-header {
+ font-weight: 600;
+ line-height: 16px;
+ padding: 8px 12px;
}
.dropdown-menu .badge.badge-pill + span:not(.badge):not(.badge-pill) {
margin-right: 40px;
@@ -909,7 +870,6 @@ table a code {
.dropdown-select {
width: 300px;
}
-
@media (max-width: 767.98px) {
.dropdown-select {
width: 100%;
@@ -930,123 +890,96 @@ table a code {
background-color: rgba(51, 51, 51, 0.6);
font-size: 28px;
}
-.dropdown-loading .fa {
- position: absolute;
- top: 50%;
- left: 50%;
- margin-top: -14px;
- margin-left: -14px;
-}
-
@media (max-width: 575.98px) {
.navbar-gitlab li.dropdown {
position: static;
}
+ .navbar-gitlab li.dropdown.user-counter {
+ margin-left: 8px !important;
+ }
+ .navbar-gitlab li.dropdown.user-counter > a {
+ padding: 0 4px !important;
+ }
header.navbar-gitlab .dropdown .dropdown-menu {
width: 100%;
min-width: 100%;
}
}
-
+header.header-content .dropdown-menu.frequent-items-dropdown-menu {
+ padding: 0;
+}
+.frequent-items-dropdown-container {
+ display: flex;
+ flex-direction: row;
+ height: 20rem;
+}
+.frequent-items-dropdown-container.with-deprecated-styles {
+ width: 500px;
+ height: 354px;
+}
+.frequent-items-dropdown-container.with-deprecated-styles
+ .search-input-container {
+ position: relative;
+ padding: 4px 16px;
+}
+.frequent-items-dropdown-container.with-deprecated-styles
+ .search-input-container
+ .search-icon {
+ position: absolute;
+ top: 13px;
+ right: 25px;
+ color: #5e5e5e;
+}
+@media (max-width: 575.98px) {
+ .frequent-items-dropdown-container.with-deprecated-styles {
+ flex-direction: column;
+ width: 100%;
+ height: auto;
+ flex: 1;
+ }
+ .frequent-items-dropdown-container.with-deprecated-styles
+ .frequent-items-dropdown-sidebar,
+ .frequent-items-dropdown-container.with-deprecated-styles
+ .frequent-items-dropdown-content {
+ width: 100%;
+ }
+ .frequent-items-dropdown-container.with-deprecated-styles
+ .frequent-items-dropdown-sidebar {
+ border-bottom: 1px solid #404040;
+ border-right: 0;
+ }
+}
+.frequent-items-dropdown-container .frequent-items-dropdown-sidebar,
+.frequent-items-dropdown-container .frequent-items-dropdown-content {
+ padding-top: 0.5rem;
+}
+.frequent-items-dropdown-container .frequent-items-dropdown-sidebar {
+ width: 30%;
+ border-right: 1px solid #404040;
+}
+.frequent-items-dropdown-container .frequent-items-dropdown-content {
+ position: relative;
+ width: 70%;
+}
@media (max-width: 767.98px) {
.dropdown-menu-toggle {
width: 100%;
}
}
-textarea {
- resize: vertical;
-}
input {
border-radius: 0.25rem;
color: #fafafa;
- background-color: #4f4f4f;
+ background-color: #333;
}
- .search form {
+.form-control {
border-radius: 4px;
padding: 6px 10px;
}
- .search form::placeholder {
- color: #a7a7a7;
+.form-control::-ms-input-placeholder {
+ color: #868686;
}
-body.ui-indigo .navbar-gitlab {
- background-color: #292961;
-}
-body.ui-indigo .navbar-gitlab .navbar-collapse {
- color: #d1d1f0;
-}
-body.ui-indigo .navbar-gitlab .container-fluid .navbar-toggler {
- border-left: 1px solid #6868b9;
-}
-body.ui-indigo .navbar-gitlab .container-fluid .navbar-toggler svg {
- fill: #d1d1f0;
-}
-body.ui-indigo .navbar-gitlab .navbar-sub-nav > li.active > a,
-body.ui-indigo .navbar-gitlab .navbar-sub-nav > li.active > button, body.ui-indigo .navbar-gitlab .navbar-sub-nav > li.dropdown.show > a,
-body.ui-indigo .navbar-gitlab .navbar-sub-nav > li.dropdown.show > button,
-body.ui-indigo .navbar-gitlab .navbar-nav > li.active > a,
-body.ui-indigo .navbar-gitlab .navbar-nav > li.active > button,
-body.ui-indigo .navbar-gitlab .navbar-nav > li.dropdown.show > a,
-body.ui-indigo .navbar-gitlab .navbar-nav > li.dropdown.show > button {
- color: #292961;
- background-color: #333;
-}
-body.ui-indigo .navbar-gitlab .navbar-sub-nav {
- color: #d1d1f0;
-}
-body.ui-indigo .navbar-gitlab .nav > li {
- color: #d1d1f0;
-}
-body.ui-indigo .navbar-gitlab .nav > li > a.header-user-dropdown-toggle .header-user-avatar {
- border-color: #d1d1f0;
-}
-body.ui-indigo .navbar-gitlab .nav > li.active > a,
-body.ui-indigo .navbar-gitlab .nav > li.dropdown.show > a {
- color: #292961;
- background-color: #333;
-}
-body.ui-indigo .search form {
- background-color: rgba(209, 209, 240, 0.2);
-}
-body.ui-indigo .search .search-input::placeholder {
- color: rgba(209, 209, 240, 0.8);
-}
-body.ui-indigo .search .search-input-wrap .search-icon,
-body.ui-indigo .search .search-input-wrap .clear-icon {
- fill: rgba(209, 209, 240, 0.8);
-}
-body.ui-indigo .nav-sidebar li.active {
- box-shadow: inset 4px 0 0 #4b4ba3;
-}
-body.ui-indigo .nav-sidebar li.active > a {
- color: #393982;
-}
-body.ui-indigo .nav-sidebar li.active .nav-icon-container svg {
- fill: #393982;
-}
-body.ui-indigo .sidebar-top-level-items > li.active .badge.badge-pill {
- color: #393982;
-}
-body.gl-dark .logo-text svg {
- fill: #fafafa;
-}
-body.gl-dark .navbar-gitlab {
- background-color: #2e2e2e;
- box-shadow: 0 1px 0 0 var(--gray-100);
-}
-body.gl-dark .navbar-gitlab .navbar-sub-nav li.active > a,
-body.gl-dark .navbar-gitlab .navbar-sub-nav li.active > button,
-body.gl-dark .navbar-gitlab .navbar-sub-nav li.dropdown.show > a,
-body.gl-dark .navbar-gitlab .navbar-sub-nav li.dropdown.show > button,
-body.gl-dark .navbar-gitlab .navbar-nav li.active > a,
-body.gl-dark .navbar-gitlab .navbar-nav li.active > button,
-body.gl-dark .navbar-gitlab .navbar-nav li.dropdown.show > a,
-body.gl-dark .navbar-gitlab .navbar-nav li.dropdown.show > button {
- color: #fafafa;
- background-color: #707070;
-}
-body.gl-dark .navbar-gitlab .search form {
- background-color: #4f4f4f;
- box-shadow: inset 0 0 0 1px #4f4f4f;
+.form-control::placeholder {
+ color: #868686;
}
.navbar-gitlab {
padding: 0 16px;
@@ -1054,7 +987,6 @@ body.gl-dark .navbar-gitlab .search form {
margin-bottom: 0;
min-height: 40px;
border: 0;
- border-bottom: 1px solid #4f4f4f;
position: fixed;
top: 0;
left: 0;
@@ -1104,9 +1036,6 @@ body.gl-dark .navbar-gitlab .search form {
.navbar-gitlab .header-content .title img + .logo-text {
margin-left: 8px;
}
-.navbar-gitlab .header-content .title.wrap {
- white-space: normal;
-}
.navbar-gitlab .header-content .title a {
display: flex;
align-items: center;
@@ -1114,9 +1043,6 @@ body.gl-dark .navbar-gitlab .search form {
margin: 5px 2px 5px -8px;
border-radius: 4px;
}
-.navbar-gitlab .header-content .dropdown.open > a {
- border-bottom-color: #333;
-}
.navbar-gitlab .header-content .navbar-collapse > ul.nav > li:not(.d-none) {
margin: 0 2px;
}
@@ -1125,7 +1051,6 @@ body.gl-dark .navbar-gitlab .search form {
border-top: 0;
padding: 0;
}
-
@media (max-width: 575.98px) {
.navbar-gitlab .navbar-collapse {
flex: 1 1 auto;
@@ -1134,7 +1059,6 @@ body.gl-dark .navbar-gitlab .search form {
.navbar-gitlab .navbar-collapse .nav {
flex-wrap: nowrap;
}
-
@media (max-width: 575.98px) {
.navbar-gitlab .navbar-collapse .nav > li:not(.d-none) a {
margin-left: 0;
@@ -1157,7 +1081,6 @@ body.gl-dark .navbar-gitlab .search form {
text-align: center;
color: currentColor;
}
-
@media (max-width: 575.98px) {
.navbar-gitlab .container-fluid .navbar-nav {
display: flex;
@@ -1165,11 +1088,14 @@ body.gl-dark .navbar-gitlab .search form {
flex-direction: row;
}
}
-.navbar-gitlab .container-fluid .navbar-nav li .badge.badge-pill {
+.navbar-gitlab
+ .container-fluid
+ .navbar-nav
+ li
+ .badge.badge-pill:not(.merge-request-badge) {
box-shadow: none;
font-weight: 600;
}
-
@media (max-width: 575.98px) {
.navbar-gitlab .container-fluid .nav > li.header-user {
padding-left: 10px;
@@ -1181,7 +1107,6 @@ body.gl-dark .navbar-gitlab .search form {
padding: 6px 8px;
height: 32px;
}
-
@media (max-width: 575.98px) {
.navbar-gitlab .container-fluid .nav > li > a {
padding: 0;
@@ -1190,7 +1115,12 @@ body.gl-dark .navbar-gitlab .search form {
.navbar-gitlab .container-fluid .nav > li > a.header-user-dropdown-toggle {
margin-left: 2px;
}
-.navbar-gitlab .container-fluid .nav > li > a.header-user-dropdown-toggle .header-user-avatar {
+.navbar-gitlab
+ .container-fluid
+ .nav
+ > li
+ > a.header-user-dropdown-toggle
+ .header-user-avatar {
margin-right: 0;
}
.navbar-gitlab .container-fluid .nav > li .header-new-dropdown-toggle {
@@ -1211,7 +1141,9 @@ body.gl-dark .navbar-gitlab .search form {
height: 32px;
font-weight: 600;
}
+.navbar-sub-nav > li .top-nav-toggle,
.navbar-sub-nav > li > button,
+.navbar-nav > li .top-nav-toggle,
.navbar-nav > li > button {
background: transparent;
border: 0;
@@ -1224,6 +1156,11 @@ body.gl-dark .navbar-gitlab .search form {
display: flex;
margin: 0 0 0 6px;
}
+.navbar-sub-nav .dropdown-chevron {
+ position: relative;
+ top: -1px;
+ font-size: 10px;
+}
.caret-down,
.btn .caret-down {
top: 0;
@@ -1249,31 +1186,25 @@ body.gl-dark .navbar-gitlab .search form {
font-weight: 400;
margin-left: -6px;
font-size: 11px;
- color: #333;
+ color: var(--gray-950, #333);
padding: 0 5px;
line-height: 12px;
border-radius: 7px;
box-shadow: 0 1px 0 rgba(76, 78, 84, 0.2);
}
-.title-container .badge.badge-pill.green-badge,
-.navbar-nav .badge.badge-pill.green-badge {
- background-color: #1aaa55;
+.title-container .badge.badge-pill:not(.merge-request-badge).green-badge,
+.navbar-nav .badge.badge-pill:not(.merge-request-badge).green-badge {
+ background-color: var(--green-400, #108548);
}
-.title-container .badge.badge-pill.merge-requests-count,
-.navbar-nav .badge.badge-pill.merge-requests-count {
- background-color: #fca429;
+.title-container
+ .badge.badge-pill:not(.merge-request-badge).merge-requests-count,
+.navbar-nav .badge.badge-pill:not(.merge-request-badge).merge-requests-count {
+ background-color: var(--orange-400, #ab6100);
}
-.title-container .badge.badge-pill.todos-count,
-.navbar-nav .badge.badge-pill.todos-count {
- background-color: #1f78d1;
+.title-container .badge.badge-pill:not(.merge-request-badge).todos-count,
+.navbar-nav .badge.badge-pill:not(.merge-request-badge).todos-count {
+ background-color: var(--blue-400, #1f75cb);
}
-.title-container .canary-badge .badge,
-.navbar-nav .canary-badge .badge {
- font-size: 12px;
- line-height: 16px;
- padding: 0 0.5rem;
-}
-
@media (max-width: 575.98px) {
.navbar-gitlab .container-fluid {
font-size: 18px;
@@ -1300,7 +1231,7 @@ body.gl-dark .navbar-gitlab .search form {
}
.header-user.show .dropdown-menu {
margin-top: 4px;
- color: #fafafa;
+ color: var(--gl-text-color, #fafafa);
left: auto;
max-height: 445px;
}
@@ -1313,31 +1244,36 @@ body.gl-dark .navbar-gitlab .search form {
border-radius: 50%;
border: 1px solid #333;
}
-.media {
- display: flex;
- align-items: flex-start;
+.notification-dot {
+ background-color: #9e5400;
+ height: 12px;
+ width: 12px;
+ margin-top: -15px;
+ pointer-events: none;
+ visibility: hidden;
+}
+.top-nav-toggle .dropdown-icon {
+ margin-right: 0.5rem;
+}
+.top-nav-toggle .dropdown-chevron {
+ top: 0;
+}
+.tanuki-logo .tanuki-left-ear,
+.tanuki-logo .tanuki-right-ear,
+.tanuki-logo .tanuki-nose {
+ fill: #e24329;
+}
+.tanuki-logo .tanuki-left-eye,
+.tanuki-logo .tanuki-right-eye {
+ fill: #fc6d26;
+}
+.tanuki-logo .tanuki-left-cheek,
+.tanuki-logo .tanuki-right-cheek {
+ fill: #fca326;
}
.card {
margin-bottom: 16px;
}
-.content-wrapper {
- width: 100%;
-}
-.content-wrapper .container-fluid {
- padding: 0 16px;
-}
-
-@media (min-width: 768px) {
- .page-with-contextual-sidebar {
- padding-left: 50px;
- }
-}
-
-@media (min-width: 1200px) {
- .page-with-contextual-sidebar {
- padding-left: 220px;
- }
-}
.context-header {
position: relative;
margin-right: 2px;
@@ -1367,104 +1303,85 @@ body.gl-dark .navbar-gitlab .search form {
font-weight: normal;
font-size: 0.8em;
}
-.nav-sidebar {
+@media (min-width: 768px) {
+ body:not(.sidebar-refactoring) .page-with-contextual-sidebar {
+ padding-left: 50px;
+ }
+}
+@media (min-width: 1200px) {
+ body:not(.sidebar-refactoring) .page-with-contextual-sidebar {
+ padding-left: 220px;
+ }
+}
+body:not(.sidebar-refactoring) .nav-sidebar {
position: fixed;
z-index: 600;
width: 220px;
top: 40px;
bottom: 0;
left: 0;
- background-color: #2e2e2e;
- box-shadow: inset -1px 0 0 #4f4f4f;
+ background-color: #303030;
+ box-shadow: inset -1px 0 0 #404040;
transform: translate3d(0, 0, 0);
}
-
@media (min-width: 576px) and (max-width: 576px) {
- .nav-sidebar:not(.sidebar-collapsed-desktop) {
- box-shadow: inset -1px 0 0 #4f4f4f, 2px 1px 3px rgba(0, 0, 0, 0.1);
+ body:not(.sidebar-refactoring) .nav-sidebar:not(.sidebar-collapsed-desktop) {
+ box-shadow: inset -1px 0 0 #404040, 2px 1px 3px rgba(0, 0, 0, 0.1);
}
}
-.nav-sidebar.sidebar-collapsed-desktop {
- width: 50px;
-}
-.nav-sidebar.sidebar-collapsed-desktop .nav-sidebar-inner-scroll {
- overflow-x: hidden;
-}
-.nav-sidebar.sidebar-collapsed-desktop .badge.badge-pill:not(.fly-out-badge),
-.nav-sidebar.sidebar-collapsed-desktop .sidebar-context-title,
-.nav-sidebar.sidebar-collapsed-desktop .nav-item-name {
- border: 0;
- clip: rect(0, 0, 0, 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- white-space: nowrap;
- width: 1px;
-}
-.nav-sidebar.sidebar-collapsed-desktop .sidebar-top-level-items > li > a {
- min-height: 45px;
-}
-.nav-sidebar.sidebar-collapsed-desktop .fly-out-top-item {
- display: block;
-}
-.nav-sidebar.sidebar-collapsed-desktop .avatar-container {
- margin: 0 auto;
-}
-.nav-sidebar.sidebar-expanded-mobile {
- left: 0;
-}
-.nav-sidebar a {
+body:not(.sidebar-refactoring) .nav-sidebar a {
text-decoration: none;
}
-.nav-sidebar ul {
+body:not(.sidebar-refactoring) .nav-sidebar ul {
padding-left: 0;
list-style: none;
}
-.nav-sidebar li {
+body:not(.sidebar-refactoring) .nav-sidebar li {
white-space: nowrap;
}
-.nav-sidebar li a {
+body:not(.sidebar-refactoring) .nav-sidebar li a {
display: flex;
align-items: center;
padding: 12px 16px;
- color: #bababa;
+ color: #999;
}
-.nav-sidebar li .nav-item-name {
+body:not(.sidebar-refactoring) .nav-sidebar li .nav-item-name {
flex: 1;
}
-.nav-sidebar li.active > a {
+body:not(.sidebar-refactoring) .nav-sidebar li.active > a {
font-weight: 600;
}
-
@media (max-width: 767.98px) {
- .nav-sidebar {
+ body:not(.sidebar-refactoring) .nav-sidebar {
left: -220px;
}
}
-.nav-sidebar .nav-icon-container {
+body:not(.sidebar-refactoring) .nav-sidebar .nav-icon-container {
display: flex;
margin-right: 8px;
}
-.nav-sidebar .fly-out-top-item {
+body:not(.sidebar-refactoring) .nav-sidebar .fly-out-top-item {
display: none;
}
-.nav-sidebar svg {
+body:not(.sidebar-refactoring) .nav-sidebar svg {
height: 16px;
width: 16px;
}
-
@media (min-width: 768px) and (max-width: 1199px) {
- .nav-sidebar:not(.sidebar-expanded-mobile) {
+ body:not(.sidebar-refactoring) .nav-sidebar:not(.sidebar-expanded-mobile) {
width: 50px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .nav-sidebar-inner-scroll {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-sidebar-inner-scroll {
overflow-x: hidden;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .badge.badge-pill:not(.fly-out-badge),
- .nav-sidebar:not(.sidebar-expanded-mobile) .sidebar-context-title,
- .nav-sidebar:not(.sidebar-expanded-mobile) .nav-item-name {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .badge.badge-pill:not(.fly-out-badge),
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-item-name {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
@@ -1475,273 +1392,476 @@ body.gl-dark .navbar-gitlab .search form {
white-space: nowrap;
width: 1px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .sidebar-top-level-items > li > a {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-top-level-items
+ > li
+ > a {
min-height: 45px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .fly-out-top-item {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .fly-out-top-item {
display: block;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .avatar-container {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .avatar-container {
margin: 0 auto;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .context-header {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .context-header {
height: 60px;
width: 50px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .context-header a {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .context-header
+ a {
padding: 10px 4px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .sidebar-top-level-items > li .sidebar-sub-level-items:not(.flyout-list) {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-context-title {
+ border: 0;
+ clip: rect(0, 0, 0, 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+ }
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-top-level-items
+ > li
+ .sidebar-sub-level-items:not(.flyout-list) {
display: none;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .nav-icon-container {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-icon-container {
margin-right: 0;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button {
padding: 16px;
width: 49px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button .collapse-text,
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button .icon-chevron-double-lg-left {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .collapse-text,
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .icon-chevron-double-lg-left {
display: none;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button .icon-chevron-double-lg-right {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .icon-chevron-double-lg-right {
display: block;
margin: 0;
}
}
-.nav-sidebar-inner-scroll {
+body:not(.sidebar-refactoring) .nav-sidebar-inner-scroll {
height: 100%;
width: 100%;
overflow: auto;
}
-.sidebar-sub-level-items {
+body:not(.sidebar-refactoring) .sidebar-sub-level-items {
display: none;
padding-bottom: 8px;
}
-.sidebar-sub-level-items > li a {
+body:not(.sidebar-refactoring) .sidebar-sub-level-items > li a {
padding: 8px 16px 8px 40px;
}
-.sidebar-top-level-items {
+body:not(.sidebar-refactoring) .sidebar-top-level-items {
margin-bottom: 60px;
}
-
@media (min-width: 576px) {
- .sidebar-top-level-items > li > a {
+ body:not(.sidebar-refactoring) .sidebar-top-level-items > li > a {
margin-right: 1px;
}
}
-.sidebar-top-level-items > li .badge.badge-pill {
+body:not(.sidebar-refactoring) .sidebar-top-level-items > li .badge.badge-pill {
background-color: rgba(255, 255, 255, 0.08);
- color: #bababa;
+ color: #999;
}
-.sidebar-top-level-items > li.active {
+body:not(.sidebar-refactoring) .sidebar-top-level-items > li.active {
background: rgba(255, 255, 255, 0.04);
}
-.sidebar-top-level-items > li.active > a {
+body:not(.sidebar-refactoring) .sidebar-top-level-items > li.active > a {
margin-left: 4px;
padding-left: 12px;
}
-.sidebar-top-level-items > li.active .badge.badge-pill {
+body:not(.sidebar-refactoring)
+ .sidebar-top-level-items
+ > li.active
+ .badge.badge-pill {
font-weight: 600;
}
-.sidebar-top-level-items > li.active .sidebar-sub-level-items:not(.is-fly-out-only) {
+body:not(.sidebar-refactoring)
+ .sidebar-top-level-items
+ > li.active
+ .sidebar-sub-level-items:not(.is-fly-out-only) {
display: block;
}
-.toggle-sidebar-button,
-.close-nav-button {
- width: 219px;
- position: fixed;
+body:not(.sidebar-refactoring) .toggle-sidebar-button,
+body:not(.sidebar-refactoring) .close-nav-button {
height: 48px;
- bottom: 0;
padding: 0 16px;
- background-color: #2e2e2e;
+ background-color: #303030;
border: 0;
- border-top: 1px solid #4f4f4f;
- color: #bababa;
+ color: #999;
display: flex;
align-items: center;
}
-.toggle-sidebar-button svg,
-.close-nav-button svg {
+body:not(.sidebar-refactoring) .toggle-sidebar-button,
+body:not(.sidebar-refactoring) .close-nav-button {
+ position: fixed;
+ bottom: 0;
+ width: 219px;
+ border-top: 1px solid #404040;
+}
+body:not(.sidebar-refactoring) .toggle-sidebar-button svg,
+body:not(.sidebar-refactoring) .close-nav-button svg {
margin-right: 8px;
}
-.toggle-sidebar-button .icon-chevron-double-lg-right,
-.close-nav-button .icon-chevron-double-lg-right {
+body:not(.sidebar-refactoring)
+ .toggle-sidebar-button
+ .icon-chevron-double-lg-right,
+body:not(.sidebar-refactoring) .close-nav-button .icon-chevron-double-lg-right {
display: none;
}
-.collapse-text {
+body:not(.sidebar-refactoring) .collapse-text {
white-space: nowrap;
overflow: hidden;
}
-.sidebar-collapsed-desktop .context-header {
- height: 60px;
- width: 50px;
-}
-.sidebar-collapsed-desktop .context-header a {
- padding: 10px 4px;
-}
-.sidebar-collapsed-desktop .sidebar-top-level-items > li .sidebar-sub-level-items:not(.flyout-list) {
- display: none;
-}
-.sidebar-collapsed-desktop .nav-icon-container {
- margin-right: 0;
-}
-.sidebar-collapsed-desktop .toggle-sidebar-button {
- padding: 16px;
- width: 49px;
-}
-.sidebar-collapsed-desktop .toggle-sidebar-button .collapse-text,
-.sidebar-collapsed-desktop .toggle-sidebar-button .icon-chevron-double-lg-left {
- display: none;
-}
-.sidebar-collapsed-desktop .toggle-sidebar-button .icon-chevron-double-lg-right {
- display: block;
- margin: 0;
-}
-.fly-out-top-item > a {
+body:not(.sidebar-refactoring) .fly-out-top-item > a {
display: flex;
}
-.fly-out-top-item .fly-out-badge {
+body:not(.sidebar-refactoring) .fly-out-top-item .fly-out-badge {
margin-left: 8px;
}
-.fly-out-top-item-name {
+body:not(.sidebar-refactoring) .fly-out-top-item-name {
flex: 1;
}
-.close-nav-button {
+body:not(.sidebar-refactoring) .close-nav-button {
display: none;
}
-
@media (max-width: 767.98px) {
- .close-nav-button {
+ body:not(.sidebar-refactoring) .close-nav-button {
display: flex;
}
- .toggle-sidebar-button {
+ body:not(.sidebar-refactoring) .toggle-sidebar-button {
display: none;
}
}
-table.table {
- margin-bottom: 16px;
+@media (min-width: 768px) {
+ body.sidebar-refactoring .page-with-contextual-sidebar {
+ padding-left: 50px;
+ }
}
-table.table .dropdown-menu a {
+@media (min-width: 1200px) {
+ body.sidebar-refactoring .page-with-contextual-sidebar {
+ padding-left: 220px;
+ }
+}
+body.sidebar-refactoring .nav-sidebar {
+ position: fixed;
+ z-index: 600;
+ width: 220px;
+ top: 40px;
+ bottom: 0;
+ left: 0;
+ background: linear-gradient(#cbbbf2, #8f4700);
+ box-shadow: inset -1px 0 0 #404040;
+ transform: translate3d(0, 0, 0);
+}
+@media (min-width: 576px) and (max-width: 576px) {
+ body.sidebar-refactoring .nav-sidebar:not(.sidebar-collapsed-desktop) {
+ box-shadow: inset -1px 0 0 #404040, 2px 1px 3px rgba(0, 0, 0, 0.1);
+ }
+}
+body.sidebar-refactoring .nav-sidebar a {
text-decoration: none;
}
-table.table .success,
-table.table .info {
- color: #333;
+body.sidebar-refactoring .nav-sidebar ul {
+ padding-left: 0;
+ list-style: none;
}
-table.table .success a:not(.btn),
-table.table .info a:not(.btn) {
- text-decoration: underline;
- color: #333;
+body.sidebar-refactoring .nav-sidebar li {
+ white-space: nowrap;
}
-pre {
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
+body.sidebar-refactoring .nav-sidebar li a {
+ display: flex;
+ align-items: center;
+ padding: 12px 16px;
+ color: #999;
+}
+body.sidebar-refactoring .nav-sidebar li .nav-item-name {
+ flex: 1;
+}
+body.sidebar-refactoring .nav-sidebar li.active > a {
+ font-weight: 600;
+}
+@media (max-width: 767.98px) {
+ body.sidebar-refactoring .nav-sidebar {
+ left: -220px;
+ }
+}
+body.sidebar-refactoring .nav-sidebar .nav-icon-container {
+ display: flex;
+ margin-right: 8px;
+}
+body.sidebar-refactoring .nav-sidebar .fly-out-top-item {
+ display: none;
+}
+body.sidebar-refactoring .nav-sidebar svg {
+ height: 16px;
+ width: 16px;
+}
+@media (min-width: 768px) and (max-width: 1199px) {
+ body.sidebar-refactoring .nav-sidebar:not(.sidebar-expanded-mobile) {
+ width: 50px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-sidebar-inner-scroll {
+ overflow-x: hidden;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .badge.badge-pill:not(.fly-out-badge),
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-item-name {
+ border: 0;
+ clip: rect(0, 0, 0, 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-top-level-items
+ > li
+ > a {
+ min-height: 45px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .fly-out-top-item {
+ display: block;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .avatar-container {
+ margin: 0 auto;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .context-header {
+ height: 60px;
+ width: 50px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .context-header
+ a {
+ padding: 10px 4px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-context-title {
+ border: 0;
+ clip: rect(0, 0, 0, 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-top-level-items
+ > li
+ .sidebar-sub-level-items:not(.flyout-list) {
+ display: none;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-icon-container {
+ margin-right: 0;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button {
+ padding: 16px;
+ width: 49px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .collapse-text,
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .icon-chevron-double-lg-left {
+ display: none;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .icon-chevron-double-lg-right {
+ display: block;
+ margin: 0;
+ }
+}
+body.sidebar-refactoring .nav-sidebar-inner-scroll {
+ height: 100%;
+ width: 100%;
+ overflow: auto;
+}
+body.sidebar-refactoring .sidebar-sub-level-items {
+ display: none;
+ padding-bottom: 8px;
+}
+body.sidebar-refactoring .sidebar-sub-level-items > li a {
+ padding: 8px 16px 8px 40px;
+}
+body.sidebar-refactoring .sidebar-top-level-items {
+ margin-bottom: 60px;
+}
+@media (min-width: 576px) {
+ body.sidebar-refactoring .sidebar-top-level-items > li > a {
+ margin-right: 1px;
+ }
+}
+body.sidebar-refactoring .sidebar-top-level-items > li .badge.badge-pill {
+ background-color: rgba(255, 255, 255, 0.08);
+ color: #999;
+}
+body.sidebar-refactoring .sidebar-top-level-items > li.active {
+ background: rgba(255, 255, 255, 0.04);
+}
+body.sidebar-refactoring .sidebar-top-level-items > li.active > a {
+ margin-left: 4px;
+ padding-left: 12px;
+}
+body.sidebar-refactoring
+ .sidebar-top-level-items
+ > li.active
+ .badge.badge-pill {
+ font-weight: 600;
+}
+body.sidebar-refactoring
+ .sidebar-top-level-items
+ > li.active
+ .sidebar-sub-level-items:not(.is-fly-out-only) {
display: block;
- padding: 8px 12px;
- margin: 0 0 8px;
- font-size: 13px;
- word-break: break-all;
- word-wrap: break-word;
- color: #fafafa;
- background-color: #2e2e2e;
- border: 1px solid #4f4f4f;
- border-radius: 2px;
}
-.monospace {
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
+body.sidebar-refactoring .toggle-sidebar-button,
+body.sidebar-refactoring .close-nav-button {
+ height: 48px;
+ padding: 0 16px;
+ background-color: #303030;
+ border: 0;
+ color: #999;
+ display: flex;
+ align-items: center;
}
-input::-moz-placeholder,
-textarea::-moz-placeholder {
- color: #a7a7a7;
+body.sidebar-refactoring .toggle-sidebar-button,
+body.sidebar-refactoring .close-nav-button {
+ position: fixed;
+ bottom: 0;
+ width: 219px;
+ border-top: 1px solid #404040;
+}
+body.sidebar-refactoring .toggle-sidebar-button svg,
+body.sidebar-refactoring .close-nav-button svg {
+ margin-right: 8px;
+}
+body.sidebar-refactoring .toggle-sidebar-button .icon-chevron-double-lg-right,
+body.sidebar-refactoring .close-nav-button .icon-chevron-double-lg-right {
+ display: none;
+}
+body.sidebar-refactoring .collapse-text {
+ white-space: nowrap;
+ overflow: hidden;
+}
+body.sidebar-refactoring .fly-out-top-item > a {
+ display: flex;
+}
+body.sidebar-refactoring .fly-out-top-item .fly-out-badge {
+ margin-left: 8px;
+}
+body.sidebar-refactoring .fly-out-top-item-name {
+ flex: 1;
+}
+body.sidebar-refactoring .close-nav-button {
+ display: none;
+}
+@media (max-width: 767.98px) {
+ body.sidebar-refactoring .close-nav-button {
+ display: flex;
+ }
+ body.sidebar-refactoring .toggle-sidebar-button {
+ display: none;
+ }
+}
+input::-moz-placeholder {
+ color: #868686;
opacity: 1;
}
-input::-ms-input-placeholder,
-textarea::-ms-input-placeholder {
- color: #a7a7a7;
+input::-ms-input-placeholder {
+ color: #868686;
}
-input:-ms-input-placeholder,
-textarea:-ms-input-placeholder {
- color: #a7a7a7;
+input:-ms-input-placeholder {
+ color: #868686;
}
svg {
fill: currentColor;
}
-
svg.s12 {
width: 12px;
height: 12px;
}
-
svg.s16 {
width: 16px;
height: 16px;
}
-
svg.s18 {
width: 18px;
height: 18px;
}
-
svg.s12 {
vertical-align: -1px;
}
-
svg.s16 {
vertical-align: -3px;
}
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0;
-}
-table.code {
+.js-groups-dropdown {
width: 100%;
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
- border: 0;
- border-collapse: separate;
- margin: 0;
- padding: 0;
- table-layout: fixed;
- border-radius: 0 0 4px 4px;
-}
-.frame .badge.badge-pill {
- position: absolute;
- background-color: #1b69b6;
- color: #333;
- border: #333 1px solid;
- min-height: 16px;
- padding: 5px 8px;
- border-radius: 12px;
-}
-.frame .badge.badge-pill {
- transform: translate(-50%, -50%);
-}
-.color-label {
- padding: 0 0.5rem;
- line-height: 16px;
- border-radius: 100px;
- color: #333;
-}
-.label-link {
- display: inline-flex;
- vertical-align: text-bottom;
-}
-.milestones {
- padding: 8px;
- margin-top: 8px;
- border-radius: 4px;
- background-color: #4f4f4f;
}
.search {
margin: 0 8px;
}
.search form {
+ display: block;
margin: 0;
padding: 4px;
width: 200px;
@@ -1750,7 +1870,6 @@ table.code {
border: 0;
border-radius: 4px;
}
-
@media (min-width: 1200px) {
.search form {
width: 320px;
@@ -1789,12 +1908,17 @@ table.code {
.search .search-input-wrap .dropdown {
position: static;
}
+.search .search-input-wrap .dropdown-header {
+ font-weight: 600;
+ color: #fafafa;
+ font-size: 0.875rem;
+ line-height: 16px;
+}
.search .search-input-wrap .dropdown-menu {
left: -5px;
max-height: 400px;
overflow: auto;
}
-
@media (min-width: 1200px) {
.search .search-input-wrap .dropdown-menu {
width: 320px;
@@ -1803,34 +1927,27 @@ table.code {
.search .search-input-wrap .dropdown-content {
max-height: 382px;
}
-.settings {
- border-top: 1px solid #4f4f4f;
-}
-.settings:first-of-type {
- margin-top: 10px;
- border: 0;
-}
-.settings + div .settings:first-of-type {
- margin-top: 0;
- border-top: 1px solid #4f4f4f;
-}
-.avatar, .avatar-container {
+.avatar,
+.avatar-container {
float: left;
margin-right: 16px;
border-radius: 50%;
border: 1px solid #333;
}
-.s16.avatar, .s16.avatar-container {
+.avatar.s16,
+.avatar-container.s16 {
width: 16px;
height: 16px;
margin-right: 8px;
}
-.s18.avatar, .s18.avatar-container {
+.avatar.s18,
+.avatar-container.s18 {
width: 18px;
height: 18px;
margin-right: 8px;
}
-.s40.avatar, .s40.avatar-container {
+.avatar.s40,
+.avatar-container.s40 {
width: 40px;
height: 40px;
margin-right: 8px;
@@ -1844,11 +1961,6 @@ table.code {
overflow: hidden;
border-color: rgba(255, 255, 255, 0.1);
}
-.avatar.center {
- font-size: 14px;
- line-height: 1.8em;
- text-align: center;
-}
.avatar.avatar-tile {
border-radius: 0;
border: 0;
@@ -1887,6 +1999,219 @@ table.code {
.rect-avatar.s40 {
border-radius: 4px;
}
+#content-body {
+ display: block;
+}
+@keyframes gl-spinner-rotate {
+ 0% {
+ transform: rotate(0);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+body.gl-dark .navbar-gitlab {
+ background-color: #fafafa;
+}
+body.gl-dark .navbar-gitlab .navbar-collapse {
+ color: #fafafa;
+}
+body.gl-dark .navbar-gitlab .container-fluid .navbar-toggler {
+ border-left: 1px solid #b3b3b3;
+}
+body.gl-dark .navbar-gitlab .container-fluid .navbar-toggler svg {
+ fill: #fafafa;
+}
+body.gl-dark .navbar-gitlab .navbar-sub-nav > li.active > a,
+body.gl-dark .navbar-gitlab .navbar-sub-nav > li.active > button,
+body.gl-dark .navbar-gitlab .navbar-sub-nav > li.dropdown.show > a,
+body.gl-dark .navbar-gitlab .navbar-sub-nav > li.dropdown.show > button,
+body.gl-dark .navbar-gitlab .navbar-nav > li.active > a,
+body.gl-dark .navbar-gitlab .navbar-nav > li.active > button,
+body.gl-dark .navbar-gitlab .navbar-nav > li.dropdown.show > a,
+body.gl-dark .navbar-gitlab .navbar-nav > li.dropdown.show > button {
+ color: #fafafa;
+ background-color: #333;
+}
+body.gl-dark .navbar-gitlab .navbar-sub-nav {
+ color: #fafafa;
+}
+body.gl-dark .navbar-gitlab .nav > li {
+ color: #fafafa;
+}
+body.gl-dark .navbar-gitlab .nav > li > a .notification-dot {
+ border: 2px solid #fafafa;
+}
+body.gl-dark
+ .navbar-gitlab
+ .nav
+ > li
+ > a.header-help-dropdown-toggle
+ .notification-dot {
+ background-color: #fafafa;
+}
+body.gl-dark
+ .navbar-gitlab
+ .nav
+ > li
+ > a.header-user-dropdown-toggle
+ .header-user-avatar {
+ border-color: #fafafa;
+}
+body.gl-dark .navbar-gitlab .nav > li.active > a,
+body.gl-dark .navbar-gitlab .nav > li.dropdown.show > a {
+ color: #fafafa;
+ background-color: #333;
+}
+body.gl-dark .navbar-gitlab .nav > li.active > a .notification-dot,
+body.gl-dark .navbar-gitlab .nav > li.dropdown.show > a .notification-dot {
+ border-color: #333;
+}
+body.gl-dark
+ .navbar-gitlab
+ .nav
+ > li.active
+ > a.header-help-dropdown-toggle
+ .notification-dot,
+body.gl-dark
+ .navbar-gitlab
+ .nav
+ > li.dropdown.show
+ > a.header-help-dropdown-toggle
+ .notification-dot {
+ background-color: #fafafa;
+}
+body.gl-dark .search form {
+ background-color: rgba(250, 250, 250, 0.2);
+}
+body.gl-dark .search .search-input::-ms-input-placeholder {
+ color: rgba(250, 250, 250, 0.8);
+}
+body.gl-dark .search .search-input::placeholder {
+ color: rgba(250, 250, 250, 0.8);
+}
+body.gl-dark .search .search-input-wrap .search-icon,
+body.gl-dark .search .search-input-wrap .clear-icon {
+ fill: rgba(250, 250, 250, 0.8);
+}
+body.gl-dark .nav-sidebar li.active {
+ box-shadow: inset 4px 0 0 #999;
+}
+body.gl-dark .nav-sidebar li.active > a {
+ color: #f0f0f0;
+}
+body.gl-dark .nav-sidebar li.active .nav-icon-container svg {
+ fill: #f0f0f0;
+}
+body.gl-dark .sidebar-top-level-items > li.active .badge.badge-pill {
+ color: #f0f0f0;
+}
+body.gl-dark .logo-text svg {
+ fill: var(--gl-text-color);
+}
+body.gl-dark .navbar-gitlab {
+ background-color: var(--gray-50);
+ box-shadow: 0 1px 0 0 var(--gray-100);
+}
+body.gl-dark .navbar-gitlab .navbar-sub-nav li.active > a,
+body.gl-dark .navbar-gitlab .navbar-sub-nav li.active > button,
+body.gl-dark .navbar-gitlab .navbar-sub-nav li.dropdown.show > a,
+body.gl-dark .navbar-gitlab .navbar-sub-nav li.dropdown.show > button,
+body.gl-dark .navbar-gitlab .navbar-nav li.active > a,
+body.gl-dark .navbar-gitlab .navbar-nav li.active > button,
+body.gl-dark .navbar-gitlab .navbar-nav li.dropdown.show > a,
+body.gl-dark .navbar-gitlab .navbar-nav li.dropdown.show > button {
+ color: var(--gl-text-color);
+ background-color: var(--gray-200);
+}
+body.gl-dark .navbar-gitlab .search form {
+ background-color: var(--gray-100);
+ box-shadow: inset 0 0 0 1px var(--border-color);
+}
+
+body.gl-dark {
+ --gray-10: #1f1f1f;
+ --gray-50: #303030;
+ --gray-100: #404040;
+ --gray-200: #525252;
+ --gray-300: #5e5e5e;
+ --gray-400: #868686;
+ --gray-500: #999;
+ --gray-600: #bfbfbf;
+ --gray-700: #dbdbdb;
+ --gray-800: #f0f0f0;
+ --gray-900: #fafafa;
+ --gray-950: #fff;
+ --green-50: #0a4020;
+ --green-100: #0d532a;
+ --green-200: #24663b;
+ --green-300: #217645;
+ --green-400: #108548;
+ --green-500: #2da160;
+ --green-600: #52b87a;
+ --green-700: #91d4a8;
+ --green-800: #c3e6cd;
+ --green-900: #ecf4ee;
+ --green-950: #f1fdf6;
+ --blue-50: #033464;
+ --blue-100: #064787;
+ --blue-200: #0b5cad;
+ --blue-300: #1068bf;
+ --blue-400: #1f75cb;
+ --blue-500: #428fdc;
+ --blue-600: #63a6e9;
+ --blue-700: #9dc7f1;
+ --blue-800: #cbe2f9;
+ --blue-900: #e9f3fc;
+ --blue-950: #f2f9ff;
+ --orange-50: #5c2900;
+ --orange-100: #703800;
+ --orange-200: #8f4700;
+ --orange-300: #9e5400;
+ --orange-400: #ab6100;
+ --orange-500: #c17d10;
+ --orange-600: #d99530;
+ --orange-700: #e9be74;
+ --orange-800: #f5d9a8;
+ --orange-900: #fdf1dd;
+ --orange-950: #fff4e1;
+ --red-50: #660e00;
+ --red-100: #8d1300;
+ --red-200: #ae1800;
+ --red-300: #c91c00;
+ --red-400: #dd2b0e;
+ --red-500: #ec5941;
+ --red-600: #f57f6c;
+ --red-700: #fcb5aa;
+ --red-800: #fdd4cd;
+ --red-900: #fcf1ef;
+ --red-950: #fff4f3;
+ --indigo-50: #1a1a40;
+ --indigo-100: #292961;
+ --indigo-200: #393982;
+ --indigo-300: #4b4ba3;
+ --indigo-400: #5b5bbd;
+ --indigo-500: #6666c4;
+ --indigo-600: #7c7ccc;
+ --indigo-700: #a6a6de;
+ --indigo-800: #d1d1f0;
+ --indigo-900: #ebebfa;
+ --indigo-950: #f7f7ff;
+ --indigo-900-alpha-008: rgba(235, 235, 250, 0.08);
+ --gl-text-color: #fafafa;
+ --border-color: #4f4f4f;
+ --white: #333;
+ --black: #fff;
+ --svg-status-bg: #333;
+}
+@keyframes gl-spinner-rotate {
+ 0% {
+ transform: rotate(0);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
.tab-width-8 {
-moz-tab-size: 8;
tab-size: 8;
@@ -1902,12 +2227,61 @@ table.code {
white-space: nowrap;
width: 1px;
}
+@keyframes gl-spinner-rotate {
+ 0% {
+ transform: rotate(0);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+.gl-border-solid {
+ border-style: solid;
+}
+.gl-border-gray-100 {
+ border-color: #404040;
+}
+.gl-border-0 {
+ border-width: 0;
+}
+.gl-border-t-1 {
+ border-top-width: 1px;
+}
+.gl-display-flex\! {
+ display: flex !important;
+}
+.gl-align-items-center {
+ align-items: center;
+}
+.gl-justify-content-space-between {
+ justify-content: space-between;
+}
+.gl-absolute {
+ position: absolute;
+}
+.gl-px-3\! {
+ padding-left: 0.5rem !important;
+ padding-right: 0.5rem !important;
+}
+.gl-mt-7 {
+ margin-top: 2rem;
+}
+.gl-ml-auto {
+ margin-left: auto;
+}
.gl-ml-3 {
margin-left: 0.5rem;
}
-.content-wrapper > .alert-wrapper,
-#content-body, .modal-dialog {
- display: block;
+.gl-mx-0\! {
+ margin-left: 0 !important;
+ margin-right: 0 !important;
}
-@import 'cloaking';
+.gl-font-weight-bold {
+ font-weight: 600;
+}
+.gl-line-height-20\! {
+ line-height: 1.25rem !important;
+}
+
+@import "cloaking";
@include cloak-startup-scss(none);
diff --git a/app/assets/stylesheets/startup/startup-general.scss b/app/assets/stylesheets/startup/startup-general.scss
index 44da509481d..f188ae7f507 100644
--- a/app/assets/stylesheets/startup/startup-general.scss
+++ b/app/assets/stylesheets/startup/startup-general.scss
@@ -1,3 +1,6 @@
+// DO NOT EDIT! This is auto-generated from "yarn run generate:startup_css"
+// Please see the feedback issue for more details and help:
+// https://gitlab.com/gitlab-org/gitlab/-/issues/331812
@charset "UTF-8";
*,
*::before,
@@ -8,12 +11,16 @@ html {
font-family: sans-serif;
line-height: 1.15;
}
- header, nav, section {
+aside,
+header,
+nav {
display: block;
}
body {
margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans", Ubuntu, Cantarell, "Helvetica Neue", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ "Noto Sans", Ubuntu, Cantarell, "Helvetica Neue", sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
@@ -21,55 +28,29 @@ body {
text-align: left;
background-color: #fff;
}
-h1, h2, h3 {
+h1 {
margin-top: 0;
margin-bottom: 0.25rem;
}
-p {
- margin-top: 0;
- margin-bottom: 1rem;
-}
-
ul {
margin-top: 0;
margin-bottom: 1rem;
}
-
ul ul {
margin-bottom: 0;
}
-
strong {
font-weight: bolder;
}
-sub {
- position: relative;
- font-size: 75%;
- line-height: 0;
- vertical-align: baseline;
-}
-sub {
- bottom: -.25em;
-}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
-a:not([href]) {
+a:not([href]):not([class]) {
color: inherit;
text-decoration: none;
}
-pre,
-code {
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
- font-size: 1em;
-}
-pre {
- margin-top: 0;
- margin-bottom: 1rem;
- overflow: auto;
-}
img {
vertical-align: middle;
border-style: none;
@@ -78,18 +59,11 @@ svg {
overflow: hidden;
vertical-align: middle;
}
-table {
- border-collapse: collapse;
-}
-th {
- text-align: inherit;
-}
button {
border-radius: 0;
}
input,
-button,
-textarea {
+button {
margin: 0;
font-family: inherit;
font-size: inherit;
@@ -102,21 +76,20 @@ input {
button {
text-transform: none;
}
+[role="button"] {
+ cursor: pointer;
+}
button:not(:disabled),
[type="button"]:not(:disabled),
-[type="reset"]:not(:disabled) {
+[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
-[type="reset"]::-moz-focus-inner {
+[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
-textarea {
- overflow: auto;
- resize: vertical;
-}
[type="search"] {
outline-offset: -2px;
}
@@ -130,75 +103,21 @@ template {
[hidden] {
display: none !important;
}
-h1, h2, h3,
-.h1, .h2, .h3 {
+h1,
+.h1 {
margin-bottom: 0.25rem;
font-weight: 600;
line-height: 1.2;
color: #303030;
}
-h1, .h1 {
+h1,
+.h1 {
font-size: 2.1875rem;
}
-h2, .h2 {
- font-size: 1.75rem;
-}
-h3, .h3 {
- font-size: 1.53125rem;
-}
.list-unstyled {
padding-left: 0;
list-style: none;
}
-code {
- font-size: 90%;
- color: #1f1f1f;
- word-wrap: break-word;
-}
-a > code {
- color: inherit;
-}
-pre {
- display: block;
- font-size: 90%;
- color: #303030;
-}
-pre code {
- font-size: inherit;
- color: inherit;
- word-break: normal;
-}
-.container {
- width: 100%;
- padding-right: 15px;
- padding-left: 15px;
- margin-right: auto;
- margin-left: auto;
-}
-
-@media (min-width: 576px) {
- .container {
- max-width: 540px;
- }
-}
-
-@media (min-width: 768px) {
- .container {
- max-width: 720px;
- }
-}
-
-@media (min-width: 992px) {
- .container {
- max-width: 960px;
- }
-}
-
-@media (min-width: 1200px) {
- .container {
- max-width: 1140px;
- }
-}
.container-fluid {
width: 100%;
padding-right: 15px;
@@ -206,48 +125,7 @@ pre code {
margin-right: auto;
margin-left: auto;
}
-
-@media (min-width: 576px) {
- .container {
- max-width: 540px;
- }
-}
-
-@media (min-width: 768px) {
- .container {
- max-width: 720px;
- }
-}
-
-@media (min-width: 992px) {
- .container {
- max-width: 960px;
- }
-}
-
-@media (min-width: 1200px) {
- .container {
- max-width: 1140px;
- }
-}
-.row {
- display: flex;
- flex-wrap: wrap;
- margin-right: -15px;
- margin-left: -15px;
-}
-.table {
- width: 100%;
- margin-bottom: 0.5rem;
- color: #303030;
-}
-.table th,
-.table td {
- padding: 0.75rem;
- vertical-align: top;
- border-top: 1px solid #dbdbdb;
-}
- .search form {
+.form-control {
display: block;
width: 100%;
height: 34px;
@@ -261,18 +139,21 @@ pre code {
border: 1px solid #dbdbdb;
border-radius: 0.25rem;
}
-
@media (prefers-reduced-motion: reduce) {
}
- .search form:-moz-focusring {
+.form-control:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #303030;
}
- .search form::placeholder {
+.form-control::-ms-input-placeholder {
color: #5e5e5e;
opacity: 1;
}
- .search form:disabled {
+.form-control::placeholder {
+ color: #5e5e5e;
+ opacity: 1;
+}
+.form-control:disabled {
background-color: #fafafa;
opacity: 1;
}
@@ -281,9 +162,8 @@ pre code {
flex-flow: row wrap;
align-items: center;
}
-
@media (min-width: 576px) {
- .form-inline .search form, .search .form-inline form {
+ .form-inline .form-control {
display: inline-block;
width: auto;
vertical-align: middle;
@@ -295,7 +175,7 @@ pre code {
color: #303030;
text-align: center;
vertical-align: middle;
- cursor: pointer;
+ -moz-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
@@ -304,26 +184,35 @@ pre code {
line-height: 20px;
border-radius: 0.25rem;
}
-
@media (prefers-reduced-motion: reduce) {
}
-.btn.disabled, .btn:disabled {
+.btn:disabled {
opacity: 0.65;
}
-a.btn.disabled {
+.btn:not(:disabled):not(.disabled) {
+ cursor: pointer;
+}
+.btn-link {
+ font-weight: 400;
+ color: #007bff;
+ text-decoration: none;
+}
+.btn-link:disabled {
+ color: #5e5e5e;
pointer-events: none;
}
.collapse:not(.show) {
display: none;
}
-
.dropdown {
position: relative;
}
- .dropdown-menu-toggle {
+.dropdown-toggle,
+.dropdown-menu-toggle {
white-space: nowrap;
}
- .dropdown-menu-toggle::after {
+.dropdown-toggle::after,
+.dropdown-menu-toggle::after {
display: inline-block;
margin-left: 0.255em;
vertical-align: 0.255em;
@@ -333,7 +222,8 @@ a.btn.disabled {
border-bottom: 0;
border-left: 0.3em solid transparent;
}
- .dropdown-menu-toggle:empty::after {
+.dropdown-toggle:empty::after,
+.dropdown-menu-toggle:empty::after {
margin-left: 0;
}
.dropdown-menu {
@@ -358,16 +248,18 @@ a.btn.disabled {
.dropdown-menu-right {
right: 0;
left: auto;
-}
- .divider {
- height: 0;
- margin: 4px 0;
- overflow: hidden;
- border-top: 1px solid #dbdbdb;
}
.dropdown-menu.show {
display: block;
}
+.dropdown-header {
+ display: block;
+ padding: 0.5rem 12px;
+ margin-bottom: 0;
+ font-size: 0.875rem;
+ color: #5e5e5e;
+ white-space: nowrap;
+}
.nav {
display: flex;
flex-wrap: wrap;
@@ -375,6 +267,10 @@ a.btn.disabled {
margin-bottom: 0;
list-style: none;
}
+.nav-link {
+ display: block;
+ padding: 0.5rem 1rem;
+}
.navbar {
position: relative;
display: flex;
@@ -383,7 +279,6 @@ a.btn.disabled {
justify-content: space-between;
padding: 0.25rem 0.5rem;
}
-.navbar .container,
.navbar .container-fluid {
display: flex;
flex-wrap: wrap;
@@ -397,6 +292,10 @@ a.btn.disabled {
margin-bottom: 0;
list-style: none;
}
+.navbar-nav .nav-link {
+ padding-right: 0;
+ padding-left: 0;
+}
.navbar-nav .dropdown-menu {
position: static;
float: none;
@@ -414,15 +313,12 @@ a.btn.disabled {
border: 1px solid transparent;
border-radius: 0.25rem;
}
-
@media (max-width: 575.98px) {
- .navbar-expand-sm > .container,
.navbar-expand-sm > .container-fluid {
padding-right: 0;
padding-left: 0;
}
}
-
@media (min-width: 576px) {
.navbar-expand-sm {
flex-flow: row nowrap;
@@ -434,7 +330,10 @@ a.btn.disabled {
.navbar-expand-sm .navbar-nav .dropdown-menu {
position: absolute;
}
- .navbar-expand-sm > .container,
+ .navbar-expand-sm .navbar-nav .nav-link {
+ padding-right: 0.5rem;
+ padding-left: 0.5rem;
+ }
.navbar-expand-sm > .container-fluid {
flex-wrap: nowrap;
}
@@ -468,7 +367,6 @@ a.btn.disabled {
vertical-align: baseline;
border-radius: 0.25rem;
}
-
@media (prefers-reduced-motion: reduce) {
}
.badge:empty {
@@ -483,9 +381,9 @@ a.btn.disabled {
padding-left: 0.6em;
border-radius: 10rem;
}
-.media {
- display: flex;
- align-items: flex-start;
+.badge-dark {
+ color: #fff;
+ background-color: #404040;
}
.close {
float: right;
@@ -494,55 +392,15 @@ a.btn.disabled {
line-height: 1;
color: #000;
text-shadow: 0 1px 0 #fff;
- opacity: .5;
+ opacity: 0.5;
}
button.close {
padding: 0;
background-color: transparent;
border: 0;
- appearance: none;
}
-a.close.disabled {
- pointer-events: none;
-}
-.modal-dialog {
- position: relative;
- width: auto;
- margin: 0.5rem;
- pointer-events: none;
-}
-
-@media (min-width: 576px) {
- .modal-dialog {
- max-width: 500px;
- margin: 1.75rem auto;
- }
-}
-.bg-transparent {
- background-color: transparent !important;
-}
-.border {
- border: 1px solid #dbdbdb !important;
-}
-.border-top {
- border-top: 1px solid #dbdbdb !important;
-}
-.border-right {
- border-right: 1px solid #dbdbdb !important;
-}
-.border-bottom {
- border-bottom: 1px solid #dbdbdb !important;
-}
-.border-left {
- border-left: 1px solid #dbdbdb !important;
-}
-.rounded {
- border-radius: 0.25rem !important;
-}
-.clearfix::after {
- display: block;
- clear: both;
- content: "";
+.rounded-circle {
+ border-radius: 50% !important;
}
.d-none {
display: none !important;
@@ -553,19 +411,19 @@ a.close.disabled {
.d-block {
display: block !important;
}
-
@media (min-width: 576px) {
.d-sm-none {
display: none !important;
}
}
-
@media (min-width: 768px) {
+ .d-md-none {
+ display: none !important;
+ }
.d-md-block {
display: block !important;
}
}
-
@media (min-width: 992px) {
.d-lg-none {
display: none !important;
@@ -574,15 +432,14 @@ a.close.disabled {
display: block !important;
}
}
-
@media (min-width: 1200px) {
+ .d-xl-none {
+ display: none !important;
+ }
.d-xl-block {
display: block !important;
}
}
-.flex-wrap {
- flex-wrap: wrap !important;
-}
.float-right {
float: right !important;
}
@@ -603,15 +460,13 @@ a.close.disabled {
.text-nowrap {
white-space: nowrap !important;
}
-.visible {
- visibility: visible !important;
-}
- .search form.focus {
- color: #303030;
- background-color: #fff;
- border-color: #80bdff;
- outline: 0;
- box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
+@keyframes gl-spinner-rotate {
+ 0% {
+ transform: rotate(0);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
}
.gl-badge {
display: inline-flex;
@@ -623,50 +478,148 @@ a.close.disabled {
padding-bottom: 0.25rem;
padding-left: 0.5rem;
padding-right: 0.5rem;
- outline: none;
}
-body, .search form,
+.gl-badge.sm {
+ padding-top: 0;
+ padding-bottom: 0;
+}
+.gl-badge.badge-muted {
+ background-color: #f0f0f0;
+ color: #666;
+}
+a.gl-badge.badge-muted.active,
+a.gl-badge.badge-muted:active {
+ color: #404040;
+ background-color: #dbdbdb;
+}
+.gl-new-dropdown .dropdown-menu {
+ background-color: #fff;
+ border-width: 1px;
+ border-color: #bfbfbf;
+ margin-top: 0.25rem;
+ margin-bottom: 0.25rem;
+ padding: 0;
+ border-radius: 0.25rem;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
+ width: 15rem;
+}
+.gl-new-dropdown .dropdown-menu li {
+ padding: 0;
+}
+.gl-new-dropdown .dropdown-toggle::after,
+.gl-new-dropdown .dropdown-menu-toggle::after {
+ display: none;
+}
+.gl-new-dropdown .dropdown-toggle.gl-button,
+.gl-new-dropdown .gl-button.dropdown-menu-toggle {
+ padding-right: 0.5rem;
+}
+.gl-new-dropdown.dropdown .gl-button .dropdown-chevron,
+.gl-new-dropdown.dropdown .dropdown-chevron {
+ margin-left: 0.25rem;
+ margin-right: 0;
+}
+.gl-new-dropdown .dropdown-icon {
+ margin-right: 0.25rem;
+}
+.gl-spinner-container {
+ line-height: 0;
+ text-align: center;
+}
+.gl-spinner {
+ position: relative;
+ display: inline-flex;
+ border-radius: 50%;
+ border-style: solid;
+ margin-left: auto;
+ margin-right: auto;
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 0.875rem;
+ animation-name: gl-spinner-rotate;
+ animation-duration: 0.6s;
+ animation-timing-function: linear;
+ animation-iteration-count: infinite;
+ width: 1rem;
+ height: 1rem;
+ border-width: 2px;
+ transform-origin: 50% 50% calc((1rem / 2) + 2px);
+ border-color: rgba(82, 82, 82, 0.25);
+ border-top-color: #525252;
+}
+.gl-spinner.gl-spinner-md {
+ width: 1.5rem;
+ height: 1.5rem;
+ border-width: 3px;
+ transform-origin: 50% 50% calc((1.5rem / 2) + 3px);
+}
+.gl-button {
+ display: inline-flex;
+}
+.gl-button.gl-button {
+ border-width: 0;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+ background-color: transparent;
+ line-height: 1rem;
+ color: #303030;
+ fill: currentColor;
+ box-shadow: inset 0 0 0 1px #bfbfbf;
+ justify-content: center;
+ align-items: center;
+ font-size: 0.875rem;
+ border-radius: 0.25rem;
+}
+.gl-button.gl-button.btn-default {
+ background-color: #fff;
+}
+.gl-button.gl-button.btn-default:active,
+.gl-button.gl-button.btn-default.active {
+ box-shadow: inset 0 0 0 2px #5e5e5e, 0 0 0 1px rgba(255, 255, 255, 0.4),
+ 0 0 0 4px rgba(31, 117, 203, 0.48);
+ outline: none;
+ background-color: #dbdbdb;
+}
+.gl-button.gl-button.btn-link {
+ background-color: transparent;
+ border-width: 0;
+ font-size: 0.875rem;
+ line-height: 1rem;
+ color: #1f75cb;
+ padding-top: 0;
+ padding-bottom: 0;
+ padding-left: 0;
+ padding-right: 0;
+ box-shadow: none;
+}
+.gl-button.gl-button.btn-link:active {
+ color: #0b5cad;
+ text-decoration: underline;
+}
+body,
+.form-control,
.search form {
font-size: 0.875rem;
}
button,
-html [type='button'],
-[type='reset'],
-[role='button'] {
+html [type="button"],
+[type="submit"],
+[role="button"] {
cursor: pointer;
}
h1,
-.h1,
-h2,
-.h2,
-h3,
-.h3 {
+.h1 {
margin-top: 20px;
margin-bottom: 10px;
}
-input[type='file'] {
- line-height: 1;
-}
-
strong {
font-weight: bold;
}
a {
color: #1068bf;
}
-code {
- padding: 2px 4px;
- color: #1f1f1f;
- background-color: #f0f0f0;
- border-radius: 4px;
-}
-.code > code {
- background-color: inherit;
- padding: unset;
-}
-table {
- border-spacing: 0;
-}
.hidden {
display: none !important;
visibility: hidden !important;
@@ -674,7 +627,8 @@ table {
.hide {
display: none;
}
- .dropdown-menu-toggle::after {
+.dropdown-toggle::after,
+.dropdown-menu-toggle::after {
display: none;
}
.badge:not(.gl-badge) {
@@ -684,8 +638,11 @@ table {
font-weight: 400;
display: inline-block;
}
-pre code {
- white-space: pre-wrap;
+.divider {
+ height: 0;
+ margin: 4px 0;
+ overflow: hidden;
+ border-top: 1px solid #dbdbdb;
}
.toggle-sidebar-button .collapse-text,
.toggle-sidebar-button .icon-chevron-double-lg-left,
@@ -701,28 +658,20 @@ html {
body {
text-decoration-skip: ink;
}
-.content-wrapper {
- margin-top: 40px;
- padding-bottom: 100px;
-}
-.container {
- padding-top: 0;
- z-index: 5;
-}
-.container .content {
- margin: 0;
-}
-
-@media (max-width: 575.98px) {
- .container .content {
- margin-top: 20px;
+@keyframes spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
}
}
-
-@media (max-width: 575.98px) {
- .container .container .title {
- padding-left: 15px !important;
- }
+.gl-spinner {
+ animation-name: spin;
+ animation-iteration-count: infinite;
+ animation-timing-function: linear;
+ animation-duration: 1s;
+ transform-origin: 50% 50%;
}
.btn {
border-radius: 4px;
@@ -735,7 +684,8 @@ body {
color: #303030;
white-space: nowrap;
}
-.btn:active, .btn.active {
+.btn:active,
+.btn.active {
background-color: #eaeaea;
border-color: #e3e3e3;
color: #303030;
@@ -744,64 +694,35 @@ body {
height: 15px;
width: 15px;
}
-.btn svg:not(:last-child),
-.btn .fa:not(:last-child) {
+.btn svg:not(:last-child) {
margin-right: 5px;
}
+.btn-link {
+ padding: 0;
+ background-color: transparent;
+ color: #1068bf;
+ font-weight: normal;
+ border-radius: 0;
+ border-color: transparent;
+ border-width: 0;
+}
.badge.badge-pill:not(.gl-badge) {
font-weight: 400;
background-color: rgba(0, 0, 0, 0.07);
color: #525252;
vertical-align: baseline;
}
-.hint {
- font-style: italic;
- color: #bfbfbf;
-}
-.bold {
- font-weight: 600;
-}
-pre.wrap {
- word-break: break-word;
- white-space: pre-wrap;
-}
-table a code {
- position: relative;
- top: -2px;
- margin-right: 3px;
-}
-.loading {
- margin: 20px auto;
- height: 40px;
- color: #525252;
- font-size: 32px;
- text-align: center;
-}
-.highlight {
- text-shadow: none;
-}
.chart {
overflow: hidden;
height: 220px;
}
-.break-word {
- word-wrap: break-word;
-}
-.center {
- text-align: center;
-}
-.block {
- display: block;
-}
-.flex {
- display: flex;
-}
-.flex-grow {
- flex-grow: 1;
-}
.dropdown {
position: relative;
}
+.dropdown.gl-new-dropdown button.dropdown-toggle,
+.dropdown.gl-new-dropdown button.dropdown-menu-toggle {
+ display: inline-flex;
+}
.show.dropdown .dropdown-menu {
transform: translateY(0);
display: block;
@@ -809,23 +730,32 @@ table a code {
max-height: 312px;
overflow-y: auto;
}
-
+.show.dropdown .dropdown-menu.dropdown-extended-height {
+ max-height: 400px;
+}
@media (max-width: 575.98px) {
.show.dropdown .dropdown-menu {
width: 100%;
}
}
- .show.dropdown .dropdown-menu-toggle,
+.show.dropdown .dropdown-menu.frequent-items-dropdown-menu {
+ padding: 0;
+ overflow-y: initial;
+ max-height: initial;
+}
+.show.dropdown .dropdown-toggle,
+.show.dropdown .dropdown-menu-toggle,
.show.dropdown .dropdown-menu-toggle {
border-color: #c4c4c4;
}
-.show.dropdown [data-toggle='dropdown'] {
+.show.dropdown [data-toggle="dropdown"] {
outline: 0;
}
.search-input-container .dropdown-menu {
margin-top: 11px;
}
- .dropdown-menu-toggle {
+.dropdown-toggle,
+.dropdown-menu-toggle {
padding: 6px 8px 6px 10px;
background-color: #fff;
color: #303030;
@@ -835,21 +765,22 @@ table a code {
border-radius: 0.25rem;
white-space: nowrap;
}
- .no-outline.dropdown-menu-toggle {
+.dropdown-toggle.no-outline,
+.no-outline.dropdown-menu-toggle {
outline: 0;
}
- .dropdown-menu-toggle .fa {
- color: #c4c4c4;
-}
-.dropdown-menu-toggle {
+.dropdown-menu-toggle.dropdown-menu-toggle {
+ justify-content: flex-start;
+ overflow: hidden;
padding-right: 25px;
position: relative;
- width: 160px;
text-overflow: ellipsis;
- overflow: hidden;
+ width: 160px;
}
-.dropdown-menu-toggle .fa {
+.dropdown-menu-toggle.dropdown-menu-toggle .gl-spinner {
position: absolute;
+ top: 9px;
+ right: 8px;
}
.dropdown-menu {
display: none;
@@ -880,7 +811,9 @@ table a code {
padding: 0 1px;
}
.dropdown-menu li > a,
-.dropdown-menu li button {
+.dropdown-menu li button,
+.dropdown-menu li .gl-button.btn-link,
+.dropdown-menu li .menu-item {
background: transparent;
border: 0;
border-radius: 0;
@@ -902,13 +835,24 @@ table a code {
padding: 0;
background-color: #dbdbdb;
}
+.dropdown-menu .dropdown-header {
+ color: #000;
+ font-size: 13px;
+ font-weight: 600;
+ line-height: 16px;
+ padding: 8px 12px;
+}
+.dropdown-menu .dropdown-bold-header {
+ font-weight: 600;
+ line-height: 16px;
+ padding: 8px 12px;
+}
.dropdown-menu .badge.badge-pill + span:not(.badge):not(.badge-pill) {
margin-right: 40px;
}
.dropdown-select {
width: 300px;
}
-
@media (max-width: 767.98px) {
.dropdown-select {
width: 100%;
@@ -929,42 +873,95 @@ table a code {
background-color: rgba(255, 255, 255, 0.6);
font-size: 28px;
}
-.dropdown-loading .fa {
- position: absolute;
- top: 50%;
- left: 50%;
- margin-top: -14px;
- margin-left: -14px;
-}
-
@media (max-width: 575.98px) {
.navbar-gitlab li.dropdown {
position: static;
}
+ .navbar-gitlab li.dropdown.user-counter {
+ margin-left: 8px !important;
+ }
+ .navbar-gitlab li.dropdown.user-counter > a {
+ padding: 0 4px !important;
+ }
header.navbar-gitlab .dropdown .dropdown-menu {
width: 100%;
min-width: 100%;
}
}
-
+header.header-content .dropdown-menu.frequent-items-dropdown-menu {
+ padding: 0;
+}
+.frequent-items-dropdown-container {
+ display: flex;
+ flex-direction: row;
+ height: 20rem;
+}
+.frequent-items-dropdown-container.with-deprecated-styles {
+ width: 500px;
+ height: 354px;
+}
+.frequent-items-dropdown-container.with-deprecated-styles
+ .search-input-container {
+ position: relative;
+ padding: 4px 16px;
+}
+.frequent-items-dropdown-container.with-deprecated-styles
+ .search-input-container
+ .search-icon {
+ position: absolute;
+ top: 13px;
+ right: 25px;
+ color: #999;
+}
+@media (max-width: 575.98px) {
+ .frequent-items-dropdown-container.with-deprecated-styles {
+ flex-direction: column;
+ width: 100%;
+ height: auto;
+ flex: 1;
+ }
+ .frequent-items-dropdown-container.with-deprecated-styles
+ .frequent-items-dropdown-sidebar,
+ .frequent-items-dropdown-container.with-deprecated-styles
+ .frequent-items-dropdown-content {
+ width: 100%;
+ }
+ .frequent-items-dropdown-container.with-deprecated-styles
+ .frequent-items-dropdown-sidebar {
+ border-bottom: 1px solid #dbdbdb;
+ border-right: 0;
+ }
+}
+.frequent-items-dropdown-container .frequent-items-dropdown-sidebar,
+.frequent-items-dropdown-container .frequent-items-dropdown-content {
+ padding-top: 0.5rem;
+}
+.frequent-items-dropdown-container .frequent-items-dropdown-sidebar {
+ width: 30%;
+ border-right: 1px solid #dbdbdb;
+}
+.frequent-items-dropdown-container .frequent-items-dropdown-content {
+ position: relative;
+ width: 70%;
+}
@media (max-width: 767.98px) {
.dropdown-menu-toggle {
width: 100%;
}
}
-textarea {
- resize: vertical;
-}
input {
border-radius: 0.25rem;
color: #303030;
background-color: #fff;
}
- .search form {
+.form-control {
border-radius: 4px;
padding: 6px 10px;
}
- .search form::placeholder {
+.form-control::-ms-input-placeholder {
+ color: #868686;
+}
+.form-control::placeholder {
color: #868686;
}
.navbar-gitlab {
@@ -973,7 +970,6 @@ input {
margin-bottom: 0;
min-height: 40px;
border: 0;
- border-bottom: 1px solid #dbdbdb;
position: fixed;
top: 0;
left: 0;
@@ -1023,9 +1019,6 @@ input {
.navbar-gitlab .header-content .title img + .logo-text {
margin-left: 8px;
}
-.navbar-gitlab .header-content .title.wrap {
- white-space: normal;
-}
.navbar-gitlab .header-content .title a {
display: flex;
align-items: center;
@@ -1033,9 +1026,6 @@ input {
margin: 5px 2px 5px -8px;
border-radius: 4px;
}
-.navbar-gitlab .header-content .dropdown.open > a {
- border-bottom-color: #fff;
-}
.navbar-gitlab .header-content .navbar-collapse > ul.nav > li:not(.d-none) {
margin: 0 2px;
}
@@ -1044,7 +1034,6 @@ input {
border-top: 0;
padding: 0;
}
-
@media (max-width: 575.98px) {
.navbar-gitlab .navbar-collapse {
flex: 1 1 auto;
@@ -1053,7 +1042,6 @@ input {
.navbar-gitlab .navbar-collapse .nav {
flex-wrap: nowrap;
}
-
@media (max-width: 575.98px) {
.navbar-gitlab .navbar-collapse .nav > li:not(.d-none) a {
margin-left: 0;
@@ -1076,7 +1064,6 @@ input {
text-align: center;
color: currentColor;
}
-
@media (max-width: 575.98px) {
.navbar-gitlab .container-fluid .navbar-nav {
display: flex;
@@ -1084,11 +1071,14 @@ input {
flex-direction: row;
}
}
-.navbar-gitlab .container-fluid .navbar-nav li .badge.badge-pill {
+.navbar-gitlab
+ .container-fluid
+ .navbar-nav
+ li
+ .badge.badge-pill:not(.merge-request-badge) {
box-shadow: none;
font-weight: 600;
}
-
@media (max-width: 575.98px) {
.navbar-gitlab .container-fluid .nav > li.header-user {
padding-left: 10px;
@@ -1100,7 +1090,6 @@ input {
padding: 6px 8px;
height: 32px;
}
-
@media (max-width: 575.98px) {
.navbar-gitlab .container-fluid .nav > li > a {
padding: 0;
@@ -1109,7 +1098,12 @@ input {
.navbar-gitlab .container-fluid .nav > li > a.header-user-dropdown-toggle {
margin-left: 2px;
}
-.navbar-gitlab .container-fluid .nav > li > a.header-user-dropdown-toggle .header-user-avatar {
+.navbar-gitlab
+ .container-fluid
+ .nav
+ > li
+ > a.header-user-dropdown-toggle
+ .header-user-avatar {
margin-right: 0;
}
.navbar-gitlab .container-fluid .nav > li .header-new-dropdown-toggle {
@@ -1130,7 +1124,9 @@ input {
height: 32px;
font-weight: 600;
}
+.navbar-sub-nav > li .top-nav-toggle,
.navbar-sub-nav > li > button,
+.navbar-nav > li .top-nav-toggle,
.navbar-nav > li > button {
background: transparent;
border: 0;
@@ -1143,6 +1139,11 @@ input {
display: flex;
margin: 0 0 0 6px;
}
+.navbar-sub-nav .dropdown-chevron {
+ position: relative;
+ top: -1px;
+ font-size: 10px;
+}
.caret-down,
.btn .caret-down {
top: 0;
@@ -1168,31 +1169,25 @@ input {
font-weight: 400;
margin-left: -6px;
font-size: 11px;
- color: #fff;
+ color: var(--gray-950, #fff);
padding: 0 5px;
line-height: 12px;
border-radius: 7px;
box-shadow: 0 1px 0 rgba(76, 78, 84, 0.2);
}
-.title-container .badge.badge-pill.green-badge,
-.navbar-nav .badge.badge-pill.green-badge {
- background-color: #108548;
+.title-container .badge.badge-pill:not(.merge-request-badge).green-badge,
+.navbar-nav .badge.badge-pill:not(.merge-request-badge).green-badge {
+ background-color: var(--green-400, #2da160);
}
-.title-container .badge.badge-pill.merge-requests-count,
-.navbar-nav .badge.badge-pill.merge-requests-count {
- background-color: #de7e00;
+.title-container
+ .badge.badge-pill:not(.merge-request-badge).merge-requests-count,
+.navbar-nav .badge.badge-pill:not(.merge-request-badge).merge-requests-count {
+ background-color: var(--orange-400, #c17d10);
}
-.title-container .badge.badge-pill.todos-count,
-.navbar-nav .badge.badge-pill.todos-count {
- background-color: #1f75cb;
+.title-container .badge.badge-pill:not(.merge-request-badge).todos-count,
+.navbar-nav .badge.badge-pill:not(.merge-request-badge).todos-count {
+ background-color: var(--blue-400, #428fdc);
}
-.title-container .canary-badge .badge,
-.navbar-nav .canary-badge .badge {
- font-size: 12px;
- line-height: 16px;
- padding: 0 0.5rem;
-}
-
@media (max-width: 575.98px) {
.navbar-gitlab .container-fluid {
font-size: 18px;
@@ -1219,7 +1214,7 @@ input {
}
.header-user.show .dropdown-menu {
margin-top: 4px;
- color: #303030;
+ color: var(--gl-text-color, #303030);
left: auto;
max-height: 445px;
}
@@ -1232,31 +1227,36 @@ input {
border-radius: 50%;
border: 1px solid #f5f5f5;
}
-.media {
- display: flex;
- align-items: flex-start;
+.notification-dot {
+ background-color: #d99530;
+ height: 12px;
+ width: 12px;
+ margin-top: -15px;
+ pointer-events: none;
+ visibility: hidden;
+}
+.top-nav-toggle .dropdown-icon {
+ margin-right: 0.5rem;
+}
+.top-nav-toggle .dropdown-chevron {
+ top: 0;
+}
+.tanuki-logo .tanuki-left-ear,
+.tanuki-logo .tanuki-right-ear,
+.tanuki-logo .tanuki-nose {
+ fill: #e24329;
+}
+.tanuki-logo .tanuki-left-eye,
+.tanuki-logo .tanuki-right-eye {
+ fill: #fc6d26;
+}
+.tanuki-logo .tanuki-left-cheek,
+.tanuki-logo .tanuki-right-cheek {
+ fill: #fca326;
}
.card {
margin-bottom: 16px;
}
-.content-wrapper {
- width: 100%;
-}
-.content-wrapper .container-fluid {
- padding: 0 16px;
-}
-
-@media (min-width: 768px) {
- .page-with-contextual-sidebar {
- padding-left: 50px;
- }
-}
-
-@media (min-width: 1200px) {
- .page-with-contextual-sidebar {
- padding-left: 220px;
- }
-}
.context-header {
position: relative;
margin-right: 2px;
@@ -1286,7 +1286,17 @@ input {
font-weight: normal;
font-size: 0.8em;
}
-.nav-sidebar {
+@media (min-width: 768px) {
+ body:not(.sidebar-refactoring) .page-with-contextual-sidebar {
+ padding-left: 50px;
+ }
+}
+@media (min-width: 1200px) {
+ body:not(.sidebar-refactoring) .page-with-contextual-sidebar {
+ padding-left: 220px;
+ }
+}
+body:not(.sidebar-refactoring) .nav-sidebar {
position: fixed;
z-index: 600;
width: 220px;
@@ -1297,93 +1307,64 @@ input {
box-shadow: inset -1px 0 0 #dbdbdb;
transform: translate3d(0, 0, 0);
}
-
@media (min-width: 576px) and (max-width: 576px) {
- .nav-sidebar:not(.sidebar-collapsed-desktop) {
+ body:not(.sidebar-refactoring) .nav-sidebar:not(.sidebar-collapsed-desktop) {
box-shadow: inset -1px 0 0 #dbdbdb, 2px 1px 3px rgba(0, 0, 0, 0.1);
}
}
-.nav-sidebar.sidebar-collapsed-desktop {
- width: 50px;
-}
-.nav-sidebar.sidebar-collapsed-desktop .nav-sidebar-inner-scroll {
- overflow-x: hidden;
-}
-.nav-sidebar.sidebar-collapsed-desktop .badge.badge-pill:not(.fly-out-badge),
-.nav-sidebar.sidebar-collapsed-desktop .sidebar-context-title,
-.nav-sidebar.sidebar-collapsed-desktop .nav-item-name {
- border: 0;
- clip: rect(0, 0, 0, 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- white-space: nowrap;
- width: 1px;
-}
-.nav-sidebar.sidebar-collapsed-desktop .sidebar-top-level-items > li > a {
- min-height: 45px;
-}
-.nav-sidebar.sidebar-collapsed-desktop .fly-out-top-item {
- display: block;
-}
-.nav-sidebar.sidebar-collapsed-desktop .avatar-container {
- margin: 0 auto;
-}
-.nav-sidebar.sidebar-expanded-mobile {
- left: 0;
-}
-.nav-sidebar a {
+body:not(.sidebar-refactoring) .nav-sidebar a {
text-decoration: none;
}
-.nav-sidebar ul {
+body:not(.sidebar-refactoring) .nav-sidebar ul {
padding-left: 0;
list-style: none;
}
-.nav-sidebar li {
+body:not(.sidebar-refactoring) .nav-sidebar li {
white-space: nowrap;
}
-.nav-sidebar li a {
+body:not(.sidebar-refactoring) .nav-sidebar li a {
display: flex;
align-items: center;
padding: 12px 16px;
color: #666;
}
-.nav-sidebar li .nav-item-name {
+body:not(.sidebar-refactoring) .nav-sidebar li .nav-item-name {
flex: 1;
}
-.nav-sidebar li.active > a {
+body:not(.sidebar-refactoring) .nav-sidebar li.active > a {
font-weight: 600;
}
-
@media (max-width: 767.98px) {
- .nav-sidebar {
+ body:not(.sidebar-refactoring) .nav-sidebar {
left: -220px;
}
}
-.nav-sidebar .nav-icon-container {
+body:not(.sidebar-refactoring) .nav-sidebar .nav-icon-container {
display: flex;
margin-right: 8px;
}
-.nav-sidebar .fly-out-top-item {
+body:not(.sidebar-refactoring) .nav-sidebar .fly-out-top-item {
display: none;
}
-.nav-sidebar svg {
+body:not(.sidebar-refactoring) .nav-sidebar svg {
height: 16px;
width: 16px;
}
-
@media (min-width: 768px) and (max-width: 1199px) {
- .nav-sidebar:not(.sidebar-expanded-mobile) {
+ body:not(.sidebar-refactoring) .nav-sidebar:not(.sidebar-expanded-mobile) {
width: 50px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .nav-sidebar-inner-scroll {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-sidebar-inner-scroll {
overflow-x: hidden;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .badge.badge-pill:not(.fly-out-badge),
- .nav-sidebar:not(.sidebar-expanded-mobile) .sidebar-context-title,
- .nav-sidebar:not(.sidebar-expanded-mobile) .nav-item-name {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .badge.badge-pill:not(.fly-out-badge),
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-item-name {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
@@ -1394,273 +1375,476 @@ input {
white-space: nowrap;
width: 1px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .sidebar-top-level-items > li > a {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-top-level-items
+ > li
+ > a {
min-height: 45px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .fly-out-top-item {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .fly-out-top-item {
display: block;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .avatar-container {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .avatar-container {
margin: 0 auto;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .context-header {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .context-header {
height: 60px;
width: 50px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .context-header a {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .context-header
+ a {
padding: 10px 4px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .sidebar-top-level-items > li .sidebar-sub-level-items:not(.flyout-list) {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-context-title {
+ border: 0;
+ clip: rect(0, 0, 0, 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+ }
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-top-level-items
+ > li
+ .sidebar-sub-level-items:not(.flyout-list) {
display: none;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .nav-icon-container {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-icon-container {
margin-right: 0;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button {
padding: 16px;
width: 49px;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button .collapse-text,
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button .icon-chevron-double-lg-left {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .collapse-text,
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .icon-chevron-double-lg-left {
display: none;
}
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button .icon-chevron-double-lg-right {
+ body:not(.sidebar-refactoring)
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .icon-chevron-double-lg-right {
display: block;
margin: 0;
}
}
-.nav-sidebar-inner-scroll {
+body:not(.sidebar-refactoring) .nav-sidebar-inner-scroll {
height: 100%;
width: 100%;
overflow: auto;
}
-.sidebar-sub-level-items {
+body:not(.sidebar-refactoring) .sidebar-sub-level-items {
display: none;
padding-bottom: 8px;
}
-.sidebar-sub-level-items > li a {
+body:not(.sidebar-refactoring) .sidebar-sub-level-items > li a {
padding: 8px 16px 8px 40px;
}
-.sidebar-top-level-items {
+body:not(.sidebar-refactoring) .sidebar-top-level-items {
margin-bottom: 60px;
}
-
@media (min-width: 576px) {
- .sidebar-top-level-items > li > a {
+ body:not(.sidebar-refactoring) .sidebar-top-level-items > li > a {
margin-right: 1px;
}
}
-.sidebar-top-level-items > li .badge.badge-pill {
+body:not(.sidebar-refactoring) .sidebar-top-level-items > li .badge.badge-pill {
background-color: rgba(0, 0, 0, 0.08);
color: #666;
}
-.sidebar-top-level-items > li.active {
+body:not(.sidebar-refactoring) .sidebar-top-level-items > li.active {
background: rgba(0, 0, 0, 0.04);
}
-.sidebar-top-level-items > li.active > a {
+body:not(.sidebar-refactoring) .sidebar-top-level-items > li.active > a {
margin-left: 4px;
padding-left: 12px;
}
-.sidebar-top-level-items > li.active .badge.badge-pill {
+body:not(.sidebar-refactoring)
+ .sidebar-top-level-items
+ > li.active
+ .badge.badge-pill {
font-weight: 600;
}
-.sidebar-top-level-items > li.active .sidebar-sub-level-items:not(.is-fly-out-only) {
+body:not(.sidebar-refactoring)
+ .sidebar-top-level-items
+ > li.active
+ .sidebar-sub-level-items:not(.is-fly-out-only) {
display: block;
}
-.toggle-sidebar-button,
-.close-nav-button {
- width: 219px;
- position: fixed;
+body:not(.sidebar-refactoring) .toggle-sidebar-button,
+body:not(.sidebar-refactoring) .close-nav-button {
height: 48px;
- bottom: 0;
padding: 0 16px;
background-color: #fafafa;
border: 0;
- border-top: 1px solid #dbdbdb;
color: #666;
display: flex;
align-items: center;
}
-.toggle-sidebar-button svg,
-.close-nav-button svg {
+body:not(.sidebar-refactoring) .toggle-sidebar-button,
+body:not(.sidebar-refactoring) .close-nav-button {
+ position: fixed;
+ bottom: 0;
+ width: 219px;
+ border-top: 1px solid #dbdbdb;
+}
+body:not(.sidebar-refactoring) .toggle-sidebar-button svg,
+body:not(.sidebar-refactoring) .close-nav-button svg {
margin-right: 8px;
}
-.toggle-sidebar-button .icon-chevron-double-lg-right,
-.close-nav-button .icon-chevron-double-lg-right {
+body:not(.sidebar-refactoring)
+ .toggle-sidebar-button
+ .icon-chevron-double-lg-right,
+body:not(.sidebar-refactoring) .close-nav-button .icon-chevron-double-lg-right {
display: none;
}
-.collapse-text {
+body:not(.sidebar-refactoring) .collapse-text {
white-space: nowrap;
overflow: hidden;
}
-.sidebar-collapsed-desktop .context-header {
- height: 60px;
- width: 50px;
-}
-.sidebar-collapsed-desktop .context-header a {
- padding: 10px 4px;
-}
-.sidebar-collapsed-desktop .sidebar-top-level-items > li .sidebar-sub-level-items:not(.flyout-list) {
- display: none;
-}
-.sidebar-collapsed-desktop .nav-icon-container {
- margin-right: 0;
-}
-.sidebar-collapsed-desktop .toggle-sidebar-button {
- padding: 16px;
- width: 49px;
-}
-.sidebar-collapsed-desktop .toggle-sidebar-button .collapse-text,
-.sidebar-collapsed-desktop .toggle-sidebar-button .icon-chevron-double-lg-left {
- display: none;
-}
-.sidebar-collapsed-desktop .toggle-sidebar-button .icon-chevron-double-lg-right {
- display: block;
- margin: 0;
-}
-.fly-out-top-item > a {
+body:not(.sidebar-refactoring) .fly-out-top-item > a {
display: flex;
}
-.fly-out-top-item .fly-out-badge {
+body:not(.sidebar-refactoring) .fly-out-top-item .fly-out-badge {
margin-left: 8px;
}
-.fly-out-top-item-name {
+body:not(.sidebar-refactoring) .fly-out-top-item-name {
flex: 1;
}
-.close-nav-button {
+body:not(.sidebar-refactoring) .close-nav-button {
display: none;
}
-
@media (max-width: 767.98px) {
- .close-nav-button {
+ body:not(.sidebar-refactoring) .close-nav-button {
display: flex;
}
- .toggle-sidebar-button {
+ body:not(.sidebar-refactoring) .toggle-sidebar-button {
display: none;
}
}
-table.table {
- margin-bottom: 16px;
+@media (min-width: 768px) {
+ body.sidebar-refactoring .page-with-contextual-sidebar {
+ padding-left: 50px;
+ }
}
-table.table .dropdown-menu a {
+@media (min-width: 1200px) {
+ body.sidebar-refactoring .page-with-contextual-sidebar {
+ padding-left: 220px;
+ }
+}
+body.sidebar-refactoring .nav-sidebar {
+ position: fixed;
+ z-index: 600;
+ width: 220px;
+ top: 40px;
+ bottom: 0;
+ left: 0;
+ background: linear-gradient(#cbbbf2, #e9be74);
+ box-shadow: inset -1px 0 0 #dbdbdb;
+ transform: translate3d(0, 0, 0);
+}
+@media (min-width: 576px) and (max-width: 576px) {
+ body.sidebar-refactoring .nav-sidebar:not(.sidebar-collapsed-desktop) {
+ box-shadow: inset -1px 0 0 #dbdbdb, 2px 1px 3px rgba(0, 0, 0, 0.1);
+ }
+}
+body.sidebar-refactoring .nav-sidebar a {
text-decoration: none;
}
-table.table .success,
-table.table .info {
- color: #fff;
+body.sidebar-refactoring .nav-sidebar ul {
+ padding-left: 0;
+ list-style: none;
}
-table.table .success a:not(.btn),
-table.table .info a:not(.btn) {
- text-decoration: underline;
- color: #fff;
+body.sidebar-refactoring .nav-sidebar li {
+ white-space: nowrap;
}
-pre {
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
+body.sidebar-refactoring .nav-sidebar li a {
+ display: flex;
+ align-items: center;
+ padding: 12px 16px;
+ color: #666;
+}
+body.sidebar-refactoring .nav-sidebar li .nav-item-name {
+ flex: 1;
+}
+body.sidebar-refactoring .nav-sidebar li.active > a {
+ font-weight: 600;
+}
+@media (max-width: 767.98px) {
+ body.sidebar-refactoring .nav-sidebar {
+ left: -220px;
+ }
+}
+body.sidebar-refactoring .nav-sidebar .nav-icon-container {
+ display: flex;
+ margin-right: 8px;
+}
+body.sidebar-refactoring .nav-sidebar .fly-out-top-item {
+ display: none;
+}
+body.sidebar-refactoring .nav-sidebar svg {
+ height: 16px;
+ width: 16px;
+}
+@media (min-width: 768px) and (max-width: 1199px) {
+ body.sidebar-refactoring .nav-sidebar:not(.sidebar-expanded-mobile) {
+ width: 50px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-sidebar-inner-scroll {
+ overflow-x: hidden;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .badge.badge-pill:not(.fly-out-badge),
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-item-name {
+ border: 0;
+ clip: rect(0, 0, 0, 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-top-level-items
+ > li
+ > a {
+ min-height: 45px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .fly-out-top-item {
+ display: block;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .avatar-container {
+ margin: 0 auto;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .context-header {
+ height: 60px;
+ width: 50px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .context-header
+ a {
+ padding: 10px 4px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-context-title {
+ border: 0;
+ clip: rect(0, 0, 0, 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .sidebar-top-level-items
+ > li
+ .sidebar-sub-level-items:not(.flyout-list) {
+ display: none;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .nav-icon-container {
+ margin-right: 0;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button {
+ padding: 16px;
+ width: 49px;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .collapse-text,
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .icon-chevron-double-lg-left {
+ display: none;
+ }
+ body.sidebar-refactoring
+ .nav-sidebar:not(.sidebar-expanded-mobile)
+ .toggle-sidebar-button
+ .icon-chevron-double-lg-right {
+ display: block;
+ margin: 0;
+ }
+}
+body.sidebar-refactoring .nav-sidebar-inner-scroll {
+ height: 100%;
+ width: 100%;
+ overflow: auto;
+}
+body.sidebar-refactoring .sidebar-sub-level-items {
+ display: none;
+ padding-bottom: 8px;
+}
+body.sidebar-refactoring .sidebar-sub-level-items > li a {
+ padding: 8px 16px 8px 40px;
+}
+body.sidebar-refactoring .sidebar-top-level-items {
+ margin-bottom: 60px;
+}
+@media (min-width: 576px) {
+ body.sidebar-refactoring .sidebar-top-level-items > li > a {
+ margin-right: 1px;
+ }
+}
+body.sidebar-refactoring .sidebar-top-level-items > li .badge.badge-pill {
+ background-color: rgba(0, 0, 0, 0.08);
+ color: #666;
+}
+body.sidebar-refactoring .sidebar-top-level-items > li.active {
+ background: rgba(0, 0, 0, 0.04);
+}
+body.sidebar-refactoring .sidebar-top-level-items > li.active > a {
+ margin-left: 4px;
+ padding-left: 12px;
+}
+body.sidebar-refactoring
+ .sidebar-top-level-items
+ > li.active
+ .badge.badge-pill {
+ font-weight: 600;
+}
+body.sidebar-refactoring
+ .sidebar-top-level-items
+ > li.active
+ .sidebar-sub-level-items:not(.is-fly-out-only) {
display: block;
- padding: 8px 12px;
- margin: 0 0 8px;
- font-size: 13px;
- word-break: break-all;
- word-wrap: break-word;
- color: #303030;
+}
+body.sidebar-refactoring .toggle-sidebar-button,
+body.sidebar-refactoring .close-nav-button {
+ height: 48px;
+ padding: 0 16px;
background-color: #fafafa;
- border: 1px solid #dbdbdb;
- border-radius: 2px;
+ border: 0;
+ color: #666;
+ display: flex;
+ align-items: center;
}
-.monospace {
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
+body.sidebar-refactoring .toggle-sidebar-button,
+body.sidebar-refactoring .close-nav-button {
+ position: fixed;
+ bottom: 0;
+ width: 219px;
+ border-top: 1px solid #dbdbdb;
}
-input::-moz-placeholder,
-textarea::-moz-placeholder {
+body.sidebar-refactoring .toggle-sidebar-button svg,
+body.sidebar-refactoring .close-nav-button svg {
+ margin-right: 8px;
+}
+body.sidebar-refactoring .toggle-sidebar-button .icon-chevron-double-lg-right,
+body.sidebar-refactoring .close-nav-button .icon-chevron-double-lg-right {
+ display: none;
+}
+body.sidebar-refactoring .collapse-text {
+ white-space: nowrap;
+ overflow: hidden;
+}
+body.sidebar-refactoring .fly-out-top-item > a {
+ display: flex;
+}
+body.sidebar-refactoring .fly-out-top-item .fly-out-badge {
+ margin-left: 8px;
+}
+body.sidebar-refactoring .fly-out-top-item-name {
+ flex: 1;
+}
+body.sidebar-refactoring .close-nav-button {
+ display: none;
+}
+@media (max-width: 767.98px) {
+ body.sidebar-refactoring .close-nav-button {
+ display: flex;
+ }
+ body.sidebar-refactoring .toggle-sidebar-button {
+ display: none;
+ }
+}
+input::-moz-placeholder {
color: #868686;
opacity: 1;
}
-input::-ms-input-placeholder,
-textarea::-ms-input-placeholder {
+input::-ms-input-placeholder {
color: #868686;
}
-input:-ms-input-placeholder,
-textarea:-ms-input-placeholder {
+input:-ms-input-placeholder {
color: #868686;
}
svg {
fill: currentColor;
}
-
svg.s12 {
width: 12px;
height: 12px;
}
-
svg.s16 {
width: 16px;
height: 16px;
}
-
svg.s18 {
width: 18px;
height: 18px;
}
-
svg.s12 {
vertical-align: -1px;
}
-
svg.s16 {
vertical-align: -3px;
}
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0;
-}
-table.code {
+.js-groups-dropdown {
width: 100%;
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
- border: 0;
- border-collapse: separate;
- margin: 0;
- padding: 0;
- table-layout: fixed;
- border-radius: 0 0 4px 4px;
-}
-.frame .badge.badge-pill {
- position: absolute;
- background-color: #428fdc;
- color: #fff;
- border: #fff 1px solid;
- min-height: 16px;
- padding: 5px 8px;
- border-radius: 12px;
-}
-.frame .badge.badge-pill {
- transform: translate(-50%, -50%);
-}
-.color-label {
- padding: 0 0.5rem;
- line-height: 16px;
- border-radius: 100px;
- color: #fff;
-}
-.label-link {
- display: inline-flex;
- vertical-align: text-bottom;
-}
-.milestones {
- padding: 8px;
- margin-top: 8px;
- border-radius: 4px;
- background-color: #dbdbdb;
}
.search {
margin: 0 8px;
}
.search form {
+ display: block;
margin: 0;
padding: 4px;
width: 200px;
@@ -1669,7 +1853,6 @@ table.code {
border: 0;
border-radius: 4px;
}
-
@media (min-width: 1200px) {
.search form {
width: 320px;
@@ -1708,12 +1891,17 @@ table.code {
.search .search-input-wrap .dropdown {
position: static;
}
+.search .search-input-wrap .dropdown-header {
+ font-weight: 600;
+ color: #303030;
+ font-size: 0.875rem;
+ line-height: 16px;
+}
.search .search-input-wrap .dropdown-menu {
left: -5px;
max-height: 400px;
overflow: auto;
}
-
@media (min-width: 1200px) {
.search .search-input-wrap .dropdown-menu {
width: 320px;
@@ -1722,34 +1910,27 @@ table.code {
.search .search-input-wrap .dropdown-content {
max-height: 382px;
}
-.settings {
- border-top: 1px solid #dbdbdb;
-}
-.settings:first-of-type {
- margin-top: 10px;
- border: 0;
-}
-.settings + div .settings:first-of-type {
- margin-top: 0;
- border-top: 1px solid #dbdbdb;
-}
-.avatar, .avatar-container {
+.avatar,
+.avatar-container {
float: left;
margin-right: 16px;
border-radius: 50%;
border: 1px solid #f5f5f5;
}
-.s16.avatar, .s16.avatar-container {
+.avatar.s16,
+.avatar-container.s16 {
width: 16px;
height: 16px;
margin-right: 8px;
}
-.s18.avatar, .s18.avatar-container {
+.avatar.s18,
+.avatar-container.s18 {
width: 18px;
height: 18px;
margin-right: 8px;
}
-.s40.avatar, .s40.avatar-container {
+.avatar.s40,
+.avatar-container.s40 {
width: 40px;
height: 40px;
margin-right: 8px;
@@ -1763,11 +1944,6 @@ table.code {
overflow: hidden;
border-color: rgba(0, 0, 0, 0.1);
}
-.avatar.center {
- font-size: 14px;
- line-height: 1.8em;
- text-align: center;
-}
.avatar.avatar-tile {
border-radius: 0;
border: 0;
@@ -1806,6 +1982,18 @@ table.code {
.rect-avatar.s40 {
border-radius: 4px;
}
+#content-body {
+ display: block;
+}
+
+@keyframes gl-spinner-rotate {
+ 0% {
+ transform: rotate(0);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
.tab-width-8 {
-moz-tab-size: 8;
tab-size: 8;
@@ -1821,12 +2009,61 @@ table.code {
white-space: nowrap;
width: 1px;
}
+@keyframes gl-spinner-rotate {
+ 0% {
+ transform: rotate(0);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+.gl-border-solid {
+ border-style: solid;
+}
+.gl-border-gray-100 {
+ border-color: #dbdbdb;
+}
+.gl-border-0 {
+ border-width: 0;
+}
+.gl-border-t-1 {
+ border-top-width: 1px;
+}
+.gl-display-flex\! {
+ display: flex !important;
+}
+.gl-align-items-center {
+ align-items: center;
+}
+.gl-justify-content-space-between {
+ justify-content: space-between;
+}
+.gl-absolute {
+ position: absolute;
+}
+.gl-px-3\! {
+ padding-left: 0.5rem !important;
+ padding-right: 0.5rem !important;
+}
+.gl-mt-7 {
+ margin-top: 2rem;
+}
+.gl-ml-auto {
+ margin-left: auto;
+}
.gl-ml-3 {
margin-left: 0.5rem;
}
-.content-wrapper > .alert-wrapper,
-#content-body, .modal-dialog {
- display: block;
+.gl-mx-0\! {
+ margin-left: 0 !important;
+ margin-right: 0 !important;
}
-@import 'cloaking';
+.gl-font-weight-bold {
+ font-weight: 600;
+}
+.gl-line-height-20\! {
+ line-height: 1.25rem !important;
+}
+
+@import "cloaking";
@include cloak-startup-scss(none);
diff --git a/app/assets/stylesheets/startup/startup-signin.scss b/app/assets/stylesheets/startup/startup-signin.scss
index 6b78abdb5e0..ccc67c23dd3 100644
--- a/app/assets/stylesheets/startup/startup-signin.scss
+++ b/app/assets/stylesheets/startup/startup-signin.scss
@@ -1,3 +1,6 @@
+// DO NOT EDIT! This is auto-generated from "yarn run generate:startup_css"
+// Please see the feedback issue for more details and help:
+// https://gitlab.com/gitlab-org/gitlab/-/issues/331812
@charset "UTF-8";
*,
*::before,
@@ -8,12 +11,14 @@ html {
font-family: sans-serif;
line-height: 1.15;
}
- header, nav, section {
+header {
display: block;
}
body {
margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans", Ubuntu, Cantarell, "Helvetica Neue", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ "Noto Sans", Ubuntu, Cantarell, "Helvetica Neue", sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
@@ -26,7 +31,8 @@ hr {
height: 0;
overflow: visible;
}
-h1, h2, h3 {
+h1,
+h3 {
margin-top: 0;
margin-bottom: 0.25rem;
}
@@ -39,47 +45,20 @@ address {
font-style: normal;
line-height: inherit;
}
-
-ul {
- margin-top: 0;
- margin-bottom: 1rem;
-}
-
-ul ul {
- margin-bottom: 0;
-}
-
-strong {
- font-weight: bolder;
-}
-sub {
- position: relative;
- font-size: 75%;
- line-height: 0;
- vertical-align: baseline;
-}
-sub {
- bottom: -.25em;
-}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
-a:not([href]) {
+a:not([href]):not([class]) {
color: inherit;
text-decoration: none;
}
-pre,
code {
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
+ font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas",
+ "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
font-size: 1em;
}
-pre {
- margin-top: 0;
- margin-bottom: 1rem;
- overflow: auto;
-}
img {
vertical-align: middle;
border-style: none;
@@ -88,89 +67,54 @@ svg {
overflow: hidden;
vertical-align: middle;
}
-table {
- border-collapse: collapse;
-}
-th {
- text-align: inherit;
-}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
-button {
- border-radius: 0;
-}
-input,
-button,
-textarea {
+input {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
-button,
input {
overflow: visible;
}
-button {
- text-transform: none;
-}
-button:not(:disabled),
-[type="button"]:not(:disabled),
-[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
cursor: pointer;
}
-button::-moz-focus-inner,
-[type="button"]::-moz-focus-inner,
-[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
-
-input[type="checkbox"] {
- box-sizing: border-box;
- padding: 0;
-}
-textarea {
- overflow: auto;
- resize: vertical;
-}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
-[type="search"] {
- outline-offset: -2px;
-}
summary {
display: list-item;
cursor: pointer;
}
-template {
- display: none;
-}
[hidden] {
display: none !important;
}
-h1, h2, h3,
-.h1, .h2, .h3 {
+h1,
+h3,
+.h1,
+.h3 {
margin-bottom: 0.25rem;
font-weight: 600;
line-height: 1.2;
color: #303030;
}
-h1, .h1 {
+h1,
+.h1 {
font-size: 2.1875rem;
}
-h2, .h2 {
- font-size: 1.75rem;
-}
-h3, .h3 {
+h3,
+.h3 {
font-size: 1.53125rem;
}
hr {
@@ -179,10 +123,6 @@ hr {
border: 0;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
-.list-unstyled {
- padding-left: 0;
- list-style: none;
-}
code {
font-size: 90%;
color: #1f1f1f;
@@ -191,16 +131,6 @@ code {
a > code {
color: inherit;
}
-pre {
- display: block;
- font-size: 90%;
- color: #303030;
-}
-pre code {
- font-size: inherit;
- color: inherit;
- word-break: normal;
-}
.container {
width: 100%;
padding-right: 15px;
@@ -208,56 +138,21 @@ pre code {
margin-right: auto;
margin-left: auto;
}
-
@media (min-width: 576px) {
.container {
max-width: 540px;
}
}
-
@media (min-width: 768px) {
.container {
max-width: 720px;
}
}
-
@media (min-width: 992px) {
.container {
max-width: 960px;
}
}
-
-@media (min-width: 1200px) {
- .container {
- max-width: 1140px;
- }
-}
-.container-fluid {
- width: 100%;
- padding-right: 15px;
- padding-left: 15px;
- margin-right: auto;
- margin-left: auto;
-}
-
-@media (min-width: 576px) {
- .container {
- max-width: 540px;
- }
-}
-
-@media (min-width: 768px) {
- .container {
- max-width: 720px;
- }
-}
-
-@media (min-width: 992px) {
- .container {
- max-width: 960px;
- }
-}
-
@media (min-width: 1200px) {
.container {
max-width: 1140px;
@@ -269,19 +164,26 @@ pre code {
margin-right: -15px;
margin-left: -15px;
}
- .col-sm-5, .col-sm-7, .col-sm-12 {
+.col,
+.col-sm-5,
+.col-sm-7,
+.col-sm-12 {
position: relative;
width: 100%;
padding-right: 15px;
padding-left: 15px;
}
+.col {
+ flex-basis: 0;
+ flex-grow: 1;
+ max-width: 100%;
+}
.order-1 {
order: 1;
}
.order-12 {
order: 12;
}
-
@media (min-width: 576px) {
.col-sm-5 {
flex: 0 0 41.66667%;
@@ -302,18 +204,7 @@ pre code {
order: 12;
}
}
-.table {
- width: 100%;
- margin-bottom: 0.5rem;
- color: #303030;
-}
-.table th,
-.table td {
- padding: 0.75rem;
- vertical-align: top;
- border-top: 1px solid #dbdbdb;
-}
-.form-control, .search form {
+.form-control {
display: block;
width: 100%;
height: 34px;
@@ -327,52 +218,37 @@ pre code {
border: 1px solid #dbdbdb;
border-radius: 0.25rem;
}
-
@media (prefers-reduced-motion: reduce) {
}
-.form-control:-moz-focusring, .search form:-moz-focusring {
+.form-control:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #303030;
}
-.form-control::placeholder, .search form::placeholder {
+.form-control::-ms-input-placeholder {
color: #5e5e5e;
opacity: 1;
}
-.form-control:disabled, .search form:disabled {
- background-color: #fafafa;
+.form-control::placeholder {
+ color: #5e5e5e;
opacity: 1;
}
-textarea.form-control {
- height: auto;
+.form-control:disabled {
+ background-color: #fafafa;
+ opacity: 1;
}
.form-group {
margin-bottom: 1rem;
}
-.form-inline {
+.form-row {
display: flex;
- flex-flow: row wrap;
- align-items: center;
+ flex-wrap: wrap;
+ margin-right: -5px;
+ margin-left: -5px;
}
-
-@media (min-width: 576px) {
- .form-inline label {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 0;
- }
- .form-inline .form-group {
- display: flex;
- flex: 0 0 auto;
- flex-flow: row wrap;
- align-items: center;
- margin-bottom: 0;
- }
- .form-inline .form-control, .form-inline .search form, .search .form-inline form {
- display: inline-block;
- width: auto;
- vertical-align: middle;
- }
+.form-row > .col,
+.form-row > [class*="col-"] {
+ padding-right: 5px;
+ padding-left: 5px;
}
.btn {
display: inline-block;
@@ -380,7 +256,7 @@ textarea.form-control {
color: #303030;
text-align: center;
vertical-align: middle;
- cursor: pointer;
+ -moz-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
@@ -389,148 +265,17 @@ textarea.form-control {
line-height: 20px;
border-radius: 0.25rem;
}
-
@media (prefers-reduced-motion: reduce) {
}
-.btn.disabled, .btn:disabled {
+.btn:disabled {
opacity: 0.65;
}
-a.btn.disabled,
+.btn:not(:disabled):not(.disabled) {
+ cursor: pointer;
+}
fieldset:disabled a.btn {
pointer-events: none;
}
-.btn-success {
- color: #fff;
- background-color: #108548;
- border-color: #108548;
-}
-.btn-success.disabled, .btn-success:disabled {
- color: #fff;
- background-color: #108548;
- border-color: #108548;
-}
-.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,
-.show > .btn-success.dropdown-menu-toggle {
- color: #fff;
- background-color: #0b572f;
- border-color: #094c29;
-}
- .login-page input[type='submit'] {
- display: block;
- width: 100%;
-}
- .login-page input[type='submit'] + input[type='submit'] {
- margin-top: 0.5rem;
-}
- .login-page input[type="submit"][type='submit'],
-.login-page input[type="reset"][type='submit'],
-.login-page input[type="button"][type='submit'] {
- width: 100%;
-}
-.collapse:not(.show) {
- display: none;
-}
-
-.dropdown {
- position: relative;
-}
- .dropdown-menu-toggle {
- white-space: nowrap;
-}
- .dropdown-menu-toggle::after {
- display: inline-block;
- margin-left: 0.255em;
- vertical-align: 0.255em;
- content: "";
- border-top: 0.3em solid;
- border-right: 0.3em solid transparent;
- border-bottom: 0;
- border-left: 0.3em solid transparent;
-}
- .dropdown-menu-toggle:empty::after {
- margin-left: 0;
-}
-.dropdown-menu {
- position: absolute;
- top: 100%;
- left: 0;
- z-index: 1000;
- display: none;
- float: left;
- min-width: 10rem;
- padding: 0.5rem 0;
- margin: 0.125rem 0 0;
- font-size: 1rem;
- color: #303030;
- text-align: left;
- list-style: none;
- background-color: #fff;
- background-clip: padding-box;
- border: 1px solid rgba(0, 0, 0, 0.15);
- border-radius: 0.25rem;
-}
-.dropdown-menu-right {
- right: 0;
- left: auto;
-}
- .divider {
- height: 0;
- margin: 4px 0;
- overflow: hidden;
- border-top: 1px solid #dbdbdb;
-}
-.dropdown-menu.show {
- display: block;
-}
-.nav {
- display: flex;
- flex-wrap: wrap;
- padding-left: 0;
- margin-bottom: 0;
- list-style: none;
-}
-.nav-link {
- display: block;
- padding: 0.5rem 1rem;
-}
-.nav-link.disabled {
- color: #5e5e5e;
- pointer-events: none;
- cursor: default;
-}
-.nav-tabs {
- border-bottom: 1px solid #999;
-}
-.nav-tabs .nav-item {
- margin-bottom: -1px;
-}
-.nav-tabs .nav-link {
- border: 1px solid transparent;
- border-top-left-radius: 0.25rem;
- border-top-right-radius: 0.25rem;
-}
-.nav-tabs .nav-link.disabled {
- color: #5e5e5e;
- background-color: transparent;
- border-color: transparent;
-}
-.nav-tabs .nav-link.active,
-.nav-tabs .nav-item.show .nav-link {
- color: #525252;
- background-color: #fff;
- border-color: #999 #999 #fff;
-}
-.nav-tabs .dropdown-menu {
- margin-top: -1px;
- border-top-left-radius: 0;
- border-top-right-radius: 0;
-}
-.tab-content > .tab-pane {
- display: none;
-}
-.tab-content > .active {
- display: block;
-}
.navbar {
position: relative;
display: flex;
@@ -539,77 +284,12 @@ fieldset:disabled a.btn {
justify-content: space-between;
padding: 0.25rem 0.5rem;
}
-.navbar .container,
-.navbar .container-fluid {
+.navbar .container {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
}
-.navbar-nav {
- display: flex;
- flex-direction: column;
- padding-left: 0;
- margin-bottom: 0;
- list-style: none;
-}
-.navbar-nav .nav-link {
- padding-right: 0;
- padding-left: 0;
-}
-.navbar-nav .dropdown-menu {
- position: static;
- float: none;
-}
-.navbar-collapse {
- flex-basis: 100%;
- flex-grow: 1;
- align-items: center;
-}
-.navbar-toggler {
- padding: 0.25rem 0.75rem;
- font-size: 1.25rem;
- line-height: 1;
- background-color: transparent;
- border: 1px solid transparent;
- border-radius: 0.25rem;
-}
-
-@media (max-width: 575.98px) {
- .navbar-expand-sm > .container,
- .navbar-expand-sm > .container-fluid {
- padding-right: 0;
- padding-left: 0;
- }
-}
-
-@media (min-width: 576px) {
- .navbar-expand-sm {
- flex-flow: row nowrap;
- justify-content: flex-start;
- }
- .navbar-expand-sm .navbar-nav {
- flex-direction: row;
- }
- .navbar-expand-sm .navbar-nav .dropdown-menu {
- position: absolute;
- }
- .navbar-expand-sm .navbar-nav .nav-link {
- padding-right: 0.5rem;
- padding-left: 0.5rem;
- }
- .navbar-expand-sm > .container,
- .navbar-expand-sm > .container-fluid {
- flex-wrap: nowrap;
- }
- .navbar-expand-sm .navbar-collapse {
- display: flex !important;
- flex-basis: auto;
- }
- .navbar-expand-sm .navbar-toggler {
- display: none;
- }
-}
.card {
position: relative;
display: flex;
@@ -625,132 +305,12 @@ fieldset:disabled a.btn {
margin-right: 0;
margin-left: 0;
}
-.badge {
- display: inline-block;
- padding: 0.25em 0.4em;
- font-size: 75%;
- font-weight: 600;
- line-height: 1;
- text-align: center;
- white-space: nowrap;
- vertical-align: baseline;
- border-radius: 0.25rem;
-}
-
-@media (prefers-reduced-motion: reduce) {
-}
-.badge:empty {
- display: none;
-}
-.btn .badge {
- position: relative;
- top: -1px;
-}
-.badge-pill {
- padding-right: 0.6em;
- padding-left: 0.6em;
- border-radius: 10rem;
-}
-.media {
- display: flex;
- align-items: flex-start;
-}
-.close {
- float: right;
- font-size: 1.5rem;
- font-weight: 600;
- line-height: 1;
- color: #000;
- text-shadow: 0 1px 0 #fff;
- opacity: .5;
-}
-button.close {
- padding: 0;
- background-color: transparent;
- border: 0;
- appearance: none;
-}
-a.close.disabled {
- pointer-events: none;
-}
-.modal-dialog {
- position: relative;
- width: auto;
- margin: 0.5rem;
- pointer-events: none;
-}
-
-@media (min-width: 576px) {
- .modal-dialog {
- max-width: 500px;
- margin: 1.75rem auto;
- }
-}
-.bg-transparent {
- background-color: transparent !important;
-}
-.border {
- border: 1px solid #dbdbdb !important;
-}
-.border-top {
- border-top: 1px solid #dbdbdb !important;
-}
-.border-right {
- border-right: 1px solid #dbdbdb !important;
-}
-.border-bottom {
- border-bottom: 1px solid #dbdbdb !important;
-}
-.border-left {
- border-left: 1px solid #dbdbdb !important;
-}
-.rounded {
- border-radius: 0.25rem !important;
-}
-.clearfix::after {
- display: block;
- clear: both;
- content: "";
-}
-.d-none {
- display: none !important;
-}
-.d-inline-block {
- display: inline-block !important;
-}
.d-block {
display: block !important;
}
.d-flex {
display: flex !important;
}
-
-@media (min-width: 576px) {
- .d-sm-none {
- display: none !important;
- }
-}
-
-@media (min-width: 768px) {
- .d-md-block {
- display: block !important;
- }
-}
-
-@media (min-width: 992px) {
- .d-lg-none {
- display: none !important;
- }
- .d-lg-block {
- display: block !important;
- }
-}
-
-@media (min-width: 1200px) {
- .d-xl-block {
- display: block !important;
- }
-}
.flex-wrap {
flex-wrap: wrap !important;
}
@@ -760,9 +320,6 @@ a.close.disabled {
.align-items-center {
align-items: center !important;
}
-.float-right {
- float: right !important;
-}
.fixed-top {
position: fixed;
top: 0;
@@ -770,16 +327,8 @@ a.close.disabled {
left: 0;
z-index: 1030;
}
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- white-space: nowrap;
- border: 0;
+.ml-2 {
+ margin-left: 0.5rem !important;
}
.mt-3 {
margin-top: 1rem !important;
@@ -787,81 +336,122 @@ a.close.disabled {
.mb-3 {
margin-bottom: 1rem !important;
}
-.m-auto {
- margin: auto !important;
-}
-
@media (min-width: 576px) {
.mt-sm-0 {
margin-top: 0 !important;
}
}
-.text-nowrap {
- white-space: nowrap !important;
-}
-.text-left {
- text-align: left !important;
+.text-center {
+ text-align: center !important;
}
.font-weight-normal {
font-weight: 400 !important;
}
-.visible {
- visibility: visible !important;
-}
-.form-control.focus, .search form.focus {
- color: #303030;
+.gl-form-input,
+.gl-form-input.form-control {
background-color: #fff;
- border-color: #80bdff;
- outline: 0;
- box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
-}
-input[type="color"].form-control {
- height: 34px;
- padding: 0.125rem 0.25rem;
-}
-input[type="color"].form-control:disabled {
- background-color: #666;
- opacity: 0.65;
-}
-.gl-badge {
- display: inline-flex;
- align-items: center;
- font-size: 0.75rem;
- font-weight: 400;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ "Noto Sans", Ubuntu, Cantarell, "Helvetica Neue", sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ font-size: 0.875rem;
line-height: 1rem;
- padding-top: 0.25rem;
- padding-bottom: 0.25rem;
- padding-left: 0.5rem;
- padding-right: 0.5rem;
- outline: none;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+ height: auto;
+ color: #303030;
+ box-shadow: inset 0 0 0 1px #868686;
+ border-style: none;
+ appearance: none;
+ -moz-appearance: none;
}
-body, .form-control, .search form,
-.search form {
+.gl-form-input:not(.form-control-plaintext):-moz-read-only,
+.gl-form-input.form-control:not(.form-control-plaintext):-moz-read-only {
+ background-color: #fafafa;
+ color: #868686;
+ box-shadow: inset 0 0 0 1px #dbdbdb;
+ cursor: not-allowed;
+}
+.gl-form-input:disabled,
+.gl-form-input:not(.form-control-plaintext):read-only,
+.gl-form-input.form-control:disabled,
+.gl-form-input.form-control:not(.form-control-plaintext):read-only {
+ background-color: #fafafa;
+ color: #868686;
+ box-shadow: inset 0 0 0 1px #dbdbdb;
+ cursor: not-allowed;
+}
+.gl-form-input::-ms-input-placeholder,
+.gl-form-input.form-control::-ms-input-placeholder {
+ color: #868686;
+}
+.gl-form-input::placeholder,
+.gl-form-input.form-control::placeholder {
+ color: #868686;
+}
+.gl-button {
+ display: inline-flex;
+}
+.gl-button.gl-button {
+ border-width: 0;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+ background-color: transparent;
+ line-height: 1rem;
+ color: #303030;
+ fill: currentColor;
+ box-shadow: inset 0 0 0 1px #bfbfbf;
+ justify-content: center;
+ align-items: center;
+ font-size: 0.875rem;
+ border-radius: 0.25rem;
+}
+.gl-button.gl-button .gl-button-icon {
+ height: 1rem;
+ width: 1rem;
+ flex-shrink: 0;
+ margin-right: 0.25rem;
+ top: auto;
+}
+.gl-button.gl-button.btn-default {
+ background-color: #fff;
+}
+.gl-button.gl-button.btn-default:active {
+ box-shadow: inset 0 0 0 2px #5e5e5e, 0 0 0 1px rgba(255, 255, 255, 0.4),
+ 0 0 0 4px rgba(31, 117, 203, 0.48);
+ outline: none;
+ background-color: #dbdbdb;
+}
+.gl-button.gl-button.btn-confirm {
+ color: #fff;
+}
+.gl-button.gl-button.btn-confirm {
+ background-color: #1f75cb;
+ box-shadow: inset 0 0 0 1px #1068bf;
+}
+.gl-button.gl-button.btn-confirm:active {
+ box-shadow: inset 0 0 0 2px #033464, 0 0 0 1px rgba(255, 255, 255, 0.4),
+ 0 0 0 4px rgba(31, 117, 203, 0.48);
+ outline: none;
+ background-color: #0b5cad;
+}
+body,
+.form-control {
font-size: 0.875rem;
}
-button,
-html [type='button'],
-[type='reset'],
-[type='submit'],
-[role='button'] {
+[type="submit"] {
cursor: pointer;
}
h1,
.h1,
-h2,
-.h2,
h3,
.h3 {
margin-top: 20px;
margin-bottom: 10px;
}
-input[type='file'] {
- line-height: 1;
-}
-
-strong {
- font-weight: bold;
-}
a {
color: #1068bf;
}
@@ -878,9 +468,6 @@ code {
background-color: inherit;
padding: unset;
}
-table {
- border-spacing: 0;
-}
.hidden {
display: none !important;
visibility: hidden !important;
@@ -888,10 +475,6 @@ table {
.hide {
display: none;
}
- .dropdown-menu-toggle::after {
- display: none;
-}
-.badge:not(.gl-badge),
.label {
padding: 4px 5px;
font-size: 12px;
@@ -899,28 +482,6 @@ table {
font-weight: 400;
display: inline-block;
}
-.nav-tabs {
- border-bottom: 0;
-}
-.nav-tabs .nav-link {
- border-top: 0;
- border-left: 0;
- border-right: 0;
-}
-.nav-tabs .nav-item {
- margin-bottom: 0;
-}
-pre code {
- white-space: pre-wrap;
-}
-input[type="color"].form-control {
- height: 34px;
-}
-.toggle-sidebar-button .collapse-text,
-.toggle-sidebar-button .icon-chevron-double-lg-left,
-.toggle-sidebar-button .icon-chevron-double-lg-right {
- color: #666;
-}
svg {
vertical-align: baseline;
}
@@ -933,10 +494,6 @@ body {
body.navless {
background-color: #fff !important;
}
-.content-wrapper {
- margin-top: 40px;
- padding-bottom: 100px;
-}
.container {
padding-top: 0;
z-index: 5;
@@ -944,13 +501,11 @@ body.navless {
.container .content {
margin: 0;
}
-
@media (max-width: 575.98px) {
.container .content {
margin-top: 20px;
}
}
-
@media (max-width: 575.98px) {
.container .container .title {
padding-left: 15px !important;
@@ -971,259 +526,31 @@ body.navless {
color: #303030;
white-space: nowrap;
}
-.btn:active, .btn.active {
- box-shadow: rgba(0, 0, 0, 0.16);
+.btn:active {
background-color: #eaeaea;
border-color: #e3e3e3;
color: #303030;
}
-.btn.btn-success {
- background-color: #108548;
- border-color: #217645;
- color: #fff;
-}
-.btn.btn-success:active, .btn.btn-success.active {
- box-shadow: rgba(0, 0, 0, 0.16);
- background-color: #24663b;
- border-color: #0d532a;
- color: #fff;
-}
.btn svg {
height: 15px;
width: 15px;
}
-.btn svg:not(:last-child),
-.btn .fa:not(:last-child) {
+.btn svg:not(:last-child) {
margin-right: 5px;
}
- .login-page input[type='submit'] {
- width: 100%;
- margin: 0;
- margin-bottom: 15px;
-}
- .login-page input.btn[type='submit'] {
- padding: 6px 0;
-}
-.badge.badge-pill:not(.gl-badge) {
- font-weight: 400;
- background-color: rgba(0, 0, 0, 0.07);
- color: #525252;
- vertical-align: baseline;
-}
-.hint {
- font-style: italic;
- color: #bfbfbf;
-}
-.bold {
- font-weight: 600;
-}
-.tab-content {
- overflow: visible;
-}
-pre.wrap {
- word-break: break-word;
- white-space: pre-wrap;
+.light {
+ color: #303030;
}
hr {
- margin: 24px 0;
+ margin: 1.5rem 0;
border-top: 1px solid #eee;
}
-table a code {
- position: relative;
- top: -2px;
- margin-right: 3px;
-}
-.loading {
- margin: 20px auto;
- height: 40px;
- color: #525252;
- font-size: 32px;
- text-align: center;
-}
-.highlight {
- text-shadow: none;
-}
-.chart {
- overflow: hidden;
- height: 220px;
-}
.footer-links {
margin-bottom: 20px;
}
.footer-links a {
margin-right: 15px;
}
-.break-word {
- word-wrap: break-word;
-}
-.append-bottom-20 {
- margin-bottom: 20px;
-}
-.center {
- text-align: center;
-}
-.block {
- display: block;
-}
-.flex {
- display: flex;
-}
-.flex-grow {
- flex-grow: 1;
-}
-.dropdown {
- position: relative;
-}
-.show.dropdown .dropdown-menu {
- transform: translateY(0);
- display: block;
- min-height: 40px;
- max-height: 312px;
- overflow-y: auto;
-}
-
-@media (max-width: 575.98px) {
- .show.dropdown .dropdown-menu {
- width: 100%;
- }
-}
- .show.dropdown .dropdown-menu-toggle,
-.show.dropdown .dropdown-menu-toggle {
- border-color: #c4c4c4;
-}
-.show.dropdown [data-toggle='dropdown'] {
- outline: 0;
-}
-.search-input-container .dropdown-menu {
- margin-top: 11px;
-}
- .dropdown-menu-toggle {
- padding: 6px 8px 6px 10px;
- background-color: #fff;
- color: #303030;
- font-size: 14px;
- text-align: left;
- border: 1px solid #dbdbdb;
- border-radius: 0.25rem;
- white-space: nowrap;
-}
- .no-outline.dropdown-menu-toggle {
- outline: 0;
-}
- .dropdown-menu-toggle .fa {
- color: #c4c4c4;
-}
-.dropdown-menu-toggle {
- padding-right: 25px;
- position: relative;
- width: 160px;
- text-overflow: ellipsis;
- overflow: hidden;
-}
-.dropdown-menu-toggle .fa {
- position: absolute;
-}
-.dropdown-menu {
- display: none;
- position: absolute;
- width: auto;
- top: 100%;
- z-index: 300;
- min-width: 240px;
- max-width: 500px;
- margin-top: 4px;
- margin-bottom: 24px;
- font-size: 14px;
- font-weight: 400;
- padding: 8px 0;
- background-color: #fff;
- border: 1px solid #dbdbdb;
- border-radius: 0.25rem;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-}
-.dropdown-menu ul {
- margin: 0;
- padding: 0;
-}
-.dropdown-menu li {
- display: block;
- text-align: left;
- list-style: none;
- padding: 0 1px;
-}
-.dropdown-menu li > a,
-.dropdown-menu li button {
- background: transparent;
- border: 0;
- border-radius: 0;
- box-shadow: none;
- display: block;
- font-weight: 400;
- position: relative;
- padding: 8px 12px;
- color: #303030;
- line-height: 16px;
- white-space: normal;
- overflow: hidden;
- text-align: left;
- width: 100%;
-}
-.dropdown-menu .divider {
- height: 1px;
- margin: 0.25rem 0;
- padding: 0;
- background-color: #dbdbdb;
-}
-.dropdown-menu .badge.badge-pill + span:not(.badge):not(.badge-pill) {
- margin-right: 40px;
-}
-.dropdown-select {
- width: 300px;
-}
-
-@media (max-width: 767.98px) {
- .dropdown-select {
- width: 100%;
- }
-}
-.dropdown-content {
- max-height: 252px;
- overflow-y: auto;
-}
-.dropdown-loading {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- display: none;
- z-index: 9;
- background-color: rgba(255, 255, 255, 0.6);
- font-size: 28px;
-}
-.dropdown-loading .fa {
- position: absolute;
- top: 50%;
- left: 50%;
- margin-top: -14px;
- margin-left: -14px;
-}
-
-@media (max-width: 575.98px) {
- .navbar-gitlab li.dropdown {
- position: static;
- }
- header.navbar-gitlab .dropdown .dropdown-menu {
- width: 100%;
- min-width: 100%;
- }
-}
-
-@media (max-width: 767.98px) {
- .dropdown-menu-toggle {
- width: 100%;
- }
-}
.flash-container {
margin: 0;
margin-bottom: 16px;
@@ -1232,8 +559,8 @@ table a code {
z-index: 1;
}
.flash-container.sticky {
- position: sticky;
position: -webkit-sticky;
+ position: sticky;
top: 48px;
z-index: 251;
}
@@ -1243,9 +570,6 @@ table a code {
.flash-container:empty {
margin: 0;
}
-textarea {
- resize: vertical;
-}
input {
border-radius: 0.25rem;
color: #303030;
@@ -1257,809 +581,61 @@ label {
label.label-bold {
font-weight: 600;
}
-.form-control, .search form {
+.form-control {
border-radius: 4px;
padding: 6px 10px;
}
-.form-control::placeholder, .search form::placeholder {
+.form-control::-ms-input-placeholder {
color: #868686;
}
-.gl-field-error {
- color: #dd2b0e;
- font-size: 0.875rem;
+.form-control::placeholder {
+ color: #868686;
}
-.gl-show-field-errors .form-control:not(textarea), .gl-show-field-errors .search form:not(textarea), .search .gl-show-field-errors form:not(textarea) {
+.gl-show-field-errors .form-control:not(textarea) {
height: 34px;
}
.gl-show-field-errors .gl-field-hint {
color: #303030;
}
-
-@media (max-width: 575.98px) {
- .remember-me .remember-me-checkbox {
- margin-top: 0;
- }
-}
-body.ui-indigo .navbar-gitlab {
- background-color: #292961;
-}
-body.ui-indigo .navbar-gitlab .navbar-collapse {
- color: #d1d1f0;
-}
-body.ui-indigo .navbar-gitlab .container-fluid .navbar-toggler {
- border-left: 1px solid #6868b9;
-}
-body.ui-indigo .navbar-gitlab .container-fluid .navbar-toggler svg {
- fill: #d1d1f0;
-}
-body.ui-indigo .navbar-gitlab .navbar-sub-nav > li.active > a,
-body.ui-indigo .navbar-gitlab .navbar-sub-nav > li.active > button, body.ui-indigo .navbar-gitlab .navbar-sub-nav > li.dropdown.show > a,
-body.ui-indigo .navbar-gitlab .navbar-sub-nav > li.dropdown.show > button,
-body.ui-indigo .navbar-gitlab .navbar-nav > li.active > a,
-body.ui-indigo .navbar-gitlab .navbar-nav > li.active > button,
-body.ui-indigo .navbar-gitlab .navbar-nav > li.dropdown.show > a,
-body.ui-indigo .navbar-gitlab .navbar-nav > li.dropdown.show > button {
- color: #292961;
- background-color: #fff;
-}
-body.ui-indigo .navbar-gitlab .navbar-sub-nav {
- color: #d1d1f0;
-}
-body.ui-indigo .navbar-gitlab .nav > li {
- color: #d1d1f0;
-}
-body.ui-indigo .navbar-gitlab .nav > li > a.header-user-dropdown-toggle .header-user-avatar {
- border-color: #d1d1f0;
-}
-body.ui-indigo .navbar-gitlab .nav > li.active > a,
-body.ui-indigo .navbar-gitlab .nav > li.dropdown.show > a {
- color: #292961;
- background-color: #fff;
-}
-body.ui-indigo .search form {
- background-color: rgba(209, 209, 240, 0.2);
-}
-body.ui-indigo .search .search-input::placeholder {
- color: rgba(209, 209, 240, 0.8);
-}
-body.ui-indigo .search .search-input-wrap .search-icon,
-body.ui-indigo .search .search-input-wrap .clear-icon {
- fill: rgba(209, 209, 240, 0.8);
-}
-body.ui-indigo .nav-sidebar li.active {
- box-shadow: inset 4px 0 0 #4b4ba3;
-}
-body.ui-indigo .nav-sidebar li.active > a {
- color: #393982;
-}
-body.ui-indigo .nav-sidebar li.active .nav-icon-container svg {
- fill: #393982;
-}
-body.ui-indigo .sidebar-top-level-items > li.active .badge.badge-pill {
- color: #393982;
-}
-body.ui-indigo .nav-links li.active a,
-body.ui-indigo .nav-links li a.active {
- border-bottom: 2px solid #6666c4;
-}
-body.ui-indigo .nav-links li.active a .badge.badge-pill,
-body.ui-indigo .nav-links li a.active .badge.badge-pill {
- font-weight: 600;
-}
-.navbar-gitlab {
- padding: 0 16px;
- z-index: 1000;
- margin-bottom: 0;
- min-height: 40px;
- border: 0;
- border-bottom: 1px solid #dbdbdb;
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- border-radius: 0;
-}
-.navbar-gitlab .logo-text {
- line-height: initial;
-}
-.navbar-gitlab .logo-text svg {
- width: 55px;
- height: 14px;
- margin: 0;
- fill: #fff;
-}
-.navbar-gitlab .close-icon {
- display: none;
-}
-.navbar-gitlab .header-content {
- width: 100%;
- display: flex;
- justify-content: space-between;
- position: relative;
- min-height: 40px;
- padding-left: 0;
-}
-.navbar-gitlab .header-content .title-container {
- display: flex;
- align-items: stretch;
- flex: 1 1 auto;
- padding-top: 0;
- overflow: visible;
-}
-.navbar-gitlab .header-content .title {
- padding-right: 0;
- color: currentColor;
- display: flex;
- position: relative;
- margin: 0;
- font-size: 18px;
- vertical-align: top;
- white-space: nowrap;
-}
-.navbar-gitlab .header-content .title img {
- height: 28px;
-}
-.navbar-gitlab .header-content .title img + .logo-text {
- margin-left: 8px;
-}
-.navbar-gitlab .header-content .title.wrap {
- white-space: normal;
-}
-.navbar-gitlab .header-content .title a {
- display: flex;
- align-items: center;
- padding: 2px 8px;
- margin: 5px 2px 5px -8px;
- border-radius: 4px;
-}
-.navbar-gitlab .header-content .dropdown.open > a {
- border-bottom-color: #fff;
-}
-.navbar-gitlab .header-content .navbar-collapse > ul.nav > li:not(.d-none) {
- margin: 0 2px;
-}
-.navbar-gitlab .navbar-collapse {
- flex: 0 0 auto;
- border-top: 0;
- padding: 0;
-}
-
-@media (max-width: 575.98px) {
- .navbar-gitlab .navbar-collapse {
- flex: 1 1 auto;
- }
-}
-.navbar-gitlab .navbar-collapse .nav {
- flex-wrap: nowrap;
-}
-
-@media (max-width: 575.98px) {
- .navbar-gitlab .navbar-collapse .nav > li:not(.d-none) a {
- margin-left: 0;
- }
-}
-.navbar-gitlab .container-fluid {
- padding: 0;
-}
-.navbar-gitlab .container-fluid .user-counter svg {
- margin-right: 3px;
-}
-.navbar-gitlab .container-fluid .navbar-toggler {
- position: relative;
- right: -10px;
- border-radius: 0;
- min-width: 45px;
- padding: 0;
- margin: 8px -7px 8px 0;
- font-size: 14px;
- text-align: center;
- color: currentColor;
-}
-
-@media (max-width: 575.98px) {
- .navbar-gitlab .container-fluid .navbar-nav {
- display: flex;
- padding-right: 10px;
- flex-direction: row;
- }
-}
-.navbar-gitlab .container-fluid .navbar-nav li .badge.badge-pill {
- box-shadow: none;
- font-weight: 600;
-}
-
-@media (max-width: 575.98px) {
- .navbar-gitlab .container-fluid .nav > li.header-user {
- padding-left: 10px;
- }
-}
-.navbar-gitlab .container-fluid .nav > li > a {
- will-change: color;
- margin: 4px 0;
- padding: 6px 8px;
- height: 32px;
-}
-
-@media (max-width: 575.98px) {
- .navbar-gitlab .container-fluid .nav > li > a {
- padding: 0;
- }
-}
-.navbar-gitlab .container-fluid .nav > li > a.header-user-dropdown-toggle {
- margin-left: 2px;
-}
-.navbar-gitlab .container-fluid .nav > li > a.header-user-dropdown-toggle .header-user-avatar {
- margin-right: 0;
-}
-.navbar-gitlab .container-fluid .nav > li .header-new-dropdown-toggle {
- margin-right: 0;
-}
-.navbar-sub-nav > li > a,
-.navbar-sub-nav > li > button,
-.navbar-nav > li > a,
-.navbar-nav > li > button {
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 6px 8px;
- margin: 4px 2px;
- font-size: 12px;
- color: currentColor;
- border-radius: 4px;
- height: 32px;
- font-weight: 600;
-}
-.navbar-sub-nav > li > button,
-.navbar-nav > li > button {
- background: transparent;
- border: 0;
-}
-.navbar-sub-nav .dropdown-menu,
-.navbar-nav .dropdown-menu {
- position: absolute;
-}
-.navbar-sub-nav {
- display: flex;
- margin: 0 0 0 6px;
-}
-.caret-down,
-.btn .caret-down {
- top: 0;
- height: 11px;
- width: 11px;
- margin-left: 4px;
- fill: currentColor;
-}
-.header-user .dropdown-menu,
-.header-new .dropdown-menu {
- margin-top: 4px;
-}
-.btn-sign-in {
- background-color: #ebebfa;
- color: #292961;
- font-weight: 600;
- line-height: 18px;
- margin: 4px 0 4px 2px;
-}
-.title-container .badge.badge-pill,
-.navbar-nav .badge.badge-pill {
- position: inherit;
- font-weight: 400;
- margin-left: -6px;
- font-size: 11px;
- color: #fff;
- padding: 0 5px;
- line-height: 12px;
- border-radius: 7px;
- box-shadow: 0 1px 0 rgba(76, 78, 84, 0.2);
-}
-.title-container .badge.badge-pill.green-badge,
-.navbar-nav .badge.badge-pill.green-badge {
- background-color: #108548;
-}
-.title-container .badge.badge-pill.merge-requests-count,
-.navbar-nav .badge.badge-pill.merge-requests-count {
- background-color: #de7e00;
-}
-.title-container .badge.badge-pill.todos-count,
-.navbar-nav .badge.badge-pill.todos-count {
- background-color: #1f75cb;
-}
-.title-container .canary-badge .badge,
-.navbar-nav .canary-badge .badge {
- font-size: 12px;
- line-height: 16px;
- padding: 0 0.5rem;
-}
-
-@media (max-width: 575.98px) {
- .navbar-gitlab .container-fluid {
- font-size: 18px;
- }
- .navbar-gitlab .container-fluid .navbar-nav {
- table-layout: fixed;
- width: 100%;
- margin: 0;
- text-align: right;
- }
- .navbar-gitlab .container-fluid .navbar-collapse {
- margin-left: -8px;
- margin-right: -10px;
- }
- .navbar-gitlab .container-fluid .navbar-collapse .nav > li:not(.d-none) {
- flex: 1;
- }
- .header-user-dropdown-toggle {
- text-align: center;
- }
- .header-user-avatar {
- float: none;
- }
-}
-.header-user.show .dropdown-menu {
- margin-top: 4px;
- color: #303030;
- left: auto;
- max-height: 445px;
-}
-.header-user.show .dropdown-menu svg {
- vertical-align: text-top;
-}
-.header-user-avatar {
- float: left;
- margin-right: 5px;
- border-radius: 50%;
- border: 1px solid #f5f5f5;
-}
.navbar-empty {
justify-content: center;
height: 40px;
background: #fff;
border-bottom: 1px solid #f0f0f0;
}
-
-@media (max-width: 575.98px) {
- .nav-links > li > a .badge.badge-pill {
- display: none;
- }
+.navbar-empty .tanuki-logo,
+.navbar-empty .brand-header-logo {
+ max-height: 100%;
}
-
-@media (max-width: 575.98px) {
- .nav-links > li > a {
- margin-right: 3px;
- }
+.tanuki-logo .tanuki-left-ear,
+.tanuki-logo .tanuki-right-ear,
+.tanuki-logo .tanuki-nose {
+ fill: #e24329;
}
-.media {
- display: flex;
- align-items: flex-start;
+.tanuki-logo .tanuki-left-eye,
+.tanuki-logo .tanuki-right-eye {
+ fill: #fc6d26;
+}
+.tanuki-logo .tanuki-left-cheek,
+.tanuki-logo .tanuki-right-cheek {
+ fill: #fca326;
}
.card {
margin-bottom: 16px;
}
-.nav-links:not(.quick-links) {
- display: flex;
- padding: 0;
- margin: 0;
- list-style: none;
- height: auto;
- border-bottom: 1px solid #dbdbdb;
-}
-.content-wrapper {
- width: 100%;
-}
-.content-wrapper .container-fluid {
- padding: 0 16px;
-}
-
-@media (min-width: 768px) {
- .page-with-contextual-sidebar {
- padding-left: 50px;
- }
-}
-
-@media (min-width: 1200px) {
- .page-with-contextual-sidebar {
- padding-left: 220px;
- }
-}
-.context-header {
- position: relative;
- margin-right: 2px;
- width: 220px;
-}
-.context-header > a,
-.context-header > button {
- font-weight: 600;
- display: flex;
- width: 100%;
- align-items: center;
- padding: 10px 16px 10px 10px;
- color: #303030;
- background-color: transparent;
- border: 0;
- text-align: left;
-}
-.context-header .avatar-container {
- flex: 0 0 40px;
- background-color: #fff;
-}
-.context-header .sidebar-context-title {
- overflow: hidden;
- text-overflow: ellipsis;
-}
-.context-header .sidebar-context-title.text-secondary {
- font-weight: normal;
- font-size: 0.8em;
-}
-.nav-sidebar {
- position: fixed;
- z-index: 600;
- width: 220px;
- top: 40px;
- bottom: 0;
- left: 0;
- background-color: #fafafa;
- box-shadow: inset -1px 0 0 #dbdbdb;
- transform: translate3d(0, 0, 0);
-}
-
-@media (min-width: 576px) and (max-width: 576px) {
- .nav-sidebar:not(.sidebar-collapsed-desktop) {
- box-shadow: inset -1px 0 0 #dbdbdb, 2px 1px 3px rgba(0, 0, 0, 0.1);
- }
-}
-.nav-sidebar.sidebar-collapsed-desktop {
- width: 50px;
-}
-.nav-sidebar.sidebar-collapsed-desktop .nav-sidebar-inner-scroll {
- overflow-x: hidden;
-}
-.nav-sidebar.sidebar-collapsed-desktop .badge.badge-pill:not(.fly-out-badge),
-.nav-sidebar.sidebar-collapsed-desktop .sidebar-context-title,
-.nav-sidebar.sidebar-collapsed-desktop .nav-item-name {
- border: 0;
- clip: rect(0, 0, 0, 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- white-space: nowrap;
- width: 1px;
-}
-.nav-sidebar.sidebar-collapsed-desktop .sidebar-top-level-items > li > a {
- min-height: 45px;
-}
-.nav-sidebar.sidebar-collapsed-desktop .fly-out-top-item {
- display: block;
-}
-.nav-sidebar.sidebar-collapsed-desktop .avatar-container {
- margin: 0 auto;
-}
-.nav-sidebar.sidebar-expanded-mobile {
- left: 0;
-}
-.nav-sidebar a {
- text-decoration: none;
-}
-.nav-sidebar ul {
- padding-left: 0;
- list-style: none;
-}
-.nav-sidebar li {
- white-space: nowrap;
-}
-.nav-sidebar li a {
- display: flex;
- align-items: center;
- padding: 12px 16px;
- color: #666;
-}
-.nav-sidebar li .nav-item-name {
- flex: 1;
-}
-.nav-sidebar li.active > a {
- font-weight: 600;
-}
-
-@media (max-width: 767.98px) {
- .nav-sidebar {
- left: -220px;
- }
-}
-.nav-sidebar .nav-icon-container {
- display: flex;
- margin-right: 8px;
-}
-.nav-sidebar .fly-out-top-item {
- display: none;
-}
-.nav-sidebar svg {
- height: 16px;
- width: 16px;
-}
-
-@media (min-width: 768px) and (max-width: 1199px) {
- .nav-sidebar:not(.sidebar-expanded-mobile) {
- width: 50px;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .nav-sidebar-inner-scroll {
- overflow-x: hidden;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .badge.badge-pill:not(.fly-out-badge),
- .nav-sidebar:not(.sidebar-expanded-mobile) .sidebar-context-title,
- .nav-sidebar:not(.sidebar-expanded-mobile) .nav-item-name {
- border: 0;
- clip: rect(0, 0, 0, 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- white-space: nowrap;
- width: 1px;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .sidebar-top-level-items > li > a {
- min-height: 45px;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .fly-out-top-item {
- display: block;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .avatar-container {
- margin: 0 auto;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .context-header {
- height: 60px;
- width: 50px;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .context-header a {
- padding: 10px 4px;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .sidebar-top-level-items > li .sidebar-sub-level-items:not(.flyout-list) {
- display: none;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .nav-icon-container {
- margin-right: 0;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button {
- padding: 16px;
- width: 49px;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button .collapse-text,
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button .icon-chevron-double-lg-left {
- display: none;
- }
- .nav-sidebar:not(.sidebar-expanded-mobile) .toggle-sidebar-button .icon-chevron-double-lg-right {
- display: block;
- margin: 0;
- }
-}
-.nav-sidebar-inner-scroll {
- height: 100%;
- width: 100%;
- overflow: auto;
-}
-.sidebar-sub-level-items {
- display: none;
- padding-bottom: 8px;
-}
-.sidebar-sub-level-items > li a {
- padding: 8px 16px 8px 40px;
-}
-.sidebar-top-level-items {
- margin-bottom: 60px;
-}
-
-@media (min-width: 576px) {
- .sidebar-top-level-items > li > a {
- margin-right: 1px;
- }
-}
-.sidebar-top-level-items > li .badge.badge-pill {
- background-color: rgba(0, 0, 0, 0.08);
- color: #666;
-}
-.sidebar-top-level-items > li.active {
- background: rgba(0, 0, 0, 0.04);
-}
-.sidebar-top-level-items > li.active > a {
- margin-left: 4px;
- padding-left: 12px;
-}
-.sidebar-top-level-items > li.active .badge.badge-pill {
- font-weight: 600;
-}
-.sidebar-top-level-items > li.active .sidebar-sub-level-items:not(.is-fly-out-only) {
- display: block;
-}
-.toggle-sidebar-button,
-.close-nav-button {
- width: 219px;
- position: fixed;
- height: 48px;
- bottom: 0;
- padding: 0 16px;
- background-color: #fafafa;
- border: 0;
- border-top: 1px solid #dbdbdb;
- color: #666;
- display: flex;
- align-items: center;
-}
-.toggle-sidebar-button svg,
-.close-nav-button svg {
- margin-right: 8px;
-}
-.toggle-sidebar-button .icon-chevron-double-lg-right,
-.close-nav-button .icon-chevron-double-lg-right {
- display: none;
-}
-.collapse-text {
- white-space: nowrap;
- overflow: hidden;
-}
-.sidebar-collapsed-desktop .context-header {
- height: 60px;
- width: 50px;
-}
-.sidebar-collapsed-desktop .context-header a {
- padding: 10px 4px;
-}
-.sidebar-collapsed-desktop .sidebar-top-level-items > li .sidebar-sub-level-items:not(.flyout-list) {
- display: none;
-}
-.sidebar-collapsed-desktop .nav-icon-container {
- margin-right: 0;
-}
-.sidebar-collapsed-desktop .toggle-sidebar-button {
- padding: 16px;
- width: 49px;
-}
-.sidebar-collapsed-desktop .toggle-sidebar-button .collapse-text,
-.sidebar-collapsed-desktop .toggle-sidebar-button .icon-chevron-double-lg-left {
- display: none;
-}
-.sidebar-collapsed-desktop .toggle-sidebar-button .icon-chevron-double-lg-right {
- display: block;
- margin: 0;
-}
-.fly-out-top-item > a {
- display: flex;
-}
-.fly-out-top-item .fly-out-badge {
- margin-left: 8px;
-}
-.fly-out-top-item-name {
- flex: 1;
-}
-.close-nav-button {
- display: none;
-}
-
-@media (max-width: 767.98px) {
- .close-nav-button {
- display: flex;
- }
- .toggle-sidebar-button {
- display: none;
- }
-}
-table.table {
- margin-bottom: 16px;
-}
-table.table .dropdown-menu a {
- text-decoration: none;
-}
-table.table .success,
-table.table .info {
- color: #fff;
-}
-table.table .success a:not(.btn),
-table.table .info a:not(.btn) {
- text-decoration: underline;
- color: #fff;
-}
-pre {
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
- display: block;
- padding: 8px 12px;
- margin: 0 0 8px;
- font-size: 13px;
- word-break: break-all;
- word-wrap: break-word;
- color: #303030;
- background-color: #fafafa;
- border: 1px solid #dbdbdb;
- border-radius: 2px;
-}
-.monospace {
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
-}
-input::-moz-placeholder,
-textarea::-moz-placeholder {
+input::-moz-placeholder {
color: #868686;
opacity: 1;
}
-input::-ms-input-placeholder,
-textarea::-ms-input-placeholder {
+input::-ms-input-placeholder {
color: #868686;
}
-input:-ms-input-placeholder,
-textarea:-ms-input-placeholder {
+input:-ms-input-placeholder {
color: #868686;
}
svg {
fill: currentColor;
}
-
-svg.s12 {
- width: 12px;
- height: 12px;
-}
-
-svg.s16 {
- width: 16px;
- height: 16px;
-}
-
-svg.s18 {
- width: 18px;
- height: 18px;
-}
-
-svg.s12 {
- vertical-align: -1px;
-}
-
-svg.s16 {
- vertical-align: -3px;
-}
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0;
-}
-table.code {
- width: 100%;
- font-family: "Menlo", "DejaVu Sans Mono", "Liberation Mono", "Consolas", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace;
- border: 0;
- border-collapse: separate;
- margin: 0;
- padding: 0;
- table-layout: fixed;
- border-radius: 0 0 4px 4px;
-}
-.frame .badge.badge-pill {
- position: absolute;
- background-color: #428fdc;
- color: #fff;
- border: #fff 1px solid;
- min-height: 16px;
- padding: 5px 8px;
- border-radius: 12px;
-}
-.frame .badge.badge-pill {
- transform: translate(-50%, -50%);
-}
-.color-label {
- padding: 0 0.5rem;
- line-height: 16px;
- border-radius: 100px;
- color: #fff;
-}
-.label-link {
- display: inline-flex;
- vertical-align: text-bottom;
-}
-.label-link .label {
- vertical-align: inherit;
- font-size: 12px;
-}
.login-page .container {
max-width: 960px;
}
@@ -2096,6 +672,25 @@ table.code {
border-radius: 0.25rem;
padding: 15px;
}
+.login-page .login-box .login-heading h3,
+.login-page .omniauth-container .login-heading h3 {
+ font-weight: 400;
+ line-height: 1.5;
+ margin: 0 0 10px;
+}
+.login-page .login-box .login-footer,
+.login-page .omniauth-container .login-footer {
+ margin-top: 10px;
+}
+.login-page .login-box .login-footer p:last-child,
+.login-page .omniauth-container .login-footer p:last-child {
+ margin-bottom: 0;
+}
+.login-page .login-box a.forgot,
+.login-page .omniauth-container a.forgot {
+ float: right;
+ padding-top: 6px;
+}
.login-page .login-box .nav .active a,
.login-page .omniauth-container .nav .active a {
background: transparent;
@@ -2132,22 +727,30 @@ table.code {
background: none;
margin-bottom: 16px;
}
-
@media (max-width: 991.98px) {
.login-page .omniauth-container form {
width: 100%;
}
}
-.login-page .omniauth-container .omniauth-btn {
- width: 100%;
- padding: 8px;
-}
.login-page .new-session-tabs {
display: flex;
box-shadow: 0 0 0 1px #dbdbdb;
border-top-right-radius: 4px;
border-top-left-radius: 4px;
}
+.login-page .new-session-tabs.custom-provider-tabs {
+ flex-wrap: wrap;
+}
+.login-page .new-session-tabs.custom-provider-tabs li {
+ min-width: 85px;
+ flex-basis: auto;
+}
+.login-page .new-session-tabs.custom-provider-tabs li:nth-child(n + 5) {
+ border-top: 1px solid #dbdbdb;
+}
+.login-page .new-session-tabs.custom-provider-tabs a {
+ font-size: 16px;
+}
.login-page .new-session-tabs li {
flex: 1;
text-align: center;
@@ -2173,14 +776,22 @@ table.code {
.login-page .submit-container {
margin-top: 16px;
}
-.login-page input[type='submit'] {
+.login-page input[type="submit"] {
margin-bottom: 0;
+ display: block;
+ width: 100%;
}
.login-page .devise-errors h2 {
margin-top: 0;
font-size: 14px;
color: #ae1800;
}
+@media (max-width: 575.98px) {
+ .login-page .col-md-5.float-right {
+ float: none !important;
+ margin-bottom: 45px;
+ }
+}
.devise-layout-html {
margin: 0;
padding: 0;
@@ -2213,191 +824,57 @@ table.code {
.devise-layout-html body .navless-container {
padding: 65px 15px;
}
-
@media (max-width: 575.98px) {
.devise-layout-html body .navless-container {
padding: 0 15px 65px;
}
}
-.milestones {
- padding: 8px;
- margin-top: 8px;
- border-radius: 4px;
- background-color: #dbdbdb;
+
+.gl-border-solid {
+ border-style: solid;
}
-.search {
- margin: 0 8px;
+.gl-border-gray-100 {
+ border-color: #dbdbdb;
}
-.search form {
- margin: 0;
- padding: 4px;
- width: 200px;
- line-height: 24px;
- height: 32px;
- border: 0;
- border-radius: 4px;
+.gl-border-1 {
+ border-width: 1px;
+}
+.gl-rounded-base {
+ border-radius: 0.25rem;
+}
+.gl-text-green-600 {
+ color: #217645;
+}
+.gl-text-red-500 {
+ color: #dd2b0e;
+}
+.gl-display-flex {
+ display: flex;
+}
+.gl-align-items-center {
+ align-items: center;
+}
+.gl-p-2 {
+ padding: 0.25rem;
+}
+.gl-p-4 {
+ padding: 0.75rem;
+}
+.gl-mt-2 {
+ margin-top: 0.25rem;
+}
+.gl-mb-2 {
+ margin-bottom: 0.25rem;
+}
+.gl-mb-3 {
+ margin-bottom: 0.5rem;
+}
+.gl-mb-5 {
+ margin-bottom: 1rem;
+}
+.gl-text-left {
+ text-align: left;
}
-@media (min-width: 1200px) {
- .search form {
- width: 320px;
- }
-}
-.search .search-input {
- border: 0;
- font-size: 14px;
- padding: 0 20px 0 0;
- margin-left: 5px;
- line-height: 25px;
- width: 98%;
- color: #fff;
- background: none;
-}
-.search .search-input-container {
- display: flex;
- position: relative;
-}
-.search .search-input-wrap {
- width: 100%;
-}
-.search .search-input-wrap .search-icon,
-.search .search-input-wrap .clear-icon {
- position: absolute;
- right: 5px;
- top: 4px;
-}
-.search .search-input-wrap .search-icon {
- -moz-user-select: none;
- user-select: none;
-}
-.search .search-input-wrap .clear-icon {
- display: none;
-}
-.search .search-input-wrap .dropdown {
- position: static;
-}
-.search .search-input-wrap .dropdown-menu {
- left: -5px;
- max-height: 400px;
- overflow: auto;
-}
-
-@media (min-width: 1200px) {
- .search .search-input-wrap .dropdown-menu {
- width: 320px;
- }
-}
-.search .search-input-wrap .dropdown-content {
- max-height: 382px;
-}
-.settings {
- border-top: 1px solid #dbdbdb;
-}
-.settings:first-of-type {
- margin-top: 10px;
- border: 0;
-}
-.settings + div .settings:first-of-type {
- margin-top: 0;
- border-top: 1px solid #dbdbdb;
-}
-.avatar, .avatar-container {
- float: left;
- margin-right: 16px;
- border-radius: 50%;
- border: 1px solid #f5f5f5;
-}
-.s16.avatar, .s16.avatar-container {
- width: 16px;
- height: 16px;
- margin-right: 8px;
-}
-.s18.avatar, .s18.avatar-container {
- width: 18px;
- height: 18px;
- margin-right: 8px;
-}
-.s40.avatar, .s40.avatar-container {
- width: 40px;
- height: 40px;
- margin-right: 8px;
-}
-.avatar {
- transition-property: none;
- width: 40px;
- height: 40px;
- padding: 0;
- background: #fdfdfd;
- overflow: hidden;
- border-color: rgba(0, 0, 0, 0.1);
-}
-.avatar.center {
- font-size: 14px;
- line-height: 1.8em;
- text-align: center;
-}
-.avatar.avatar-tile {
- border-radius: 0;
- border: 0;
-}
-.avatar-container {
- overflow: hidden;
- display: flex;
-}
-.avatar-container a {
- width: 100%;
- height: 100%;
- display: flex;
- text-decoration: none;
-}
-.avatar-container .avatar {
- border-radius: 0;
- border: 0;
- height: auto;
- width: 100%;
- margin: 0;
- align-self: center;
-}
-.avatar-container.s40 {
- min-width: 40px;
- min-height: 40px;
-}
-.rect-avatar {
- border-radius: 2px;
-}
-.rect-avatar.s16 {
- border-radius: 2px;
-}
-.rect-avatar.s18 {
- border-radius: 2px;
-}
-.rect-avatar.s40 {
- border-radius: 4px;
-}
-.tab-width-8 {
- -moz-tab-size: 8;
- tab-size: 8;
-}
-.gl-sr-only {
- border: 0;
- clip: rect(0, 0, 0, 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- white-space: nowrap;
- width: 1px;
-}
-.gl-mt-5 {
- margin-top: 1rem;
-}
-.gl-ml-3 {
- margin-left: 0.5rem;
-}
-.content-wrapper > .alert-wrapper,
-#content-body, .modal-dialog {
- display: block;
-}
-@import 'cloaking';
+@import "cloaking";
@include cloak-startup-scss(none);
diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb
index e1f09d73739..a6235d8fc04 100644
--- a/app/controllers/groups/boards_controller.rb
+++ b/app/controllers/groups/boards_controller.rb
@@ -8,6 +8,7 @@ class Groups::BoardsController < Groups::ApplicationController
before_action :assign_endpoint_vars
before_action do
push_frontend_feature_flag(:graphql_board_lists, group, default_enabled: false)
+ push_frontend_feature_flag(:board_multi_select, group, default_enabled: :yaml)
push_frontend_feature_flag(:swimlanes_buffered_rendering, group, default_enabled: :yaml)
end
diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb
index 9a3e9437426..ee8bacbac61 100644
--- a/app/controllers/projects/boards_controller.rb
+++ b/app/controllers/projects/boards_controller.rb
@@ -9,6 +9,7 @@ class Projects::BoardsController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:swimlanes_buffered_rendering, project, default_enabled: :yaml)
push_frontend_feature_flag(:graphql_board_lists, project, default_enabled: :yaml)
+ push_frontend_feature_flag(:board_multi_select, project, default_enabled: :yaml)
end
feature_category :boards
diff --git a/app/models/bulk_imports/export.rb b/app/models/bulk_imports/export.rb
index 59ca4dbfec6..371b58dea03 100644
--- a/app/models/bulk_imports/export.rb
+++ b/app/models/bulk_imports/export.rb
@@ -4,6 +4,10 @@ module BulkImports
class Export < ApplicationRecord
include Gitlab::Utils::StrongMemoize
+ STARTED = 0
+ FINISHED = 1
+ FAILED = -1
+
self.table_name = 'bulk_import_exports'
belongs_to :project, optional: true
@@ -18,9 +22,9 @@ module BulkImports
validate :portable_relation?
state_machine :status, initial: :started do
- state :started, value: 0
- state :finished, value: 1
- state :failed, value: -1
+ state :started, value: STARTED
+ state :finished, value: FINISHED
+ state :failed, value: FAILED
event :start do
transition any => :started
diff --git a/app/models/bulk_imports/export_status.rb b/app/models/bulk_imports/export_status.rb
new file mode 100644
index 00000000000..72ece4e8fc0
--- /dev/null
+++ b/app/models/bulk_imports/export_status.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+module BulkImports
+ class ExportStatus
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(pipeline_tracker, relation)
+ @pipeline_tracker = pipeline_tracker
+ @relation = relation
+ @entity = @pipeline_tracker.entity
+ @configuration = @entity.bulk_import.configuration
+ @client = Clients::Http.new(uri: @configuration.url, token: @configuration.access_token)
+ end
+
+ def started?
+ export_status['status'] == Export::STARTED
+ end
+
+ def failed?
+ export_status['status'] == Export::FAILED
+ end
+
+ def error
+ export_status['error']
+ end
+
+ private
+
+ attr_reader :client, :entity, :relation
+
+ def export_status
+ strong_memoize(:export_status) do
+ fetch_export_status.find { |item| item['relation'] == relation }
+ end
+ rescue StandardError => e
+ { 'status' => Export::FAILED, 'error' => e.message }
+ end
+
+ def fetch_export_status
+ client.get(status_endpoint).parsed_response
+ end
+
+ def status_endpoint
+ "/groups/#{entity.encoded_source_full_path}/export_relations/status"
+ end
+ end
+end
diff --git a/app/models/bulk_imports/file_transfer/base_config.rb b/app/models/bulk_imports/file_transfer/base_config.rb
index bb04e84ad72..7396f9d3655 100644
--- a/app/models/bulk_imports/file_transfer/base_config.rb
+++ b/app/models/bulk_imports/file_transfer/base_config.rb
@@ -13,6 +13,14 @@ module BulkImports
attributes_finder.find_root(portable_class_sym)
end
+ def top_relation_tree(relation)
+ portable_relations_tree[relation.to_s]
+ end
+
+ def relation_excluded_keys(relation)
+ attributes_finder.find_excluded_keys(relation)
+ end
+
def export_path
strong_memoize(:export_path) do
relative_path = File.join(base_export_path, SecureRandom.hex)
@@ -47,6 +55,10 @@ module BulkImports
@portable_class_sym ||= portable_class.to_s.demodulize.underscore.to_sym
end
+ def portable_relations_tree
+ @portable_relations_tree ||= attributes_finder.find_relations_tree(portable_class_sym).deep_stringify_keys
+ end
+
def import_export_yaml
raise NotImplementedError
end
diff --git a/app/services/bulk_imports/file_download_service.rb b/app/services/bulk_imports/file_download_service.rb
index 6d338268440..1edd0695efd 100644
--- a/app/services/bulk_imports/file_download_service.rb
+++ b/app/services/bulk_imports/file_download_service.rb
@@ -3,7 +3,7 @@
module BulkImports
class FileDownloadService
FILE_SIZE_LIMIT = 5.gigabytes
- ALLOWED_CONTENT_TYPES = ['application/octet-stream'].freeze
+ ALLOWED_CONTENT_TYPES = %w(application/gzip application/octet-stream).freeze
ServiceError = Class.new(StandardError)
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index b28cd47efcc..14d0d73e2b7 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -36,7 +36,7 @@
= favicon_link_tag favicon, id: 'favicon', data: { original_href: favicon }, type: 'image/png'
- = render 'layouts/startup_css'
+ = render 'layouts/startup_css', { startup_filename: local_assigns.fetch(:startup_filename, nil) }
- if user_application_theme == 'gl-dark'
= stylesheet_link_tag_defer "application_dark"
= yield :page_specific_styles
diff --git a/app/views/layouts/_startup_css.haml b/app/views/layouts/_startup_css.haml
index 7d3cfe28007..67c871b95f5 100644
--- a/app/views/layouts/_startup_css.haml
+++ b/app/views/layouts/_startup_css.haml
@@ -1,4 +1,5 @@
-- startup_filename = current_path?("sessions#new") ? 'signin' : user_application_theme == 'gl-dark' ? 'dark' : 'general'
+- startup_filename_default = user_application_theme == 'gl-dark' ? 'dark' : 'general'
+- startup_filename = local_assigns.fetch(:startup_filename, nil) || startup_filename_default
%style
= Rails.application.assets_manifest.find_sources("themes/#{user_application_theme_css_filename}.css").first.to_s.html_safe if user_application_theme_css_filename
diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml
index ef61a04c288..ae7c160c060 100644
--- a/app/views/layouts/devise.html.haml
+++ b/app/views/layouts/devise.html.haml
@@ -1,6 +1,6 @@
!!! 5
%html.devise-layout-html{ class: system_message_class }
- = render "layouts/head"
+ = render "layouts/head", { startup_filename: 'signin' }
%body.ui-indigo.login-page.application.navless{ class: "#{client_class_list}", data: { page: body_data_page, qa_selector: 'login_page' } }
= header_message
= render "layouts/init_client_detection_flags"
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index f3e9aa09306..e395a0bbed8 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -1087,15 +1087,6 @@
:weight: 2
:idempotent: true
:tags: []
-- :name: incident_management:incident_management_process_prometheus_alert
- :worker_name: IncidentManagement::ProcessPrometheusAlertWorker
- :feature_category: :incident_management
- :has_external_dependencies:
- :urgency: :low
- :resource_boundary: :cpu
- :weight: 2
- :idempotent:
- :tags: []
- :name: jira_connect:jira_connect_sync_branch
:worker_name: JiraConnect::SyncBranchWorker
:feature_category: :integrations
diff --git a/app/workers/bulk_imports/pipeline_worker.rb b/app/workers/bulk_imports/pipeline_worker.rb
index 256301bf097..2547b6bcecb 100644
--- a/app/workers/bulk_imports/pipeline_worker.rb
+++ b/app/workers/bulk_imports/pipeline_worker.rb
@@ -4,6 +4,8 @@ module BulkImports
class PipelineWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
+ NDJSON_PIPELINE_PERFORM_DELAY = 1.minute
+
feature_category :importers
tags :exclude_from_kubernetes
@@ -40,6 +42,15 @@ module BulkImports
private
def run(pipeline_tracker)
+ if ndjson_pipeline?(pipeline_tracker)
+ status = ExportStatus.new(pipeline_tracker, pipeline_tracker.pipeline_class::RELATION)
+
+ raise(Pipeline::ExpiredError, 'Pipeline timeout') if job_timeout?(pipeline_tracker)
+ raise(Pipeline::FailedError, status.error) if status.failed?
+
+ return reenqueue(pipeline_tracker) if status.started?
+ end
+
pipeline_tracker.update!(status_event: 'start', jid: jid)
context = ::BulkImports::Pipeline::Context.new(pipeline_tracker)
@@ -48,7 +59,7 @@ module BulkImports
pipeline_tracker.finish!
rescue StandardError => e
- pipeline_tracker.fail_op!
+ pipeline_tracker.update!(status_event: 'fail_op', jid: jid)
logger.error(
worker: self.class.name,
@@ -67,5 +78,17 @@ module BulkImports
def logger
@logger ||= Gitlab::Import::Logger.build
end
+
+ def ndjson_pipeline?(pipeline_tracker)
+ pipeline_tracker.pipeline_class.ndjson_pipeline?
+ end
+
+ def job_timeout?(pipeline_tracker)
+ (Time.zone.now - pipeline_tracker.entity.created_at) > Pipeline::NDJSON_EXPORT_TIMEOUT
+ end
+
+ def reenqueue(pipeline_tracker)
+ self.class.perform_in(NDJSON_PIPELINE_PERFORM_DELAY, pipeline_tracker.id, pipeline_tracker.stage, pipeline_tracker.entity.id)
+ end
end
end
diff --git a/app/workers/incident_management/process_prometheus_alert_worker.rb b/app/workers/incident_management/process_prometheus_alert_worker.rb
deleted file mode 100644
index 7b5c6fd9001..00000000000
--- a/app/workers/incident_management/process_prometheus_alert_worker.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-module IncidentManagement
- class ProcessPrometheusAlertWorker # rubocop:disable Scalability/IdempotentWorker
- include ApplicationWorker
-
- sidekiq_options retry: 3
-
- queue_namespace :incident_management
- feature_category :incident_management
- worker_resource_boundary :cpu
-
- def perform(project_id, alert_hash)
- # no-op
- #
- # This worker is not scheduled anymore since
- # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35943
- # and will be removed completely via
- # https://gitlab.com/gitlab-org/gitlab/-/issues/227146
- # in 14.0.
- end
- end
-end
diff --git a/config/feature_flags/development/board_multi_select.yml b/config/feature_flags/development/board_multi_select.yml
new file mode 100644
index 00000000000..3c37f843a9a
--- /dev/null
+++ b/config/feature_flags/development/board_multi_select.yml
@@ -0,0 +1,8 @@
+---
+name: board_multi_select
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61955
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/331189
+milestone: '14.0'
+type: development
+group: group::product planning
+default_enabled: false
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 1b356fea17c..7eb816bf985 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -2175,6 +2175,25 @@ Input type: `EscalationPolicyCreateInput`
| `errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| `escalationPolicy` | [`EscalationPolicyType`](#escalationpolicytype) | The escalation policy. |
+### `Mutation.escalationPolicyDestroy`
+
+Input type: `EscalationPolicyDestroyInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| `id` | [`IncidentManagementEscalationPolicyID!`](#incidentmanagementescalationpolicyid) | The escalation policy internal ID to remove. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| `errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| `escalationPolicy` | [`EscalationPolicyType`](#escalationpolicytype) | The escalation policy. |
+
### `Mutation.exportRequirements`
Input type: `ExportRequirementsInput`
diff --git a/doc/development/changelog.md b/doc/development/changelog.md
index 8e7b9868cbe..616b175c9eb 100644
--- a/doc/development/changelog.md
+++ b/doc/development/changelog.md
@@ -79,8 +79,17 @@ EE: true
## What warrants a changelog entry?
-- Any user-facing change **should** have a changelog entry. Example: "GitLab now
+- Any change that introduces a database migration, whether it's regular, post,
+ or data migration, **must** have a changelog entry, even if it is behind a
+ disabled feature flag.
+- [Security fixes](https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md)
+ **must** have a changelog entry, with `Changelog` trailer set to `security`.
+- Any user-facing change **must** have a changelog entry. Example: "GitLab now
uses system fonts for all text."
+- Any client-facing change to our REST and GraphQL APIs **must** have a changelog entry.
+ See the [complete list what comprises a GraphQL breaking change](api_graphql_styleguide.md#breaking-changes).
+- Any change that introduces an [Advanced Search migration](elasticsearch.md#creating-a-new-advanced-search-migration)
+ **must** have a changelog entry.
- A fix for a regression introduced and then fixed in the same release (such as
fixing a bug introduced during a monthly release candidate) **should not**
have a changelog entry.
diff --git a/doc/topics/build_your_application.md b/doc/topics/build_your_application.md
new file mode 100644
index 00000000000..d084ecec435
--- /dev/null
+++ b/doc/topics/build_your_application.md
@@ -0,0 +1,16 @@
+---
+stage:
+group:
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Build your application **(FREE)**
+
+Add your source code to a repository, create merge requests to check in
+code, and use CI/CD to generate your application. Include packages in your app and output it to a variety of environments.
+
+- [Repositories](../user/project/repository/index.md)
+- [Merge requests](../user/project/merge_requests/index.md)
+- [CI/CD](../ci/README.md)
+- [Packages & Registries](../user/packages/index.md)
+- [Application infrastructure](../user/project/clusters/index.md)
diff --git a/doc/topics/git/lfs/index.md b/doc/topics/git/lfs/index.md
index 0851d3f6b50..ff5cfe0ac3e 100644
--- a/doc/topics/git/lfs/index.md
+++ b/doc/topics/git/lfs/index.md
@@ -161,6 +161,34 @@ Feature.disable(:include_lfs_blobs_in_archive)
## Troubleshooting
+### Encountered `n` file(s) that should have been pointers, but weren't
+
+This error indicates the file (or files) are expected to be tracked by LFS, but for
+some reason the repository is not tracking them as LFS. This issue can be one
+potential reason for this error:
+[Files not tracked with LFS when uploaded through the web interface](https://gitlab.com/gitlab-org/gitlab/-/issues/326342#note_586820485)
+
+To resolve the problem, migrate the affected file (or files) and push back to the repository:
+
+1. Migrate the file to LFS:
+
+ ```shell
+ git lfs migrate import --yes --no-rewrite ""
+ ```
+
+1. Push back to your repository:
+
+ ```shell
+ git push
+ ```
+
+1. (Optional) Clean up your `.git` folder:
+
+ ```shell
+ git reflog expire --expire-unreachable=now --all
+ git gc --prune=now
+ ```
+
### error: Repository or object not found
There are a couple of reasons why this error can occur:
diff --git a/doc/topics/plan_and_track.md b/doc/topics/plan_and_track.md
new file mode 100644
index 00000000000..662898e88fc
--- /dev/null
+++ b/doc/topics/plan_and_track.md
@@ -0,0 +1,28 @@
+---
+stage:
+group:
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Plan and track work **(FREE)**
+
+Plan your work by creating requirements, issues, and epics. Schedule work
+with milestones and track your team's time. Learn how to save time with
+quick actions, see how GitLab renders Markdown text, and learn how to
+use Git to interact with GitLab.
+
+- [Epics](../user/group/epics/index.md)
+- [Issues](../user/project/issues/index.md)
+- [Labels](../user/project/labels.md)
+- [Discussions](../user/discussions/index.md)
+- [Iterations](../user/group/iterations/index.md)
+- [Milestones](../user/project/milestones/index.md)
+- [Requirements](../user/project/requirements/index.md)
+- [Roadmaps](../user/group/roadmap/index.md)
+- [Time tracking](../user/project/time_tracking.md)
+- [Wikis](../user/project/wiki/index.md)
+- [Keyboard shortcuts](../user/shortcuts.md)
+- [Quick actions](../user/project/quick_actions.md)
+- [Markdown](../user/markdown.md)
+- [To-Do lists](../user/todos.md)
+- [Using Git](../topics/git/index.md)
diff --git a/doc/topics/release_your_application.md b/doc/topics/release_your_application.md
new file mode 100644
index 00000000000..31eb7705760
--- /dev/null
+++ b/doc/topics/release_your_application.md
@@ -0,0 +1,13 @@
+---
+stage:
+group:
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Release your application **(FREE)**
+
+Release your application internally or to the public. Use
+flags to release features incrementally.
+
+- [Releases](../user/project/releases/index.md)
+- [Feature flags](../operations/feature_flags.md)
diff --git a/doc/topics/set_up_organization.md b/doc/topics/set_up_organization.md
new file mode 100644
index 00000000000..d8b1ab59b9e
--- /dev/null
+++ b/doc/topics/set_up_organization.md
@@ -0,0 +1,16 @@
+---
+stage:
+group:
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Set up your organization **(FREE)**
+
+Configure your organization and its users. Determine user roles
+and give everyone access to the projects they need.
+
+- [Members](../user/project/members/index.md)
+- [Groups](../user/group/index.md)
+- [User account options](../user/profile/index.md)
+- [SSH keys](../ssh/README.md)
+- [GitLab.com settings](../user/gitlab_com/index.md)
diff --git a/doc/topics/use_gitlab.md b/doc/topics/use_gitlab.md
new file mode 100644
index 00000000000..f45dc91131c
--- /dev/null
+++ b/doc/topics/use_gitlab.md
@@ -0,0 +1,19 @@
+---
+stage:
+group:
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Use GitLab **(FREE)**
+
+Get to know the GitLab end-to-end workflow. Configure permissions,
+organize your work, create and secure your application, and analyze its performance. Report on team productivity throughout the process.
+
+- [Set up your organization](set_up_organization.md)
+- [Organize work with projects](../user/project/index.md)
+- [Plan and track work](plan_and_track.md)
+- [Build your application](build_your_application.md)
+- [Secure your application](../user/application_security/index.md)
+- [Release your application](release_your_application.md)
+- [Monitor application performance](../operations/index.md)
+- [Analyze GitLab usage](../user/analytics/index.md)
diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md
index d50a183aa54..8c67163c4b0 100644
--- a/doc/user/analytics/index.md
+++ b/doc/user/analytics/index.md
@@ -4,7 +4,7 @@ group: Optimize
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Analytics **(FREE)**
+# Analyze GitLab usage **(FREE)**
## Definitions
diff --git a/doc/user/analytics/value_stream_analytics.md b/doc/user/analytics/value_stream_analytics.md
index 2af98492ee7..c311317b909 100644
--- a/doc/user/analytics/value_stream_analytics.md
+++ b/doc/user/analytics/value_stream_analytics.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Value Stream Analytics **(FREE)**
> - Introduced as Cycle Analytics prior to GitLab 12.3 at the project level.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12077) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3 at the group level.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12077) in GitLab Premium 12.3 at the group level.
> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23427) from Cycle Analytics to Value Stream Analytics in GitLab 12.8.
Value Stream Analytics measures the time spent to go from an
@@ -15,20 +15,20 @@ Value Stream Analytics measures the time spent to go from an
(also known as cycle time) for each of your projects or groups. Value Stream Analytics displays the median time
spent in each stage defined in the process.
-Value Stream Analytics is useful in order to quickly determine the velocity of a given
+You can use Value Stream Analytics to determine the velocity of a given
project. It points to bottlenecks in the development process, enabling management
to uncover, triage, and identify the root cause of slowdowns in the software development life cycle.
-For information on how to contribute to the development of Value Stream Analytics, see our [contributor documentation](../../development/value_stream_analytics.md).
+For information about how to contribute to the development of Value Stream Analytics, see our [contributor documentation](../../development/value_stream_analytics.md).
-Project-level Value Stream Analytics is available via **Project > Analytics > Value Stream**.
+Project-level Value Stream Analytics is available by using **Project > Analytics > Value Stream**.
NOTE:
[Group-level Value Stream Analytics](../group/value_stream_analytics) is also available.
## Default stages
-The stages tracked by Value Stream Analytics by default represent the [GitLab flow](../../topics/gitlab_flow.md). These stages can be customized in Group Level Value Stream Analytics.
+The stages tracked by Value Stream Analytics by default represent the [GitLab flow](../../topics/gitlab_flow.md). You can customize these stages in group-level Value Stream Analytics.
- **Issue** (Tracker)
- Time to schedule an issue (by milestone or by adding it to an issue board)
@@ -38,55 +38,51 @@ The stages tracked by Value Stream Analytics by default represent the [GitLab fl
- Time to create a merge request
- **Test** (CI)
- Time it takes GitLab CI/CD to test your code
-- **Review** (Merge Request/MR)
+- **Review** (Merge request)
- Time spent on code review
- **Staging** (Continuous Deployment)
- Time between merging and deploying to production
### Date ranges
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/36300) in GitLab 10.0.
+To filter analytics results based on a date range, select one of these options:
-GitLab provides the ability to filter analytics based on a date range. To filter results, select one of these options:
-
-1. Last 7 days
-1. Last 30 days (default)
-1. Last 90 days
+- **Last 7 days**
+- **Last 30 days** (default)
+- **Last 90 days**
## How Time metrics are measured
-The "Time" metrics near the top of the page are measured as follows:
+The **Time** metrics near the top of the page are measured as follows:
-- **Lead time**: median time from issue created to issue closed.
-- **Cycle time**: median time from first commit to issue closed. (You can associate a commit with an issue by [crosslinking in the commit message](../project/issues/crosslinking_issues.md#from-commit-messages).)
+- **Lead time**: Median time from issue created to issue closed.
+- **Cycle time**: Median time from first commit to issue closed. (You can associate a commit with an issue by [crosslinking in the commit message](../project/issues/crosslinking_issues.md#from-commit-messages).)
## How the stages are measured
-Value Stream Analytics uses start events and stop events to measure the time that an Issue or MR spends in each stage.
-For example, a stage might start when one label is added to an issue, and end when another label is added.
-Items are not included in the stage time calculation if they have not reached the stop event.
+Value Stream Analytics uses start events and stop events to measure the time that an issue or merge request spends in each stage.
+For example, a stage might start when one label is added to an issue and end when another label is added.
+Items aren't included in the stage time calculation if they have not reached the stop event.
-Each stage of Value Stream Analytics is further described in the table below.
+| Stage | Description |
+|---------|---------------|
+| Issue | Measures the median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone, whichever comes first. The label is tracked only if it already includes an [Issue Board list](../project/issue_board.md) created for it. |
+| Plan | Measures the median time between the action you took for the previous stage, and pushing the first commit to the branch. That first branch commit triggers the separation between **Plan** and **Code**, and at least one of the commits in the branch must include the related issue number (such as `#42`). If the issue number is *not* included in a commit, that data is not included in the measurement time of the stage. |
+| Code | Measures the median time between pushing a first commit (previous stage) and creating a merge request (MR). The process is tracked with the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically) in the description of the merge request. For example, if the issue is closed with `Closes #xxx`, it's assumed that `xxx` is issue number for the merge request). If there is no closing pattern, the start time is set to the create time of the first commit. |
+| Test | Essentially the start to finish time for all pipelines. Measures the median time to run the entire pipeline for that project. Related to the time required by GitLab CI/CD to run every job for the commits pushed to that merge request, as defined in the previous stage. |
+| Review | Measures the median time taken to review merge requests with a closing issue pattern, from creation to merge. |
+| Staging | Measures the median time between merging the merge request (with a closing issue pattern) to the first deployment to a [production environment](#how-the-production-environment-is-identified). Data not collected without a production environment. |
-| **Stage** | **Description** |
-| --------- | --------------- |
-| Issue | Measures the median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone, whichever comes first. The label is tracked only if it already includes an [Issue Board list](../project/issue_board.md) created for it. |
-| Plan | Measures the median time between the action you took for the previous stage, and pushing the first commit to the branch. That first branch commit triggers the separation between **Plan** and **Code**, and at least one of the commits in the branch must include the related issue number (such as `#42`). If the issue number is *not* included in a commit, that data is not included in the measurement time of the stage. |
-| Code | Measures the median time between pushing a first commit (previous stage) and creating a merge request (MR). The process is tracked with the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically) in the description of the merge request. For example, if the issue is closed with `Closes #xxx`, it's assumed that `xxx` is issue number for the merge request). If there is no closing pattern, the start time is set to the create time of the first commit. |
-| Test | Essentially the start to finish time for all pipelines. Measures the median time to run the entire pipeline for that project. Related to the time required by GitLab CI/CD to run every job for the commits pushed to that merge request, as defined in the previous stage. |
-| Review | Measures the median time taken to review merge requests with a closing issue pattern, from creation to merge. |
-| Staging | Measures the median time between merging the merge request (with a closing issue pattern) to the first deployment to a [production environment](#how-the-production-environment-is-identified). Data not collected without a production environment. |
-
-How this works, behind the scenes:
+How this works:
1. Issues and merge requests are grouped in pairs, where the merge request has the
[closing pattern](../project/issues/managing_issues.md#closing-issues-automatically)
- for the corresponding issue. Issue/merge request pairs without closing patterns are
- **not** included.
-1. Issue/merge request pairs are filtered by the last XX days, specified through the UI
- (default = 90 days). Pairs outside the filtered range are not included.
+ for the corresponding issue. Issue and merge request pairs without closing patterns are
+ not included.
+1. Issue and merge request pairs are filtered by the last XX days, specified through the UI
+ (default is `90` days). Pairs outside the filtered range are not included.
1. For the remaining pairs, review information needed for stages, including
- issue creation date, merge request merge time, and so on.
+ issue creation date and merge request merge time.
In short, the Value Stream Analytics dashboard tracks data related to [GitLab flow](../../topics/gitlab_flow.md). It does not include data for:
@@ -97,67 +93,69 @@ In short, the Value Stream Analytics dashboard tracks data related to [GitLab fl
## How the production environment is identified
-Value Stream Analytics identifies production environments based on
-[the deployment tier of environments](../../ci/environments/index.md#deployment-tier-of-environments).
+Value Stream Analytics identifies production environments based on the
+[deployment tier of environments](../../ci/environments/index.md#deployment-tier-of-environments).
## Example workflow
-Below is a simple fictional workflow of a single cycle that happens in a
-single day passing through all seven stages. Note that if a stage does not have
-a start and a stop mark, it is not measured and hence not calculated in the median
-time. It is assumed that milestones are created and CI for testing and setting
+Here's a fictional workflow of a single cycle that happens in a
+single day, passing through all seven stages. If a stage doesn't have
+a start and a stop mark, it isn't measured and hence isn't calculated in the median
+time. It's assumed that milestones are created, and CI for testing and setting
environments is configured.
1. Issue is created at 09:00 (start of **Issue** stage).
-1. Issue is added to a milestone at 11:00 (stop of **Issue** stage / start of
+1. Issue is added to a milestone at 11:00 (stop of **Issue** stage and start of
**Plan** stage).
-1. Start working on the issue, create a branch locally and make one commit at
+1. Start working on the issue, create a branch locally, and make one commit at
12:00.
-1. Make a second commit to the branch which mentions the issue number at 12.30
- (stop of **Plan** stage / start of **Code** stage).
-1. Push branch and create a merge request that contains the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically)
- in its description at 14:00 (stop of **Code** stage / start of **Test** and
+1. Make a second commit to the branch that mentions the issue number at 12:30
+ (stop of **Plan** stage and start of **Code** stage).
+1. Push branch, and create a merge request that contains the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically)
+ in its description at 14:00 (stop of **Code** stage and start of **Test** and
**Review** stages).
1. The CI starts running your scripts defined in [`.gitlab-ci.yml`](../../ci/yaml/README.md) and
- takes 5min (stop of **Test** stage).
-1. Review merge request, ensure that everything is OK and merge the merge
- request at 19:00. (stop of **Review** stage / start of **Staging** stage).
-1. Now that the merge request is merged, a deployment to the `production`
+ takes 5 minutes (stop of **Test** stage).
+1. Review merge request, ensure that everything is okay, and then merge the merge
+ request at 19:00 (stop of **Review** stage and start of **Staging** stage).
+1. The merge request is merged, and a deployment to the `production`
environment starts and finishes at 19:30 (stop of **Staging** stage).
-From the above example we see the time used for each stage:
+From the previous example we see the time used for each stage:
-- **Issue**: 2h (11:00 - 09:00)
-- **Plan**: 1h (12:00 - 11:00)
-- **Code**: 2h (14:00 - 12:00)
-- **Test**: 5min
-- **Review**: 5h (19:00 - 14:00)
-- **Staging**: 30min (19:30 - 19:00)
+- **Issue**: 2 hrs (09:00 to 11:00)
+- **Plan**: 1 hr (11:00 to 12:00)
+- **Code**: 2 hrs (12:00 to 14:00)
+- **Test**: 5 mins
+- **Review**: 5 hrs (14:00 to 19:00)
+- **Staging**: 30 mins (19:00 to 19:30)
More information:
-- The above example specifies the issue number in a latter commit. The process
- still collects analytics data for that issue.
-- The time required in the **Test** stage is not included in the overall time of
- the cycle. It is included in the **Review** process, as every MR should be
+- Although the previous example specifies the issue number in a later commit, the process
+ still collects analytics data for the issue.
+- The time required in the **Test** stage isn't included in the overall time of
+ the cycle. The time is included in the **Review** process, as every merge request should be
tested.
-- The example above illustrates only **one cycle** of the multiple stages. Value
+- The previous example illustrates only one cycle of the multiple stages. Value
Stream Analytics, on its dashboard, shows the calculated median elapsed time
for these issues.
## Permissions
-The current permissions on the Project-level Value Stream Analytics dashboard are:
+The permissions for the project-level Value Stream Analytics dashboard include:
-- Public projects - anyone can access.
-- Internal projects - any authenticated user can access.
-- Private projects - any member Guest and above can access.
+| Project type | Permissions |
+|--------------|---------------------------------------|
+| Public | Anyone can access |
+| Internal | Any authenticated user can access |
+| Private | Any member Guest and above can access |
You can [read more about permissions](../../user/permissions.md) in general.
## More resources
-Learn more about Value Stream Analytics in the following resources:
+Learn more about Value Stream Analytics with the following resources:
- [Value Stream Analytics feature page](https://about.gitlab.com/stages-devops-lifecycle/value-stream-analytics/).
- [Value Stream Analytics feature preview](https://about.gitlab.com/blog/2016/09/16/feature-preview-introducing-cycle-analytics/).
diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md
index 60f77ab048d..be9a3aec98e 100644
--- a/doc/user/application_security/index.md
+++ b/doc/user/application_security/index.md
@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference, howto
---
-# Application security **(ULTIMATE)**
+# Secure your application **(ULTIMATE)**
GitLab can check your application for security vulnerabilities including:
diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md
index 341723a0abb..faa394baacb 100644
--- a/doc/user/project/clusters/index.md
+++ b/doc/user/project/clusters/index.md
@@ -61,6 +61,9 @@ Kubernetes version to any supported version at any time:
Some GitLab features may support versions outside the range provided here.
+NOTE:
+[GKE Cluster creation](add_remove_clusters.md#create-new-cluster) by GitLab is currently not supported for Kubernetes 1.19+. For these versions you can create the cluster through GCP, then [Add existing cluster](add_remove_clusters.md#add-existing-cluster). See [the related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/331922) for more information.
+
### Adding and removing clusters
See [Adding and removing Kubernetes clusters](add_remove_clusters.md) for details on how
diff --git a/doc/user/project/index.md b/doc/user/project/index.md
index d9283f623d4..df14c9d328e 100644
--- a/doc/user/project/index.md
+++ b/doc/user/project/index.md
@@ -5,7 +5,7 @@ info: "To determine the technical writer assigned to the Stage/Group associated
type: reference
---
-# Projects **(FREE)**
+# Organize work with projects **(FREE)**
In GitLab, you can create projects to host
your codebase. You can also use projects to track issues, plan work,
diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md
index e1b6956f873..e02a10ecfbc 100644
--- a/doc/user/project/issue_board.md
+++ b/doc/user/project/issue_board.md
@@ -583,7 +583,15 @@ When dragging issues between lists, different behavior occurs depending on the s
### Multi-select issue cards
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18954) in GitLab 12.4.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18954) in GitLab 12.4.
+> - [Placed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61955) behind a [feature flag](../feature_flags.md), disabled by default in GitLab 14.0.
+> - Disabled on GitLab.com.
+> - Not recommended for production use.
+> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-multi-selecting-issue-cards). **(FREE SELF)**
+
+This in-development feature might not be available for your use. There can be
+[risks when enabling features still in development](../feature_flags.md#risks-when-enabling-features-still-in-development).
+Refer to this feature's version history for more details.
You can select multiple issue cards, then drag the group to another position within the list, or to
another list. This makes it faster to reorder many issues at once.
@@ -685,3 +693,22 @@ To disable it:
```ruby
Feature.disable(:iteration_board_lists)
```
+
+### Enable or disable multi-selecting issue cards **(FREE SELF)**
+
+Multi-selecting issue cards is under development and not ready for production use. It is
+deployed behind a feature flag that is **disabled by default**.
+[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
+can enable it.
+
+To enable it:
+
+```ruby
+Feature.enable(:board_multi_select)
+```
+
+To disable it:
+
+```ruby
+Feature.disable(:board_multi_select)
+```
diff --git a/lib/bulk_imports/common/extractors/ndjson_extractor.rb b/lib/bulk_imports/common/extractors/ndjson_extractor.rb
new file mode 100644
index 00000000000..27dfb0dcce5
--- /dev/null
+++ b/lib/bulk_imports/common/extractors/ndjson_extractor.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module BulkImports
+ module Common
+ module Extractors
+ class NdjsonExtractor
+ include Gitlab::ImportExport::CommandLineUtil
+ include Gitlab::Utils::StrongMemoize
+
+ EXPORT_DOWNLOAD_URL_PATH = "/%{resource}/%{full_path}/export_relations/download?relation=%{relation}"
+
+ def initialize(relation:)
+ @relation = relation
+ @tmp_dir = Dir.mktmpdir
+ end
+
+ def extract(context)
+ download_service(tmp_dir, context).execute
+ decompression_service(tmp_dir).execute
+ relations = ndjson_reader(tmp_dir).consume_relation('', relation)
+
+ BulkImports::Pipeline::ExtractedData.new(data: relations)
+ end
+
+ def remove_tmp_dir
+ FileUtils.remove_entry(tmp_dir)
+ end
+
+ private
+
+ attr_reader :relation, :tmp_dir
+
+ def filename
+ @filename ||= "#{relation}.ndjson.gz"
+ end
+
+ def download_service(tmp_dir, context)
+ @download_service ||= BulkImports::FileDownloadService.new(
+ configuration: context.configuration,
+ relative_url: relative_resource_url(context),
+ dir: tmp_dir,
+ filename: filename
+ )
+ end
+
+ def decompression_service(tmp_dir)
+ @decompression_service ||= BulkImports::FileDecompressionService.new(
+ dir: tmp_dir,
+ filename: filename
+ )
+ end
+
+ def ndjson_reader(tmp_dir)
+ @ndjson_reader ||= Gitlab::ImportExport::JSON::NdjsonReader.new(tmp_dir)
+ end
+
+ def relative_resource_url(context)
+ strong_memoize(:relative_resource_url) do
+ resource = context.portable.class.name.downcase.pluralize
+ encoded_full_path = context.entity.encoded_source_full_path
+
+ EXPORT_DOWNLOAD_URL_PATH % { resource: resource, full_path: encoded_full_path, relation: relation }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bulk_imports/groups/graphql/get_labels_query.rb b/lib/bulk_imports/groups/graphql/get_labels_query.rb
deleted file mode 100644
index f957cf0be52..00000000000
--- a/lib/bulk_imports/groups/graphql/get_labels_query.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# frozen_string_literal: true
-
-module BulkImports
- module Groups
- module Graphql
- module GetLabelsQuery
- extend self
-
- def to_s
- <<-'GRAPHQL'
- query ($full_path: ID!, $cursor: String, $per_page: Int) {
- group(fullPath: $full_path) {
- labels(first: $per_page, after: $cursor, onlyGroupLabels: true) {
- page_info: pageInfo {
- next_page: endCursor
- has_next_page: hasNextPage
- }
- nodes {
- title
- description
- color
- created_at: createdAt
- updated_at: updatedAt
- }
- }
- }
- }
- GRAPHQL
- end
-
- def variables(context)
- {
- full_path: context.entity.source_full_path,
- cursor: context.tracker.next_page,
- per_page: ::BulkImports::Tracker::DEFAULT_PAGE_SIZE
- }
- end
-
- def base_path
- %w[data group labels]
- end
-
- def data_path
- base_path << 'nodes'
- end
-
- def page_info_path
- base_path << 'page_info'
- end
- end
- end
- end
-end
diff --git a/lib/bulk_imports/groups/pipelines/entity_finisher.rb b/lib/bulk_imports/groups/pipelines/entity_finisher.rb
index 1d237bc0f7f..afe954a64d6 100644
--- a/lib/bulk_imports/groups/pipelines/entity_finisher.rb
+++ b/lib/bulk_imports/groups/pipelines/entity_finisher.rb
@@ -4,6 +4,10 @@ module BulkImports
module Groups
module Pipelines
class EntityFinisher
+ def self.ndjson_pipeline?
+ false
+ end
+
def initialize(context)
@context = context
end
diff --git a/lib/bulk_imports/groups/pipelines/labels_pipeline.rb b/lib/bulk_imports/groups/pipelines/labels_pipeline.rb
index 0dc4a968b84..806db68e5d1 100644
--- a/lib/bulk_imports/groups/pipelines/labels_pipeline.rb
+++ b/lib/bulk_imports/groups/pipelines/labels_pipeline.rb
@@ -4,15 +4,35 @@ module BulkImports
module Groups
module Pipelines
class LabelsPipeline
- include Pipeline
+ include NdjsonPipeline
- extractor BulkImports::Common::Extractors::GraphqlExtractor,
- query: BulkImports::Groups::Graphql::GetLabelsQuery
+ RELATION = 'labels'
- transformer Common::Transformers::ProhibitedAttributesTransformer
+ extractor ::BulkImports::Common::Extractors::NdjsonExtractor, relation: RELATION
- def load(context, data)
- Labels::CreateService.new(data).execute(group: context.group)
+ def transform(context, data)
+ relation_hash = data.first
+ relation_index = data.last
+ relation_definition = import_export_config.top_relation_tree(RELATION)
+
+ deep_transform_relation!(relation_hash, RELATION, relation_definition) do |key, hash|
+ Gitlab::ImportExport::Group::RelationFactory.create(
+ relation_index: relation_index,
+ relation_sym: key.to_sym,
+ relation_hash: hash,
+ importable: context.portable,
+ members_mapper: nil,
+ object_builder: object_builder,
+ user: context.current_user,
+ excluded_keys: import_export_config.relation_excluded_keys(key)
+ )
+ end
+ end
+
+ def load(_, label)
+ return unless label
+
+ label.save! unless label.persisted?
end
end
end
diff --git a/lib/bulk_imports/ndjson_pipeline.rb b/lib/bulk_imports/ndjson_pipeline.rb
new file mode 100644
index 00000000000..4f5f94c30b8
--- /dev/null
+++ b/lib/bulk_imports/ndjson_pipeline.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module BulkImports
+ module NdjsonPipeline
+ extend ActiveSupport::Concern
+
+ include Pipeline
+
+ included do
+ ndjson_pipeline!
+
+ def deep_transform_relation!(relation_hash, relation_key, relation_definition, &block)
+ relation_key = relation_key_override(relation_key)
+
+ relation_definition.each do |sub_relation_key, sub_relation_definition|
+ sub_relation = relation_hash[sub_relation_key]
+
+ next unless sub_relation
+
+ current_item =
+ if sub_relation.is_a?(Array)
+ sub_relation
+ .map { |entry| deep_transform_relation!(entry, sub_relation_key, sub_relation_definition, &block) }
+ .tap { |entry| entry.compact! }
+ .presence
+ else
+ deep_transform_relation!(sub_relation, sub_relation_key, sub_relation_definition, &block)
+ end
+
+ if current_item
+ relation_hash[sub_relation_key] = current_item
+ else
+ relation_hash.delete(sub_relation_key)
+ end
+ end
+
+ yield(relation_key, relation_hash)
+ end
+
+ def after_run(_)
+ extractor.remove_tmp_dir if extractor.respond_to?(:remove_tmp_dir)
+ end
+
+ def relation_class(relation_key)
+ relation_key.to_s.classify.constantize
+ rescue NameError
+ relation_key.to_s.constantize
+ end
+
+ def relation_key_override(relation_key)
+ relation_key_overrides[relation_key.to_sym]&.to_s || relation_key
+ end
+
+ def relation_key_overrides
+ "Gitlab::ImportExport::#{portable.class}::RelationFactory::OVERRIDES".constantize
+ end
+
+ def object_builder
+ "Gitlab::ImportExport::#{portable.class}::ObjectBuilder".constantize
+ end
+ end
+ end
+end
diff --git a/lib/bulk_imports/pipeline.rb b/lib/bulk_imports/pipeline.rb
index df4f020d6b2..24aa7482974 100644
--- a/lib/bulk_imports/pipeline.rb
+++ b/lib/bulk_imports/pipeline.rb
@@ -8,8 +8,11 @@ module BulkImports
include Runner
NotAllowedError = Class.new(StandardError)
+ ExpiredError = Class.new(StandardError)
+ FailedError = Class.new(StandardError)
CACHE_KEY_EXPIRATION = 2.hours
+ NDJSON_EXPORT_TIMEOUT = 30.minutes
def initialize(context)
@context = context
@@ -19,6 +22,14 @@ module BulkImports
@tracker ||= context.tracker
end
+ def portable
+ @portable ||= context.portable
+ end
+
+ def import_export_config
+ @import_export_config ||= context.import_export_config
+ end
+
included do
private
@@ -111,7 +122,7 @@ module BulkImports
options = class_config[:options]
if options
- class_config[:klass].new(class_config[:options])
+ class_config[:klass].new(**class_config[:options])
else
class_config[:klass].new
end
@@ -155,6 +166,14 @@ module BulkImports
class_attributes[:abort_on_failure]
end
+ def ndjson_pipeline!
+ class_attributes[:ndjson_pipeline] = true
+ end
+
+ def ndjson_pipeline?
+ class_attributes[:ndjson_pipeline]
+ end
+
private
def add_attribute(sym, klass, options)
diff --git a/lib/bulk_imports/pipeline/context.rb b/lib/bulk_imports/pipeline/context.rb
index 3c69c729f36..d753f888671 100644
--- a/lib/bulk_imports/pipeline/context.rb
+++ b/lib/bulk_imports/pipeline/context.rb
@@ -16,6 +16,14 @@ module BulkImports
@entity ||= tracker.entity
end
+ def portable
+ @portable ||= entity.group || entity.project
+ end
+
+ def import_export_config
+ @import_export_config ||= ::BulkImports::FileTransfer.config_for(portable)
+ end
+
def group
@group ||= entity.group
end
diff --git a/lib/bulk_imports/pipeline/extracted_data.rb b/lib/bulk_imports/pipeline/extracted_data.rb
index c9e54b61dd3..0b36c068298 100644
--- a/lib/bulk_imports/pipeline/extracted_data.rb
+++ b/lib/bulk_imports/pipeline/extracted_data.rb
@@ -6,7 +6,7 @@ module BulkImports
attr_reader :data
def initialize(data: nil, page_info: {})
- @data = Array.wrap(data)
+ @data = data.is_a?(Enumerator) ? data : Array.wrap(data)
@page_info = page_info
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index cd501dcf34a..d55cef9eafb 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -37506,6 +37506,9 @@ msgstr ""
msgid "You have insufficient permissions to create an on-call schedule for this project"
msgstr ""
+msgid "You have insufficient permissions to remove an escalation policy from this project"
+msgstr ""
+
msgid "You have insufficient permissions to remove an on-call rotation from this project"
msgstr ""
diff --git a/spec/features/boards/multi_select_spec.rb b/spec/features/boards/multi_select_spec.rb
index ca322355b8f..057464326fa 100644
--- a/spec/features/boards/multi_select_spec.rb
+++ b/spec/features/boards/multi_select_spec.rb
@@ -41,9 +41,9 @@ RSpec.describe 'Multi Select Issue', :js do
before do
project.add_maintainer(user)
- # multi-drag disabled with feature flag for now
+ # Multi select drag&drop support is temporarily disabled
# https://gitlab.com/gitlab-org/gitlab/-/issues/289797
- stub_feature_flags(graphql_board_lists: false)
+ stub_feature_flags(graphql_board_lists: false, board_multi_select: project)
sign_in(user)
end
diff --git a/spec/frontend/boards/components/board_card_spec.js b/spec/frontend/boards/components/board_card_spec.js
index a35dfcb497e..9a9ce7b8dc1 100644
--- a/spec/frontend/boards/components/board_card_spec.js
+++ b/spec/frontend/boards/components/board_card_spec.js
@@ -72,6 +72,10 @@ describe('Board card', () => {
await wrapper.vm.$nextTick();
};
+ beforeEach(() => {
+ window.gon = { features: {} };
+ });
+
afterEach(() => {
wrapper.destroy();
wrapper = null;
@@ -140,6 +144,10 @@ describe('Board card', () => {
});
describe('when using multi-select', () => {
+ beforeEach(() => {
+ window.gon = { features: { boardMultiSelect: true } };
+ });
+
it('should call vuex action "multiSelectBoardItem" with correct parameters', async () => {
await multiSelectCard();
diff --git a/spec/lib/bulk_imports/common/extractors/ndjson_extractor_spec.rb b/spec/lib/bulk_imports/common/extractors/ndjson_extractor_spec.rb
new file mode 100644
index 00000000000..55468b10114
--- /dev/null
+++ b/spec/lib/bulk_imports/common/extractors/ndjson_extractor_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::Common::Extractors::NdjsonExtractor do
+ let_it_be(:tmpdir) { Dir.mktmpdir }
+ let_it_be(:filepath) { 'spec/fixtures/bulk_imports/labels.ndjson.gz' }
+ let_it_be(:import) { create(:bulk_import) }
+ let_it_be(:config) { create(:bulk_import_configuration, bulk_import: import) }
+ let_it_be(:entity) { create(:bulk_import_entity, bulk_import: import) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
+
+ subject { described_class.new(relation: 'labels') }
+
+ before do
+ allow(FileUtils).to receive(:remove_entry).with(any_args).and_call_original
+
+ subject.instance_variable_set(:@tmp_dir, tmpdir)
+ end
+
+ after(:all) do
+ FileUtils.remove_entry(tmpdir) if File.directory?(tmpdir)
+ end
+
+ describe '#extract' do
+ before do
+ FileUtils.copy_file(filepath, File.join(tmpdir, 'labels.ndjson.gz'))
+
+ allow_next_instance_of(BulkImports::FileDownloadService) do |service|
+ allow(service).to receive(:execute)
+ end
+ end
+
+ it 'returns ExtractedData' do
+ extracted_data = subject.extract(context)
+ label = extracted_data.data.first.first
+
+ expect(extracted_data).to be_instance_of(BulkImports::Pipeline::ExtractedData)
+ expect(label['title']).to include('Label')
+ expect(label['description']).to include('Label')
+ expect(label['type']).to eq('GroupLabel')
+ end
+ end
+
+ describe '#remove_tmp_dir' do
+ it 'removes tmp dir' do
+ expect(FileUtils).to receive(:remove_entry).with(tmpdir).once
+
+ subject.remove_tmp_dir
+ end
+ end
+end
diff --git a/spec/lib/bulk_imports/groups/graphql/get_labels_query_spec.rb b/spec/lib/bulk_imports/groups/graphql/get_labels_query_spec.rb
deleted file mode 100644
index 61db644a372..00000000000
--- a/spec/lib/bulk_imports/groups/graphql/get_labels_query_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe BulkImports::Groups::Graphql::GetLabelsQuery do
- it 'has a valid query' do
- tracker = create(:bulk_import_tracker)
- context = BulkImports::Pipeline::Context.new(tracker)
-
- query = GraphQL::Query.new(
- GitlabSchema,
- described_class.to_s,
- variables: described_class.variables(context)
- )
- result = GitlabSchema.static_validator.validate(query)
-
- expect(result[:errors]).to be_empty
- end
-
- describe '#data_path' do
- it 'returns data path' do
- expected = %w[data group labels nodes]
-
- expect(described_class.data_path).to eq(expected)
- end
- end
-
- describe '#page_info_path' do
- it 'returns pagination information path' do
- expected = %w[data group labels page_info]
-
- expect(described_class.page_info_path).to eq(expected)
- end
- end
-end
diff --git a/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb b/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb
index 8af646d1101..2cefeec29a2 100644
--- a/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb
+++ b/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb
@@ -5,98 +5,87 @@ require 'spec_helper'
RSpec.describe BulkImports::Groups::Pipelines::LabelsPipeline do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
- let_it_be(:timestamp) { Time.new(2020, 01, 01).utc }
-
+ let_it_be(:bulk_import) { create(:bulk_import, user: user) }
+ let_it_be(:filepath) { 'spec/fixtures/bulk_imports/labels.ndjson.gz' }
let_it_be(:entity) do
create(
:bulk_import_entity,
+ group: group,
+ bulk_import: bulk_import,
source_full_path: 'source/full/path',
destination_name: 'My Destination Group',
- destination_namespace: group.full_path,
- group: group
+ destination_namespace: group.full_path
)
end
let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
+ let(:tmpdir) { Dir.mktmpdir }
+
+ before do
+ FileUtils.copy_file(filepath, File.join(tmpdir, 'labels.ndjson.gz'))
+ group.add_owner(user)
+ end
+
subject { described_class.new(context) }
describe '#run' do
- it 'imports a group labels' do
- first_page = extracted_data(title: 'label1', has_next_page: true)
- last_page = extracted_data(title: 'label2')
-
- allow_next_instance_of(BulkImports::Common::Extractors::GraphqlExtractor) do |extractor|
- allow(extractor)
- .to receive(:extract)
- .and_return(first_page, last_page)
+ it 'imports group labels into destination group and removes tmpdir' do
+ allow(Dir).to receive(:mktmpdir).and_return(tmpdir)
+ allow_next_instance_of(BulkImports::FileDownloadService) do |service|
+ allow(service).to receive(:execute)
end
- expect { subject.run }.to change(Label, :count).by(2)
+ expect { subject.run }.to change(::GroupLabel, :count).by(1)
- label = group.labels.order(:created_at).last
+ label = group.labels.first
- expect(label.title).to eq('label2')
- expect(label.description).to eq('desc')
- expect(label.color).to eq('#428BCA')
- expect(label.created_at).to eq(timestamp)
- expect(label.updated_at).to eq(timestamp)
+ expect(label.title).to eq('Label 1')
+ expect(label.description).to eq('Label 1')
+ expect(label.color).to eq('#6699cc')
+ expect(File.directory?(tmpdir)).to eq(false)
end
end
describe '#load' do
- it 'creates the label' do
- data = label_data('label')
+ context 'when label is not persisted' do
+ it 'saves the label' do
+ label = build(:group_label, group: group)
- expect { subject.load(context, data) }.to change(Label, :count).by(1)
+ expect(label).to receive(:save!)
- label = group.labels.first
+ subject.load(context, label)
+ end
+ end
- data.each do |key, value|
- expect(label[key]).to eq(value)
+ context 'when label is persisted' do
+ it 'does not save label' do
+ label = create(:group_label, group: group)
+
+ expect(label).not_to receive(:save!)
+
+ subject.load(context, label)
+ end
+ end
+
+ context 'when label is missing' do
+ it 'returns' do
+ expect(subject.load(context, nil)).to be_nil
end
end
end
describe 'pipeline parts' do
- it { expect(described_class).to include_module(BulkImports::Pipeline) }
+ it { expect(described_class).to include_module(BulkImports::NdjsonPipeline) }
it { expect(described_class).to include_module(BulkImports::Pipeline::Runner) }
- it 'has extractors' do
+ it 'has extractor' do
expect(described_class.get_extractor)
.to eq(
- klass: BulkImports::Common::Extractors::GraphqlExtractor,
- options: {
- query: BulkImports::Groups::Graphql::GetLabelsQuery
- }
+ klass: BulkImports::Common::Extractors::NdjsonExtractor,
+ options: { relation: described_class::RELATION }
)
end
-
- it 'has transformers' do
- expect(described_class.transformers)
- .to contain_exactly(
- { klass: BulkImports::Common::Transformers::ProhibitedAttributesTransformer, options: nil }
- )
- end
- end
-
- def label_data(title)
- {
- 'title' => title,
- 'description' => 'desc',
- 'color' => '#428BCA',
- 'created_at' => timestamp.to_s,
- 'updated_at' => timestamp.to_s
- }
- end
-
- def extracted_data(title:, has_next_page: false)
- page_info = {
- 'has_next_page' => has_next_page,
- 'next_page' => has_next_page ? 'cursor' : nil
- }
-
- BulkImports::Pipeline::ExtractedData.new(data: [label_data(title)], page_info: page_info)
end
end
diff --git a/spec/lib/bulk_imports/ndjson_pipeline_spec.rb b/spec/lib/bulk_imports/ndjson_pipeline_spec.rb
new file mode 100644
index 00000000000..37e9dc2d9f8
--- /dev/null
+++ b/spec/lib/bulk_imports/ndjson_pipeline_spec.rb
@@ -0,0 +1,123 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::NdjsonPipeline do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:klass) do
+ Class.new do
+ include BulkImports::NdjsonPipeline
+
+ attr_reader :portable
+
+ def initialize(portable)
+ @portable = portable
+ end
+ end
+ end
+
+ subject { klass.new(group) }
+
+ it 'marks pipeline as ndjson' do
+ expect(klass.ndjson_pipeline?).to eq(true)
+ end
+
+ describe '#deep_transform_relation!' do
+ it 'transforms relation hash' do
+ transformed = subject.deep_transform_relation!({}, 'test', {}) do |key, hash|
+ hash.merge(relation_key: key)
+ end
+
+ expect(transformed[:relation_key]).to eq('test')
+ end
+
+ context 'when subrelations is an array' do
+ it 'transforms each element of the array' do
+ relation_hash = {
+ 'key' => 'value',
+ 'labels' => [
+ { 'title' => 'label 1' },
+ { 'title' => 'label 2' },
+ { 'title' => 'label 3' }
+ ]
+ }
+ relation_definition = { 'labels' => {} }
+
+ transformed = subject.deep_transform_relation!(relation_hash, 'test', relation_definition) do |key, hash|
+ hash.merge(relation_key: key)
+ end
+
+ transformed['labels'].each do |label|
+ expect(label[:relation_key]).to eq('group_labels')
+ end
+ end
+ end
+
+ context 'when subrelation is a hash' do
+ it 'transforms subrelation hash' do
+ relation_hash = {
+ 'key' => 'value',
+ 'label' => { 'title' => 'label' }
+ }
+ relation_definition = { 'label' => {} }
+
+ transformed = subject.deep_transform_relation!(relation_hash, 'test', relation_definition) do |key, hash|
+ hash.merge(relation_key: key)
+ end
+
+ expect(transformed['label'][:relation_key]).to eq('group_label')
+ end
+ end
+
+ context 'when subrelation is nil' do
+ it 'removes subrelation' do
+ relation_hash = {
+ 'key' => 'value',
+ 'label' => { 'title' => 'label' }
+ }
+ relation_definition = { 'label' => {} }
+
+ transformed = subject.deep_transform_relation!(relation_hash, 'test', relation_definition) do |key, hash|
+ if key == 'group_label'
+ nil
+ else
+ hash
+ end
+ end
+
+ expect(transformed['label']).to be_nil
+ end
+ end
+ end
+
+ describe '#relation_class' do
+ context 'when relation name is pluralized' do
+ it 'returns constantized class' do
+ expect(subject.relation_class('MergeRequest::Metrics')).to eq(MergeRequest::Metrics)
+ end
+ end
+
+ context 'when relation name is singularized' do
+ it 'returns constantized class' do
+ expect(subject.relation_class('Badge')).to eq(Badge)
+ end
+ end
+ end
+
+ describe '#relation_key_override' do
+ context 'when portable is group' do
+ it 'returns group relation name override' do
+ expect(subject.relation_key_override('labels')).to eq('group_labels')
+ end
+ end
+
+ context 'when portable is project' do
+ subject { klass.new(project) }
+
+ it 'returns group relation name override' do
+ expect(subject.relation_key_override('labels')).to eq('project_labels')
+ end
+ end
+ end
+end
diff --git a/spec/lib/bulk_imports/pipeline/context_spec.rb b/spec/lib/bulk_imports/pipeline/context_spec.rb
index 5b7711ad5d7..83d6f494d53 100644
--- a/spec/lib/bulk_imports/pipeline/context_spec.rb
+++ b/spec/lib/bulk_imports/pipeline/context_spec.rb
@@ -6,6 +6,9 @@ RSpec.describe BulkImports::Pipeline::Context do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
let_it_be(:bulk_import) { create(:bulk_import, user: user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:project_entity) { create(:bulk_import_entity, :project_entity, project: project) }
+ let_it_be(:project_tracker) { create(:bulk_import_tracker, entity: project_entity) }
let_it_be(:entity) do
create(
@@ -51,4 +54,24 @@ RSpec.describe BulkImports::Pipeline::Context do
describe '#extra' do
it { expect(subject.extra).to eq(extra: :data) }
end
+
+ describe '#portable' do
+ it { expect(subject.portable).to eq(group) }
+
+ context 'when portable is project' do
+ subject { described_class.new(project_tracker) }
+
+ it { expect(subject.portable).to eq(project) }
+ end
+ end
+
+ describe '#import_export_config' do
+ it { expect(subject.import_export_config).to be_instance_of(BulkImports::FileTransfer::GroupConfig) }
+
+ context 'when portable is project' do
+ subject { described_class.new(project_tracker) }
+
+ it { expect(subject.import_export_config).to be_instance_of(BulkImports::FileTransfer::ProjectConfig) }
+ end
+ end
end
diff --git a/spec/lib/bulk_imports/pipeline_spec.rb b/spec/lib/bulk_imports/pipeline_spec.rb
index dda2e41f06c..48c265d6118 100644
--- a/spec/lib/bulk_imports/pipeline_spec.rb
+++ b/spec/lib/bulk_imports/pipeline_spec.rb
@@ -63,6 +63,7 @@ RSpec.describe BulkImports::Pipeline do
BulkImports::MyPipeline.transformer(klass, options)
BulkImports::MyPipeline.loader(klass, options)
BulkImports::MyPipeline.abort_on_failure!
+ BulkImports::MyPipeline.ndjson_pipeline!
expect(BulkImports::MyPipeline.get_extractor).to eq({ klass: klass, options: options })
@@ -74,6 +75,7 @@ RSpec.describe BulkImports::Pipeline do
expect(BulkImports::MyPipeline.get_loader).to eq({ klass: klass, options: options })
expect(BulkImports::MyPipeline.abort_on_failure?).to eq(true)
+ expect(BulkImports::MyPipeline.ndjson_pipeline?).to eq(true)
end
end
end
diff --git a/spec/models/bulk_imports/export_status_spec.rb b/spec/models/bulk_imports/export_status_spec.rb
new file mode 100644
index 00000000000..fde18705e35
--- /dev/null
+++ b/spec/models/bulk_imports/export_status_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::ExportStatus do
+ let_it_be(:relation) { 'labels' }
+ let_it_be(:import) { create(:bulk_import) }
+ let_it_be(:config) { create(:bulk_import_configuration, bulk_import: import) }
+ let_it_be(:entity) { create(:bulk_import_entity, bulk_import: import, source_full_path: 'foo') }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+
+ let(:response_double) do
+ double(parsed_response: [{ 'relation' => 'labels', 'status' => status, 'error' => 'error!' }])
+ end
+
+ subject { described_class.new(tracker, relation) }
+
+ before do
+ allow_next_instance_of(BulkImports::Clients::Http) do |client|
+ allow(client).to receive(:get).and_return(response_double)
+ end
+ end
+
+ describe '#started?' do
+ context 'when export status is started' do
+ let(:status) { BulkImports::Export::STARTED }
+
+ it 'returns true' do
+ expect(subject.started?).to eq(true)
+ end
+ end
+
+ context 'when export status is not started' do
+ let(:status) { BulkImports::Export::FAILED }
+
+ it 'returns false' do
+ expect(subject.started?).to eq(false)
+ end
+ end
+ end
+
+ describe '#failed' do
+ context 'when export status is failed' do
+ let(:status) { BulkImports::Export::FAILED }
+
+ it 'returns true' do
+ expect(subject.failed?).to eq(true)
+ end
+ end
+
+ context 'when export status is not failed' do
+ let(:status) { BulkImports::Export::STARTED }
+
+ it 'returns false' do
+ expect(subject.failed?).to eq(false)
+ end
+ end
+ end
+
+ describe '#error' do
+ let(:status) { BulkImports::Export::FAILED }
+
+ it 'returns error message' do
+ expect(subject.error).to eq('error!')
+ end
+
+ context 'when something goes wrong during export status fetch' do
+ it 'returns exception class as error' do
+ allow_next_instance_of(BulkImports::Clients::Http) do |client|
+ allow(client).to receive(:get).and_raise(StandardError, 'Error!')
+ end
+
+ expect(subject.error).to eq('Error!')
+ end
+ end
+ end
+end
diff --git a/spec/models/bulk_imports/file_transfer/group_config_spec.rb b/spec/models/bulk_imports/file_transfer/group_config_spec.rb
index 21da71de3c7..4611a00b0cc 100644
--- a/spec/models/bulk_imports/file_transfer/group_config_spec.rb
+++ b/spec/models/bulk_imports/file_transfer/group_config_spec.rb
@@ -12,8 +12,8 @@ RSpec.describe BulkImports::FileTransfer::GroupConfig do
subject { described_class.new(exportable) }
- describe '#exportable_tree' do
- it 'returns exportable tree' do
+ describe '#portable_tree' do
+ it 'returns portable tree' do
expect_next_instance_of(::Gitlab::ImportExport::AttributesFinder) do |finder|
expect(finder).to receive(:find_root).with(:group).and_call_original
end
@@ -30,9 +30,21 @@ RSpec.describe BulkImports::FileTransfer::GroupConfig do
end
end
- describe '#exportable_relations' do
+ describe '#portable_relations' do
it 'returns a list of top level exportable relations' do
expect(subject.portable_relations).to include('milestones', 'badges', 'boards', 'labels')
end
end
+
+ describe '#top_relation_tree' do
+ it 'returns relation tree of a top level relation' do
+ expect(subject.top_relation_tree('labels')).to eq('priorities' => {})
+ end
+ end
+
+ describe '#relation_excluded_keys' do
+ it 'returns excluded keys for relation' do
+ expect(subject.relation_excluded_keys('group')).to include('owner_id')
+ end
+ end
end
diff --git a/spec/models/bulk_imports/file_transfer/project_config_spec.rb b/spec/models/bulk_imports/file_transfer/project_config_spec.rb
index 021f96ac2a3..2995556a58d 100644
--- a/spec/models/bulk_imports/file_transfer/project_config_spec.rb
+++ b/spec/models/bulk_imports/file_transfer/project_config_spec.rb
@@ -12,8 +12,8 @@ RSpec.describe BulkImports::FileTransfer::ProjectConfig do
subject { described_class.new(exportable) }
- describe '#exportable_tree' do
- it 'returns exportable tree' do
+ describe 'portable_tree' do
+ it 'returns portable tree' do
expect_next_instance_of(::Gitlab::ImportExport::AttributesFinder) do |finder|
expect(finder).to receive(:find_root).with(:project).and_call_original
end
@@ -30,9 +30,21 @@ RSpec.describe BulkImports::FileTransfer::ProjectConfig do
end
end
- describe '#exportable_relations' do
+ describe '#portable_relations' do
it 'returns a list of top level exportable relations' do
expect(subject.portable_relations).to include('issues', 'labels', 'milestones', 'merge_requests')
end
end
+
+ describe '#top_relation_tree' do
+ it 'returns relation tree of a top level relation' do
+ expect(subject.top_relation_tree('labels')).to eq('priorities' => {})
+ end
+ end
+
+ describe '#relation_excluded_keys' do
+ it 'returns excluded keys for relation' do
+ expect(subject.relation_excluded_keys('project')).to include('creator_id')
+ end
+ end
end
diff --git a/spec/services/bulk_imports/file_download_service_spec.rb b/spec/services/bulk_imports/file_download_service_spec.rb
index 9d34a93a09d..5171bb40f0a 100644
--- a/spec/services/bulk_imports/file_download_service_spec.rb
+++ b/spec/services/bulk_imports/file_download_service_spec.rb
@@ -32,11 +32,21 @@ RSpec.describe BulkImports::FileDownloadService do
end
end
- it 'downloads file' do
- subject.execute
+ shared_examples 'downloads file' do
+ it 'downloads file' do
+ subject.execute
- expect(File.exist?(filepath)).to eq(true)
- expect(File.read(filepath)).to include('chunk')
+ expect(File.exist?(filepath)).to eq(true)
+ expect(File.read(filepath)).to include('chunk')
+ end
+ end
+
+ include_examples 'downloads file'
+
+ context 'when content-type is application/gzip' do
+ let_it_be(:content_type) { 'application/gzip' }
+
+ include_examples 'downloads file'
end
context 'when url is not valid' do
diff --git a/spec/workers/bulk_imports/pipeline_worker_spec.rb b/spec/workers/bulk_imports/pipeline_worker_spec.rb
index 27151177634..44c31714d09 100644
--- a/spec/workers/bulk_imports/pipeline_worker_spec.rb
+++ b/spec/workers/bulk_imports/pipeline_worker_spec.rb
@@ -8,10 +8,16 @@ RSpec.describe BulkImports::PipelineWorker do
def initialize(_); end
def run; end
+
+ def self.ndjson_pipeline?
+ false
+ end
end
end
- let_it_be(:entity) { create(:bulk_import_entity) }
+ let_it_be(:bulk_import) { create(:bulk_import) }
+ let_it_be(:config) { create(:bulk_import_configuration, bulk_import: bulk_import) }
+ let_it_be(:entity) { create(:bulk_import_entity, bulk_import: bulk_import) }
before do
stub_const('FakePipeline', pipeline_class)
@@ -27,6 +33,7 @@ RSpec.describe BulkImports::PipelineWorker do
expect(BulkImports::Stage)
.to receive(:pipeline_exists?)
.with('FakePipeline')
+ .twice
.and_return(true)
expect_next_instance_of(Gitlab::Import::Logger) do |logger|
@@ -122,4 +129,114 @@ RSpec.describe BulkImports::PipelineWorker do
expect(pipeline_tracker.jid).to eq('jid')
end
end
+
+ context 'when ndjson pipeline' do
+ let(:ndjson_pipeline) do
+ Class.new do
+ def initialize(_); end
+
+ def run; end
+
+ def self.ndjson_pipeline?
+ true
+ end
+ end
+ end
+
+ let(:pipeline_tracker) do
+ create(
+ :bulk_import_tracker,
+ entity: entity,
+ pipeline_name: 'NdjsonPipeline'
+ )
+ end
+
+ before do
+ stub_const('NdjsonPipeline', ndjson_pipeline)
+ stub_const('NdjsonPipeline::RELATION', 'test')
+ allow(BulkImports::Stage)
+ .to receive(:pipeline_exists?)
+ .with('NdjsonPipeline')
+ .and_return(true)
+ end
+
+ it 'runs the pipeline successfully' do
+ allow_next_instance_of(BulkImports::ExportStatus) do |status|
+ allow(status).to receive(:started?).and_return(false)
+ allow(status).to receive(:failed?).and_return(false)
+ end
+
+ subject.perform(pipeline_tracker.id, pipeline_tracker.stage, entity.id)
+
+ expect(pipeline_tracker.reload.status_name).to eq(:finished)
+ end
+
+ context 'when export status is started' do
+ it 'reenqueues pipeline worker' do
+ allow_next_instance_of(BulkImports::ExportStatus) do |status|
+ allow(status).to receive(:started?).and_return(true)
+ allow(status).to receive(:failed?).and_return(false)
+ end
+
+ expect(described_class)
+ .to receive(:perform_in)
+ .with(
+ described_class::NDJSON_PIPELINE_PERFORM_DELAY,
+ pipeline_tracker.id,
+ pipeline_tracker.stage,
+ entity.id
+ )
+
+ subject.perform(pipeline_tracker.id, pipeline_tracker.stage, entity.id)
+ end
+ end
+
+ context 'when job reaches timeout' do
+ it 'marks as failed and logs the error' do
+ old_created_at = entity.created_at
+ entity.update!(created_at: (BulkImports::Pipeline::NDJSON_EXPORT_TIMEOUT + 1.hour).ago)
+
+ expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect(logger)
+ .to receive(:error)
+ .with(
+ worker: described_class.name,
+ pipeline_name: 'NdjsonPipeline',
+ entity_id: entity.id,
+ message: 'Pipeline timeout'
+ )
+ end
+
+ subject.perform(pipeline_tracker.id, pipeline_tracker.stage, entity.id)
+
+ expect(pipeline_tracker.reload.status_name).to eq(:failed)
+
+ entity.update!(created_at: old_created_at)
+ end
+ end
+
+ context 'when export status is failed' do
+ it 'marks as failed and logs the error' do
+ allow_next_instance_of(BulkImports::ExportStatus) do |status|
+ allow(status).to receive(:failed?).and_return(true)
+ allow(status).to receive(:error).and_return('Error!')
+ end
+
+ expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect(logger)
+ .to receive(:error)
+ .with(
+ worker: described_class.name,
+ pipeline_name: 'NdjsonPipeline',
+ entity_id: entity.id,
+ message: 'Error!'
+ )
+ end
+
+ subject.perform(pipeline_tracker.id, pipeline_tracker.stage, entity.id)
+
+ expect(pipeline_tracker.reload.status_name).to eq(:failed)
+ end
+ end
+ end
end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 7949b6158c1..72e52146baf 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -306,7 +306,6 @@ RSpec.describe 'Every Sidekiq worker' do
'IncidentManagement::OncallRotations::PersistAllRotationsShiftsJob' => 3,
'IncidentManagement::OncallRotations::PersistShiftsJob' => 3,
'IncidentManagement::PagerDuty::ProcessIncidentWorker' => 3,
- 'IncidentManagement::ProcessPrometheusAlertWorker' => 3,
'InvalidGpgSignatureUpdateWorker' => 3,
'IrkerWorker' => 3,
'IssuableExportCsvWorker' => 3,
diff --git a/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb b/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb
deleted file mode 100644
index 56f07459a15..00000000000
--- a/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe IncidentManagement::ProcessPrometheusAlertWorker do
- describe '#perform' do
- let_it_be(:project) { create(:project) }
- let_it_be(:prometheus_alert) { create(:prometheus_alert, project: project) }
-
- let(:payload_key) { Gitlab::AlertManagement::Payload::Prometheus.new(project: project, payload: alert_params).gitlab_fingerprint }
- let!(:prometheus_alert_event) { create(:prometheus_alert_event, prometheus_alert: prometheus_alert, payload_key: payload_key) }
- let!(:settings) { create(:project_incident_management_setting, project: project, create_issue: true) }
-
- let(:alert_params) do
- {
- startsAt: prometheus_alert.created_at.rfc3339,
- labels: {
- gitlab_alert_id: prometheus_alert.prometheus_metric_id
- }
- }.with_indifferent_access
- end
-
- it 'does nothing' do
- expect { subject.perform(project.id, alert_params) }
- .not_to change(Issue, :count)
- end
- end
-end