Commit aeed48cf authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch 'master' into ci-tables-ui-improvements

* master: (129 commits)
  Code style improvements
  remove require.context from network_bundle
  remove require.context from graphs_bundle
  remove require.context from filtered_search_bundle
  Ignore two Rails CVEs in bundler:audit job
  Remove Pages readme
  Change Pages redirect
  Add missing index.md to Pages docs
  Added double newline after file upload markdown insert
  Reorder main index items in Pages overview
  remove html comments
  remove <>
  wrapping text - part 3
  wrapping text - part 2 [ci skip]
  fix link
  wrap text - part 1 - [ci skip]
  typo
  fix spelling, add intermediate cert link
  Improve `Gitlab::EeCompatCheck` by using the `git apply --3way` flag
  remove link to unfinished video
  ...
parents f1971da9 f106ad51
...@@ -281,7 +281,7 @@ bundler:audit: ...@@ -281,7 +281,7 @@ bundler:audit:
- master@gitlab/gitlabhq - master@gitlab/gitlabhq
- master@gitlab/gitlab-ee - master@gitlab/gitlab-ee
script: script:
- "bundle exec bundle-audit check --update --ignore OSVDB-115941" - "bundle exec bundle-audit check --update --ignore OSVDB-115941 CVE-2016-6316 CVE-2016-6317"
migration paths: migration paths:
stage: test stage: test
......
This diff is collapsed.
8.17.0-pre 8.18.0-pre
<svg width="12" height="15" viewBox="0 0 12 15" xmlns="http://www.w3.org/2000/svg"><path d="M10.267 11.028V5.167c-.028-.728-.318-1.372-.878-1.923-.56-.55-1.194-.85-1.922-.877h-.934V.5l-2.8 2.8 2.8 2.8V4.233h.934a.976.976 0 0 1 .644.29.88.88 0 0 1 .289.644v5.861a1.86 1.86 0 0 0 .933 3.472 1.86 1.86 0 0 0 .934-3.472zM3.733 3.3a1.86 1.86 0 0 0-1.866-1.867 1.86 1.86 0 0 0-.934 3.472v6.123a1.86 1.86 0 0 0 .933 3.472 1.86 1.86 0 0 0 .934-3.472V4.905c.55-.317.933-.914.933-1.605z" fill-rule="nonzero"/></svg>
/* eslint-disable one-var, quote-props, comma-dangle, space-before-function-paren, import/newline-after-import, no-multi-spaces, max-len */ /* eslint-disable one-var, quote-props, comma-dangle, space-before-function-paren */
/* global Vue */ /* global Vue */
/* global BoardService */ /* global BoardService */
function requireAll(context) { return context.keys().map(context); }
window.Vue = require('vue'); window.Vue = require('vue');
window.Vue.use(require('vue-resource')); window.Vue.use(require('vue-resource'));
requireAll(require.context('./models', true, /^\.\/.*\.(js|es6)$/)); require('./models/issue');
requireAll(require.context('./stores', true, /^\.\/.*\.(js|es6)$/)); require('./models/label');
requireAll(require.context('./services', true, /^\.\/.*\.(js|es6)$/)); require('./models/list');
requireAll(require.context('./mixins', true, /^\.\/.*\.(js|es6)$/)); require('./models/milestone');
requireAll(require.context('./filters', true, /^\.\/.*\.(js|es6)$/)); require('./models/user');
require('./stores/boards_store');
require('./stores/modal_store');
require('./services/board_service');
require('./mixins/modal_mixins');
require('./mixins/sortable_default_options');
require('./filters/due_date_filters');
require('./components/board'); require('./components/board');
require('./components/board_sidebar'); require('./components/board_sidebar');
require('./components/new_list_dropdown'); require('./components/new_list_dropdown');
...@@ -93,17 +97,53 @@ $(() => { ...@@ -93,17 +97,53 @@ $(() => {
modal: ModalStore.store, modal: ModalStore.store,
store: Store.state, store: Store.state,
}, },
watch: {
disabled() {
this.updateTooltip();
},
},
computed: { computed: {
disabled() { disabled() {
return !this.store.lists.filter(list => list.type !== 'blank' && list.type !== 'done').length; return !this.store.lists.filter(list => list.type !== 'blank' && list.type !== 'done').length;
}, },
tooltipTitle() {
if (this.disabled) {
return 'Please add a list to your board first';
}
return '';
},
},
methods: {
updateTooltip() {
const $tooltip = $(this.$el);
this.$nextTick(() => {
if (this.disabled) {
$tooltip.tooltip();
} else {
$tooltip.tooltip('destroy');
}
});
},
openModal() {
if (!this.disabled) {
this.toggleModal(true);
}
},
},
mounted() {
this.updateTooltip();
}, },
template: ` template: `
<button <button
class="btn btn-create pull-right prepend-left-10 has-tooltip" class="btn btn-create pull-right prepend-left-10"
type="button" type="button"
:disabled="disabled" data-placement="bottom"
@click="toggleModal(true)"> :class="{ 'disabled': disabled }"
:title="tooltipTitle"
:aria-disabled="disabled"
@click="openModal">
Add issues Add issues
</button> </button>
`, `,
......
...@@ -4,10 +4,20 @@ ...@@ -4,10 +4,20 @@
window.Vue = require('vue'); window.Vue = require('vue');
window.Cookies = require('js-cookie'); window.Cookies = require('js-cookie');
require('./svg/icon_branch');
function requireAll(context) { return context.keys().map(context); } require('./svg/icon_build_status');
requireAll(require.context('./svg', false, /^\.\/.*\.(js|es6)$/)); require('./svg/icon_commit');
requireAll(require.context('.', true, /^\.\/(?!cycle_analytics_bundle).*\.(js|es6)$/)); require('./components/stage_code_component');
require('./components/stage_issue_component');
require('./components/stage_plan_component');
require('./components/stage_production_component');
require('./components/stage_review_component');
require('./components/stage_staging_component');
require('./components/stage_test_component');
require('./components/total_time_component');
require('./cycle_analytics_service');
require('./cycle_analytics_store');
require('./default_event_objects');
$(() => { $(() => {
const OVERVIEW_DIALOG_COOKIE = 'cycle_analytics_help_dismissed'; const OVERVIEW_DIALOG_COOKIE = 'cycle_analytics_help_dismissed';
......
/* eslint-disable func-names, comma-dangle, new-cap, no-new, import/newline-after-import, no-multi-spaces, max-len */ /* eslint-disable func-names, comma-dangle, new-cap, no-new, max-len */
/* global Vue */ /* global Vue */
/* global ResolveCount */ /* global ResolveCount */
function requireAll(context) { return context.keys().map(context); }
const Vue = require('vue'); const Vue = require('vue');
requireAll(require.context('./models', false, /^\.\/.*\.(js|es6)$/)); require('./models/discussion');
requireAll(require.context('./stores', false, /^\.\/.*\.(js|es6)$/)); require('./models/note');
requireAll(require.context('./services', false, /^\.\/.*\.(js|es6)$/)); require('./stores/comments');
requireAll(require.context('./mixins', false, /^\.\/.*\.(js|es6)$/)); require('./services/resolve');
requireAll(require.context('./components', false, /^\.\/.*\.(js|es6)$/)); require('./mixins/discussion');
require('./components/comment_resolve_btn');
require('./components/jump_to_discussion');
require('./components/resolve_btn');
require('./components/resolve_count');
require('./components/resolve_discussion_btn');
$(() => { $(() => {
const projectPath = document.querySelector('.merge-request').dataset.projectPath; const projectPath = document.querySelector('.merge-request').dataset.projectPath;
......
...@@ -126,13 +126,14 @@ require('./preview_markdown'); ...@@ -126,13 +126,14 @@ require('./preview_markdown');
}; };
pasteText = function(text) { pasteText = function(text) {
var afterSelection, beforeSelection, caretEnd, caretStart, textEnd; var afterSelection, beforeSelection, caretEnd, caretStart, textEnd;
var formattedText = text + "\n\n";
caretStart = $(child)[0].selectionStart; caretStart = $(child)[0].selectionStart;
caretEnd = $(child)[0].selectionEnd; caretEnd = $(child)[0].selectionEnd;
textEnd = $(child).val().length; textEnd = $(child).val().length;
beforeSelection = $(child).val().substring(0, caretStart); beforeSelection = $(child).val().substring(0, caretStart);
afterSelection = $(child).val().substring(caretEnd, textEnd); afterSelection = $(child).val().substring(caretEnd, textEnd);
$(child).val(beforeSelection + text + afterSelection); $(child).val(beforeSelection + formattedText + afterSelection);
child.get(0).setSelectionRange(caretStart + text.length, caretEnd + text.length); child.get(0).setSelectionRange(caretStart + formattedText.length, caretEnd + formattedText.length);
return form_textarea.trigger("input"); return form_textarea.trigger("input");
}; };
getFilename = function(e) { getFilename = function(e) {
......
...@@ -15,29 +15,29 @@ module.exports = Vue.component('actions-component', { ...@@ -15,29 +15,29 @@ module.exports = Vue.component('actions-component', {
}, },
template: ` template: `
<div class="inline"> <div class="btn-group" role="group">
<div class="dropdown"> <button class="dropdown btn btn-default dropdown-new" data-toggle="dropdown">
<a class="dropdown-new btn btn-default" data-toggle="dropdown"> <span>
<span class="js-dropdown-play-icon-container" v-html="playIconSvg"></span> <span class="js-dropdown-play-icon-container" v-html="playIconSvg"></span>
<i class="fa fa-caret-down"></i> <i class="fa fa-caret-down"></i>
</a> </span>
<ul class="dropdown-menu dropdown-menu-align-right"> <ul class="dropdown-menu dropdown-menu-align-right">
<li v-for="action in actions"> <li v-for="action in actions">
<a :href="action.play_path" <a :href="action.play_path"
data-method="post" data-method="post"
rel="nofollow" rel="nofollow"
class="js-manual-action-link"> class="js-manual-action-link">
<span class="js-action-play-icon-container" v-html="playIconSvg"></span> <span class="js-action-play-icon-container" v-html="playIconSvg"></span>
<span> <span>
{{action.name}} {{action.name}}
</span> </span>
</a> </a>
</li> </li>
</ul> </ul>
</div> </button>
</div> </div>
`, `,
}); });
...@@ -505,39 +505,26 @@ module.exports = Vue.component('environment-item', { ...@@ -505,39 +505,26 @@ module.exports = Vue.component('environment-item', {
<td class="hidden-xs"> <td class="hidden-xs">
<div v-if="!model.isFolder"> <div v-if="!model.isFolder">
<div v-if="hasManualActions && canCreateDeployment" <div class="btn-group" role="group">
class="inline js-manual-actions-container"> <actions-component v-if="hasManualActions && canCreateDeployment"
<actions-component
:play-icon-svg="playIconSvg" :play-icon-svg="playIconSvg"
:actions="manualActions"> :actions="manualActions">
</actions-component> </actions-component>
</div>
<div v-if="externalURL && canReadEnvironment" <external-url-component v-if="externalURL && canReadEnvironment"
class="inline js-external-url-container">
<external-url-component
:external-url="externalURL"> :external-url="externalURL">
</external-url-component> </external-url-component>
</div>
<div v-if="hasStopAction && canCreateDeployment" <stop-component v-if="hasStopAction && canCreateDeployment"
class="inline js-stop-component-container">
<stop-component
:stop-url="model.stop_path"> :stop-url="model.stop_path">
</stop-component> </stop-component>
</div>
<div v-if="model && model.terminal_path" <terminal-button-component v-if="model && model.terminal_path"
class="inline js-terminal-button-container">
<terminal-button-component
:terminal-icon-svg="terminalIconSvg" :terminal-icon-svg="terminalIconSvg"
:terminal-path="model.terminal_path"> :terminal-path="model.terminal_path">
</terminal-button-component> </terminal-button-component>
</div>
<div v-if="canRetry && canCreateDeployment" <rollback-component v-if="canRetry && canCreateDeployment"
class="inline js-rollback-component-container">
<rollback-component
:is-last-deployment="isLastDeployment" :is-last-deployment="isLastDeployment"
:retry-url="retryUrl"> :retry-url="retryUrl">
</rollback-component> </rollback-component>
......
function requireAll(context) { return context.keys().map(context); } require('./dropdown_hint');
require('./dropdown_non_user');
requireAll(require.context('./', true, /^\.\/(?!filtered_search_bundle).*\.(js|es6)$/)); require('./dropdown_user');
require('./dropdown_utils');
require('./filtered_search_dropdown_manager');
require('./filtered_search_dropdown');
require('./filtered_search_manager');
require('./filtered_search_token_keys');
require('./filtered_search_tokenizer');
// require everything else in this directory require('./stat_graph_contributors_graph');
function requireAll(context) { return context.keys().map(context); } require('./stat_graph_contributors_util');
requireAll(require.context('.', false, /^\.\/(?!graphs_bundle).*\.(js|es6)$/)); require('./stat_graph_contributors');
require('./stat_graph');
...@@ -2,9 +2,8 @@ ...@@ -2,9 +2,8 @@
/* global Network */ /* global Network */
/* global ShortcutsNetwork */ /* global ShortcutsNetwork */
// require everything else in this directory require('./branch_graph');
function requireAll(context) { return context.keys().map(context); } require('./network');
requireAll(require.context('.', false, /^\.\/(?!network_bundle).*\.(js|es6)$/));
(function() { (function() {
$(function() { $(function() {
......
(() => { class VersionCheckImage {
class VersionCheckImage { static bindErrorEvent(imageElement) {
static bindErrorEvent(imageElement) { imageElement.off('error').on('error', () => imageElement.hide());
imageElement.off('error').on('error', () => imageElement.hide());
}
} }
}
window.gl = window.gl || {}; window.gl = window.gl || {};
gl.VersionCheckImage = VersionCheckImage; gl.VersionCheckImage = VersionCheckImage;
})();
module.exports = VersionCheckImage;
...@@ -148,11 +148,16 @@ header { ...@@ -148,11 +148,16 @@ header {
} }
.header-logo { .header-logo {
display: inline-block; position: absolute;
margin: 0 8px 0 3px; left: 50%;
position: relative;
top: 7px; top: 7px;
transition-duration: .3s; transition-duration: .3s;
z-index: 999;
#logo {
position: relative;
left: -50%;
}
svg, svg,
img { img {
...@@ -162,6 +167,15 @@ header { ...@@ -162,6 +167,15 @@ header {
&:hover { &:hover {
cursor: pointer; cursor: pointer;
} }
@media (max-width: $screen-xs-max) {
right: 20px;
left: auto;
#logo {
left: auto;
}
}
} }
.title { .title {
...@@ -169,7 +183,7 @@ header { ...@@ -169,7 +183,7 @@ header {
padding-right: 20px; padding-right: 20px;
margin: 0; margin: 0;
font-size: 18px; font-size: 18px;
max-width: 450px; max-width: 385px;
display: inline-block; display: inline-block;
line-height: $header-height; line-height: $header-height;
font-weight: normal; font-weight: normal;
...@@ -179,6 +193,10 @@ header { ...@@ -179,6 +193,10 @@ header {
vertical-align: top; vertical-align: top;
white-space: nowrap; white-space: nowrap;
@media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
max-width: 300px;
}
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
max-width: 190px; max-width: 190px;
} }
......
...@@ -96,16 +96,6 @@ ul.unstyled-list > li { ...@@ -96,16 +96,6 @@ ul.unstyled-list > li {
border-bottom: none; border-bottom: none;
} }
ul.task-list {
li.task-list-item {
list-style-type: none;
}
ul:not(.task-list) {
padding-left: 1.3em;
}
}
// Generic content list // Generic content list
ul.content-list { ul.content-list {
@include basic-list; @include basic-list;
......
...@@ -76,6 +76,13 @@ ...@@ -76,6 +76,13 @@
#{$property}: $value; #{$property}: $value;
} }
/* http://phrappe.com/css/conditional-css-for-webkit-based-browsers/ */
@mixin on-webkit-only {
@media screen and (-webkit-min-device-pixel-ratio:0) {
@content;
}
}
@mixin keyframes($animation-name) { @mixin keyframes($animation-name) {
@-webkit-keyframes #{$animation-name} { @-webkit-keyframes #{$animation-name} {
@content; @content;
......
@mixin fade($gradient-direction, $gradient-color) { @mixin fade($gradient-direction, $gradient-color) {
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
z-index: 1; z-index: 2;
position: absolute; position: absolute;
bottom: 12px; bottom: 12px;
width: 43px; width: 43px;
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
.fa { .fa {
position: relative; position: relative;
top: 6px; top: 5px;
font-size: 18px; font-size: 18px;
} }
} }
...@@ -79,6 +79,7 @@ ...@@ -79,6 +79,7 @@
} }
&.sub-nav { &.sub-nav {
text-align: center;
background-color: $gray-normal; background-color: $gray-normal;
.container-fluid { .container-fluid {
...@@ -286,6 +287,7 @@ ...@@ -286,6 +287,7 @@
background: $gray-light; background: $gray-light;
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
transition: padding $sidebar-transition-duration; transition: padding $sidebar-transition-duration;
text-align: center;
.container-fluid { .container-fluid {
position: relative; position: relative;
...@@ -351,7 +353,7 @@ ...@@ -351,7 +353,7 @@
right: -5px; right: -5px;
.fa { .fa {
right: -28px; right: -7px;
} }
} }
...@@ -381,7 +383,7 @@ ...@@ -381,7 +383,7 @@
left: 0; left: 0;
.fa { .fa {
left: -4px; left: 10px;
} }
} }
} }
......
...@@ -29,14 +29,16 @@ ...@@ -29,14 +29,16 @@
} }
} }
@media (min-width: $screen-sm-min) {
.content-wrapper {
padding-right: $gutter_collapsed_width;
}
}
.right-sidebar-collapsed { .right-sidebar-collapsed {
padding-right: 0; padding-right: 0;
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
.content-wrapper {
padding-right: $gutter_collapsed_width;
}
.merge-request-tabs-holder.affix { .merge-request-tabs-holder.affix {
right: $gutter_collapsed_width; right: $gutter_collapsed_width;
} }
...@@ -54,12 +56,6 @@ ...@@ -54,12 +56,6 @@
.right-sidebar-expanded { .right-sidebar-expanded {
padding-right: 0; padding-right: 0;
@media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
&:not(.build-sidebar):not(.wiki-sidebar) {
padding-right: $gutter_collapsed_width;
}
}
@media (min-width: $screen-md-min) { @media (min-width: $screen-md-min) {
.content-wrapper { .content-wrapper {
padding-right: $gutter_width; padding-right: $gutter_width;
......
...@@ -134,7 +134,7 @@ ...@@ -134,7 +134,7 @@
ul, ul,
ol { ol {
padding: 0; padding: 0;
margin: 3px 0 3px 28px !important; margin: 3px 0 !important;
} }
ul:dir(rtl), ul:dir(rtl),
...@@ -144,6 +144,29 @@ ...@@ -144,6 +144,29 @@
li { li {
line-height: 1.6em; line-height: 1.6em;
margin-left: 25px;
padding-left: 3px;
/* Normalize the bullet position on webkit. */
@include on-webkit-only {
margin-left: 28px;
padding-left: 0;
}
}
ul.task-list {
li.task-list-item {
list-style-type: none;
position: relative;
padding-left: 28px;
margin-left: 0 !important;
input.task-list-item-checkbox {
position: absolute;
left: 8px;
top: 5px;
}
}
} }
a[href*="/uploads/"], a[href*="/uploads/"],
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
display: table-cell; display: table-cell;
} }
.environments-name,
.environments-commit, .environments-commit,
.environments-actions { .environments-actions {
width: 20%; width: 20%;
...@@ -45,6 +44,7 @@ ...@@ -45,6 +44,7 @@
width: 10%; width: 10%;
} }
.environments-name,
.environments-deploy, .environments-deploy,
.environments-build { .environments-build {
width: 15%; width: 15%;
...@@ -62,6 +62,22 @@ ...@@ -62,6 +62,22 @@
} }
} }
.btn-group {
> a {
color: $gl-text-color-secondary;
}
svg path {
fill: $gl-text-color-secondary;
}
.dropdown {
outline: none;
}
}
.commit-title { .commit-title {
margin: 0; margin: 0;
} }
......
...@@ -10,6 +10,11 @@ ...@@ -10,6 +10,11 @@
.issue-labels { .issue-labels {
display: inline-block; display: inline-block;
} }
.icon-merge-request-unmerged {
height: 13px;
margin-bottom: 3px;
}
} }
} }
......
...@@ -652,23 +652,29 @@ pre.light-well { ...@@ -652,23 +652,29 @@ pre.light-well {
} }
} }
.container-fluid.project-stats-container {
@media (max-width: $screen-xs-max) {
padding: 12px 0;
}
}
.project-last-commit { .project-last-commit {
background-color: $gray-light;
padding: 12px $gl-padding;
border: 1px solid $border-color;
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
margin-top: $gl-padding; margin-top: $gl-padding;
} }
@media (min-width: $screen-sm-min) { &.container-fluid {
border-radius: $border-radius-base; padding-top: 12px;
padding-bottom: 12px;
background-color: $gray-light;
border: 1px solid $border-color;
border-right-width: 0;
border-left-width: 0;
@media (min-width: $screen-sm-min) {
border-right-width: 1px;
border-left-width: 1px;
}
}
&.container-limited {
@media (min-width: 1281px) {
border-radius: $border-radius-base;
}
} }
.ci-status { .ci-status {
......
...@@ -9,24 +9,32 @@ module IssuableCollections ...@@ -9,24 +9,32 @@ module IssuableCollections
private private
def issuable_meta_data(issuable_collection) def issuable_meta_data(issuable_collection, collection_type)
# map has to be used here since using pluck or select will # map has to be used here since using pluck or select will
# throw an error when ordering issuables by priority which inserts # throw an error when ordering issuables by priority which inserts
# a new order into the collection. # a new order into the collection.
# We cannot use reorder to not mess up the paginated collection. # We cannot use reorder to not mess up the paginated collection.
issuable_ids = issuable_collection.map(&:id) issuable_ids = issuable_collection.map(&:id)
issuable_note_count = Note.count_for_collection(issuable_ids, @collection_type) issuable_note_count = Note.count_for_collection(issuable_ids, @collection_type)
issuable_votes_count = AwardEmoji.votes_for_collection(issuable_ids, @collection_type) issuable_votes_count = AwardEmoji.votes_for_collection(issuable_ids, @collection_type)
issuable_merge_requests_count =
if collection_type == 'Issue'
MergeRequestsClosingIssues.count_for_collection(issuable_ids)
else
[]
end
issuable_ids.each_with_object({}) do |id, issuable_meta| issuable_ids.each_with_object({}) do |id, issuable_meta|
downvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.downvote? } downvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.downvote? }
upvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.upvote? } upvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.upvote? }
notes = issuable_note_count.find { |notes| notes.noteable_id == id } notes = issuable_note_count.find { |notes| notes.noteable_id == id }
merge_requests = issuable_merge_requests_count.find { |mr| mr.first == id }
issuable_meta[id] = Issuable::IssuableMeta.new( issuable_meta[id] = Issuable::IssuableMeta.new(
upvotes.try(:count).to_i, upvotes.try(:count).to_i,
downvotes.try(:count).to_i, downvotes.try(:count).to_i,
notes.try(:count).to_i notes.try(:count).to_i,
merge_requests.try(:last).to_i
) )
end end
end end
......
...@@ -10,7 +10,7 @@ module IssuesAction ...@@ -10,7 +10,7 @@ module IssuesAction
.page(params[:page]) .page(params[:page])
@collection_type = "Issue" @collection_type = "Issue"
@issuable_meta_data = issuable_meta_data(@issues) @issuable_meta_data = issuable_meta_data(@issues, @collection_type)
respond_to do |format| respond_to do |format|
format.html format.html
......
...@@ -9,7 +9,7 @@ module MergeRequestsAction ...@@ -9,7 +9,7 @@ module MergeRequestsAction
.page(params[:page]) .page(params[:page])
@collection_type = "MergeRequest" @collection_type = "MergeRequest"
@issuable_meta_data = issuable_meta_data(@merge_requests) @issuable_meta_data = issuable_meta_data(@merge_requests, @collection_type)
end end
private private
......
...@@ -26,7 +26,7 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -26,7 +26,7 @@ class Projects::IssuesController < Projects::ApplicationController
@collection_type = "Issue" @collection_type = "Issue"
@issues = issues_collection @issues = issues_collection
@issues = @issues.page(params[:page]) @issues = @issues.page(params[:page])
@issuable_meta_data = issuable_meta_data(@issues) @issuable_meta_data = issuable_meta_data(@issues, @collection_type)
if @issues.out_of_range? && @issues.total_pages != 0 if @issues.out_of_range? && @issues.total_pages != 0
return redirect_to url_for(params.merge(page: @issues.total_pages)) return redirect_to url_for(params.merge(page: @issues.total_pages))
......
...@@ -39,7 +39,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -39,7 +39,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@collection_type = "MergeRequest" @collection_type = "MergeRequest"
@merge_requests = merge_requests_collection @merge_requests = merge_requests_collection
@merge_requests = @merge_requests.page(params[:page]) @merge_requests = @merge_requests.page(params[:page])
@issuable_meta_data = issuable_meta_data(@merge_requests) @issuable_meta_data = issuable_meta_data(@merge_requests, @collection_type)
if @merge_requests.out_of_range? && @merge_requests.total_pages != 0 if @merge_requests.out_of_range? && @merge_requests.total_pages != 0
return redirect_to url_for(params.merge(page: @merge_requests.total_pages)) return redirect_to url_for(params.merge(page: @merge_requests.total_pages))
......
module EmailsHelper module EmailsHelper
include AppearancesHelper
# Google Actions # Google Actions
# https://developers.google.com/gmail/markup/reference/go-to-action # https://developers.google.com/gmail/markup/reference/go-to-action
def email_action(url) def email_action(url)
...@@ -49,4 +51,19 @@ module EmailsHelper ...@@ -49,4 +51,19 @@ module EmailsHelper
msg = "This link is valid for #{password_reset_token_valid_time}. " msg = "This link is valid for #{password_reset_token_valid_time}. "
msg << "After it expires, you can #{link_tag}." msg << "After it expires, you can #{link_tag}."
end end
def header_logo
if brand_item && brand_item.header_logo?
image_tag(
brand_item.header_logo,
style: 'height: 50px'
)
else
image_tag(
image_url('mailers/gitlab_header_logo.gif'),
size: "55x50",
alt: "GitLab"
)
end
end
end end
...@@ -22,8 +22,8 @@ module Emails ...@@ -22,8 +22,8 @@ module Emails
mail(bcc: recipients, mail(bcc: recipients,
subject: pipeline_subject(status), subject: pipeline_subject(status),
skip_premailer: true) do |format| skip_premailer: true) do |format|
format.html { render layout: false } format.html { render layout: 'mailer' }
format.text format.text { render layout: 'mailer' }
end end
end end
......
...@@ -16,9 +16,9 @@ module Issuable ...@@ -16,9 +16,9 @@ module Issuable
include TimeTrackable include TimeTrackable
# This object is used to gather issuable meta data for displaying # This object is used to gather issuable meta data for displaying
# upvotes, downvotes and notes count for issues and merge requests # upvotes, downvotes, notes and closing merge requests count for issues and merge requests
# lists avoiding n+1 queries and improving performance. # lists avoiding n+1 queries and improving performance.
IssuableMeta = Struct.new(:upvotes, :downvotes, :notes_count) IssuableMeta = Struct.new(:upvotes, :downvotes, :notes_count, :merge_requests_count)
included do included do
cache_markdown_field :title, pipeline: :single_line cache_markdown_field :title, pipeline: :single_line
......
...@@ -4,4 +4,12 @@ class MergeRequestsClosingIssues < ActiveRecord::Base ...@@ -4,4 +4,12 @@ class MergeRequestsClosingIssues < ActiveRecord::Base
validates :merge_request_id, uniqueness: { scope: :issue_id }, presence: true validates :merge_request_id, uniqueness: { scope: :issue_id }, presence: true
validates :issue_id, presence: true validates :issue_id, presence: true
class << self
def count_for_collection(ids)
group(:issue_id).
where(issue_id: ids).
pluck('issue_id', 'COUNT(*) as count')
end
end
end end
...@@ -59,7 +59,8 @@ module Ci ...@@ -59,7 +59,8 @@ module Ci
private private
def skip_ci? def skip_ci?
pipeline.git_commit_message =~ /\[(ci skip|skip ci)\]/i if pipeline.git_commit_message return false unless pipeline.git_commit_message
pipeline.git_commit_message =~ /\[(ci[ _-]skip|skip[ _-]ci)\]/i
end end
def commit def commit
......
...@@ -55,7 +55,7 @@ module Files ...@@ -55,7 +55,7 @@ module Files
file_path = action[:file_path] file_path = action[:file_path]
file_path = action[:previous_path] if action[:action] == :move file_path = action[:previous_path] if action[:action] == :move
blob = repository.blob_at_branch(params[:branch_name], file_path) blob = repository.blob_at_branch(params[:branch], file_path)
unless blob unless blob
raise_error("File to be #{action[:action]}d `#{file_path}` does not exist.") raise_error("File to be #{action[:action]}d `#{file_path}` does not exist.")
...@@ -89,7 +89,7 @@ module Files ...@@ -89,7 +89,7 @@ module Files
def validate_create(action) def validate_create(action)
return if project.empty_repo? return if project.empty_repo?
if repository.blob_at_branch(params[:branch_name], action[:file_path]) if repository.blob_at_branch(params[:branch], action[:file_path])
raise_error("Your changes could not be committed because a file with the name `#{action[:file_path]}` already exists.") raise_error("Your changes could not be committed because a file with the name `#{action[:file_path]}` already exists.")
end end
end end
...@@ -102,14 +102,14 @@ module Files ...@@ -102,14 +102,14 @@ module Files
raise_error("You must supply the original file path when moving file `#{action[:file_path]}`.") raise_error("You must supply the original file path when moving file `#{action[:file_path]}`.")
end end
blob = repository.blob_at_branch(params[:branch_name], action[:file_path]) blob = repository.blob_at_branch(params[:branch], action[:file_path])
if blob if blob
raise_error("Move destination `#{action[:file_path]}` already exists.") raise_error("Move destination `#{action[:file_path]}` already exists.")
end end
if action[:content].nil? if action[:content].nil?
blob = repository.blob_at_branch(params[:branch_name], action[:previous_path]) blob = repository.blob_at_branch(params[:branch], action[:previous_path])
blob.load_all_data!(repository) if blob.truncated? blob.load_all_data!(repository) if blob.truncated?
params[:actions][index][:content] = blob.data params[:actions][index][:content] = blob.data
end end
......
= content_for :sub_nav do
.scrolling-tabs-container.sub-nav-scroll
= render 'shared/nav_scroll'
.nav-links.sub-nav.scrolling-tabs
%ul{ class: container_class }
= nav_link(path: 'groups#show', html_options: { class: 'home' }) do
= link_to group_path(@group), title: 'Group Home' do
%span
Home
= nav_link(path: 'groups#activity') do
= link_to activity_group_path(@group), title: 'Activity' do
%span
Activity
= nav_link(path: 'group_members#index') do
= link_to group_group_members_path(@group), title: 'Members' do
%span
Members
= content_for :sub_nav do
.scrolling-tabs-container.sub-nav-scroll
= render 'shared/nav_scroll'
.nav-links.sub-nav.scrolling-tabs
%ul{ class: container_class }
= nav_link(path: 'groups#issues', html_options: { class: 'home' }) do
= link_to issues_group_path(@group), title: 'List' do
%span
List
= nav_link(path: 'labels#index') do
= link_to group_labels_path(@group), title: 'Labels' do
%span
Labels
= nav_link(path: 'milestones#index') do
= link_to group_milestones_path(@group), title: 'Milestones' do
%span
Milestones
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
- if current_user - if current_user
= auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity")
- page_title "Activity" - page_title "Activity"
= render 'groups/head'
%section.activities %section.activities
= render 'activities' = render 'activities'
- page_title "Members" - page_title "Members"
= render 'groups/head'
.project-members-page.prepend-top-default .project-members-page.prepend-top-default
%h4 %h4
......
- page_title "Issues" - page_title "Issues"
= render "head_issues"
= content_for :meta_tags do = content_for :meta_tags do
- if current_user - if current_user
= auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@group.name} issues") = auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@group.name} issues")
......
- page_title 'Labels' - page_title 'Labels'
= render "groups/head_issues"
.top-area.adjust .top-area.adjust
.nav-text .nav-text
......
- page_title "Milestones" - page_title "Milestones"
= render "groups/head_issues"
.top-area .top-area
= render 'shared/milestones_filter' = render 'shared/milestones_filter'
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
- if current_user - if current_user
= auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity")
= render 'groups/head'
= render 'groups/home_panel' = render 'groups/home_panel'
......
.page-with-sidebar{ class: page_gutter_class } .page-with-sidebar{ class: page_gutter_class }
- if defined?(nav) && nav - if defined?(nav) && nav
.layout-nav .layout-nav
%div{ class: container_class } .container-fluid
= render "layouts/nav/#{nav}" = render "layouts/nav/#{nav}"
.content-wrapper{ class: "#{layout_nav_class}" } .content-wrapper{ class: "#{layout_nav_class}" }
= yield :sub_nav = yield :sub_nav
......
...@@ -61,12 +61,12 @@ ...@@ -61,12 +61,12 @@
%div %div
= link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-success' = link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-success'
%h1.title= title
.header-logo .header-logo
= link_to root_path, class: 'home', title: 'Dashboard', id: 'logo' do = link_to root_path, class: 'home', title: 'Dashboard', id: 'logo' do
= brand_header_logo = brand_header_logo
%h1.title= title
= yield :header_content = yield :header_content
= render 'shared/outdated_browser' = render 'shared/outdated_browser'
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
%html{ lang: "en" }
%head
%meta{ content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/
%meta{ content: "width=device-width, initial-scale=1", name: "viewport" }/
%meta{ content: "IE=edge", "http-equiv" => "X-UA-Compatible" }/
%title= message.subject
:css
/* CLIENT-SPECIFIC STYLES */
body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; }
img { -ms-interpolation-mode: bicubic; }
/* iOS BLUE LINKS */
a[x-apple-data-detectors] {
color: inherit !important;
text-decoration: none !important;
font-size: inherit !important;
font-family: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
}
/* ANDROID MARGIN HACK */
body { margin:0 !important; }
div[style*="margin: 16px 0"] { margin:0 !important; }
@media only screen and (max-width: 639px) {
body, #body {
min-width: 320px !important;
}
table.wrapper {
width: 100% !important;
min-width: 320px !important;
}
table.wrapper > tbody > tr > td {
border-left: 0 !important;
border-right: 0 !important;
border-radius: 0 !important;
padding-left: 10px !important;
padding-right: 10px !important;
}
}
%body{ style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;height:100%;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" }
%table#body{ border: "0", cellpadding: "0", cellspacing: "0", style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;" }
%tbody
%tr.line
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#6b4fbb;height:4px;font-size:4px;line-height:4px;" }  
%tr.header
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" }
= header_logo
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" }
%table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:640px;margin:0 auto;border-collapse:separate;border-spacing:0;" }
%tbody
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#ffffff;text-align:left;padding:18px 25px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" }
%table.content{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;border-collapse:separate;border-spacing:0;" }
%tbody
= yield
%tr.footer
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" }
%img{ alt: "GitLab", height: "33", src: image_url('mailers/gitlab_footer_logo.gif'), style: "display:block;margin:0 auto 1em;", width: "90" }/
%div
%a{ href: profile_notifications_url, style: "color:#3777b0;text-decoration:none;" } Manage all notifications
&middot;
%a{ href: help_url, style: "color:#3777b0;text-decoration:none;" } Help
%div
You're receiving this email because of your account on
= succeed "." do
%a{ href: root_url, style: "color:#3777b0;text-decoration:none;" }= Gitlab.config.gitlab.host
= yield
You're receiving this email because of your account on #{Gitlab.config.gitlab.host}.
Manage all notifications: #{profile_notifications_url}
Help: #{help_url}
...@@ -5,23 +5,11 @@ ...@@ -5,23 +5,11 @@
.fade-right .fade-right
= icon('angle-right') = icon('angle-right')
%ul.nav-links.scrolling-tabs %ul.nav-links.scrolling-tabs
= nav_link(path: 'groups#show', html_options: {class: 'home'}) do = nav_link(path: ['groups#show', 'groups#activity', 'group_members#index'], html_options: { class: 'home' }) do
= link_to group_path(@group), title: 'Home' do = link_to group_path(@group), title: 'Home' do
%span %span
Group Group
= nav_link(path: 'groups#activity') do = nav_link(path: ['groups#issues', 'labels#index', 'milestones#index']) do
= link_to activity_group_path(@group), title: 'Activity' do
%span
Activity
= nav_link(controller: [:group, :labels]) do
= link_to group_labels_path(@group), title: 'Labels' do
%span
Labels
= nav_link(controller: [:group, :milestones]) do
= link_to group_milestones_path(@group), title: 'Milestones' do
%span
Milestones
= nav_link(path: 'groups#issues') do
= link_to issues_group_path(@group), title: 'Issues' do = link_to issues_group_path(@group), title: 'Issues' do
%span %span
Issues Issues
...@@ -33,7 +21,3 @@ ...@@ -33,7 +21,3 @@
Merge Requests Merge Requests
- merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute - merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute
%span.badge.count= number_with_delimiter(merge_requests.count) %span.badge.count= number_with_delimiter(merge_requests.count)
= nav_link(controller: [:group_members]) do
= link_to group_group_members_path(@group), title: 'Members' do
%span
Members
...@@ -27,7 +27,3 @@ Trace: <%= build.trace_with_state(last_lines: 10)[:text] %> ...@@ -27,7 +27,3 @@ Trace: <%= build.trace_with_state(last_lines: 10)[:text] %>
<% end -%> <% end -%>
<% end -%> <% end -%>
You're receiving this email because of your account on <%= Gitlab.config.gitlab.host %>.
Manage all notifications: <%= profile_notifications_url %>
Help: <%= help_url %>
...@@ -18,7 +18,3 @@ Commit Author: <%= commit.author_name %> ...@@ -18,7 +18,3 @@ Commit Author: <%= commit.author_name %>
<% build_count = @pipeline.statuses.latest.size -%> <% build_count = @pipeline.statuses.latest.size -%>
<% stage_count = @pipeline.stages_count -%> <% stage_count = @pipeline.stages_count -%>
Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) successfully completed <%= build_count %> <%= 'build'.pluralize(build_count) %> in <%= stage_count %> <%= 'stage'.pluralize(stage_count) %>. Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) successfully completed <%= build_count %> <%= 'build'.pluralize(build_count) %> in <%= stage_count %> <%= 'stage'.pluralize(stage_count) %>.
You're receiving this email because of your account on <%= Gitlab.config.gitlab.host %>.
Manage all notifications: <%= profile_notifications_url %>
Help: <%= help_url %>
...@@ -25,3 +25,10 @@ ...@@ -25,3 +25,10 @@
HTML HTML
.col-md-10.code.js-syntax-highlight .col-md-10.code.js-syntax-highlight
= highlight('.html', badge.to_html) = highlight('.html', badge.to_html)
.row
%hr
.row
.col-md-2.text-center
AsciiDoc
.col-md-10.code.js-syntax-highlight
= highlight('.adoc', badge.to_asciidoc)
...@@ -13,70 +13,69 @@ ...@@ -13,70 +13,69 @@
= render "home_panel" = render "home_panel"
- if current_user && can?(current_user, :download_code, @project) - if current_user && can?(current_user, :download_code, @project)
.project-stats-container{ class: container_class } %nav.project-stats{ class: container_class }
%nav.project-stats %ul.nav
%ul.nav %li
%li = link_to project_files_path(@project) do
= link_to project_files_path(@project) do Files (#{storage_counter(@project.statistics.total_repository_size)})
Files (#{storage_counter(@project.statistics.total_repository_size)}) %li
%li = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do
= link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do #{'Commit'.pluralize(@project.statistics.commit_count)} (#{number_with_delimiter(@project.statistics.commit_count)})
#{'Commit'.pluralize(@project.statistics.commit_count)} (#{number_with_delimiter(@project.statistics.commit_count)}) %li
%li = link_to namespace_project_branches_path(@project.namespace, @project) do
= link_to namespace_project_branches_path(@project.namespace, @project) do #{'Branch'.pluralize(@repository.branch_count)} (#{number_with_delimiter(@repository.branch_count)})
#{'Branch'.pluralize(@repository.branch_count)} (#{number_with_delimiter(@repository.branch_count)}) %li
%li = link_to namespace_project_tags_path(@project.namespace, @project) do
= link_to namespace_project_tags_path(@project.namespace, @project) do #{'Tag'.pluralize(@repository.tag_count)} (#{number_with_delimiter(@repository.tag_count)})
#{'Tag'.pluralize(@repository.tag_count)} (#{number_with_delimiter(@repository.tag_count)})
- if default_project_view != 'readme' && @repository.readme - if default_project_view != 'readme' && @repository.readme
%li %li
= link_to 'Readme', readme_path(@project) = link_to 'Readme', readme_path(@project)
- if @repository.changelog - if @repository.changelog
%li %li
= link_to 'Changelog', changelog_path(@project) = link_to 'Changelog', changelog_path(@project)
- if @repository.license_blob - if @repository.license_blob
%li %li
= link_to license_short_name(@project), license_path(@project) = link_to license_short_name(@project), license_path(@project)
- if @repository.contribution_guide - if @repository.contribution_guide
%li %li
= link_to 'Contribution guide', contribution_guide_path(@project) = link_to 'Contribution guide', contribution_guide_path(@project)
- if @repository.gitlab_ci_yml - if @repository.gitlab_ci_yml
%li %li
= link_to 'CI configuration', ci_configuration_path(@project) = link_to 'CI configuration', ci_configuration_path(@project)
- if current_user && can_push_branch?(@project, @project.default_branch) - if current_user && can_push_branch?(@project, @project.default_branch)
- unless @repository.changelog - unless @repository.changelog
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: 'CHANGELOG') do = link_to add_special_file_path(@project, file_name: 'CHANGELOG') do
Add Changelog Add Changelog
- unless @repository.license_blob - unless @repository.license_blob
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: 'LICENSE') do = link_to add_special_file_path(@project, file_name: 'LICENSE') do
Add License Add License
- unless @repository.contribution_guide - unless @repository.contribution_guide
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: 'CONTRIBUTING.md', commit_message: 'Add contribution guide') do = link_to add_special_file_path(@project, file_name: 'CONTRIBUTING.md', commit_message: 'Add contribution guide') do
Add Contribution guide Add Contribution guide
- unless @repository.gitlab_ci_yml - unless @repository.gitlab_ci_yml
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do
Set up CI Set up CI
- if koding_enabled? && @repository.koding_yml.blank? - if koding_enabled? && @repository.koding_yml.blank?
%li.missing %li.missing
= link_to 'Set up Koding', add_koding_stack_path(@project) = link_to 'Set up Koding', add_koding_stack_path(@project)
- if @repository.gitlab_ci_yml.blank? && @project.deployment_service.present? - if @repository.gitlab_ci_yml.blank? && @project.deployment_service.present?
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml', commit_message: 'Set up auto deploy', target_branch: 'auto-deploy', context: 'autodeploy') do = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml', commit_message: 'Set up auto deploy', target_branch: 'auto-deploy', context: 'autodeploy') do
Set up auto deploy Set up auto deploy
- if @repository.commit - if @repository.commit
.project-last-commit .project-last-commit{ class: container_class }
= render 'projects/last_commit', commit: @repository.commit, ref: current_ref, project: @project = render 'projects/last_commit', commit: @repository.commit, ref: current_ref, project: @project
%div{ class: container_class } %div{ class: container_class }
- if @project.archived? - if @project.archived?
......
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
= f.text_field :key, class: "form-control", placeholder: "PROJECT_VARIABLE", required: true = f.text_field :key, class: "form-control", placeholder: "PROJECT_VARIABLE", required: true
.form-group .form-group
= f.label :value, "Value", class: "label-light" = f.label :value, "Value", class: "label-light"
= f.text_area :value, class: "form-control", placeholder: "PROJECT_VARIABLE", required: true = f.text_area :value, class: "form-control", placeholder: "PROJECT_VARIABLE"
= f.submit btn_text, class: "btn btn-save" = f.submit btn_text, class: "btn btn-save"
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
- issue_votes = @issuable_meta_data[issuable.id] - issue_votes = @issuable_meta_data[issuable.id]
- upvotes, downvotes = issue_votes.upvotes, issue_votes.downvotes - upvotes, downvotes = issue_votes.upvotes, issue_votes.downvotes
- issuable_url = @collection_type == "Issue" ? issue_path(issuable, anchor: 'notes') : merge_request_path(issuable, anchor: 'notes') - issuable_url = @collection_type == "Issue" ? issue_path(issuable, anchor: 'notes') : merge_request_path(issuable, anchor: 'notes')
- issuable_mr = @issuable_meta_data[issuable.id].merge_requests_count
- if issuable_mr > 0
%li
= image_tag('icon-merge-request-unmerged', class: 'icon-merge-request-unmerged')
= issuable_mr
- if upvotes > 0 - if upvotes > 0
%li %li
......
---
title: Rename Builds to Pipelines, CI/CD Pipelines, or Jobs everywhere
merge_request: 8787
author:
---
title: Don't require lib/gitlab/request_profiler/middleware.rb in config/initializers/request_profiler.rb
merge_request:
author:
---
title: Use reCaptcha when an issue is identified as a spam
merge_request: 8846
author:
---
title: Unify projects search by removing /projects/:search endpoint
merge_request: 8877
author:
---
title: Standardize branch name params as branch on V4 API
merge_request: 8936
author:
---
title: Align task list checkboxes
merge_request: 6487
author: Jared Deckard <jared.deckard@gmail.com>
---
title: Allow creating protected branches when user can merge to such branch
merge_request: 8458
author:
---
title: Adds service trigger events to api
merge_request: 8324
author:
---
title: Create a TODO for user who set auto-merge when a build fails, merge conflict occurs
merge_request: 8056
author: twonegatives
---
title: Don't group issues by project on group-level and dashboard issue indexes.
merge_request: 8111
author: Bernardo Castro
---
title: Fix disable storing of sensitive information when importing a new repo
merge_request: 8885
author: Bernard Pietraga
---
title: Adds back ability to stop all environments
merge_request: 7379
author:
---
title: Force new password after password reset via API
merge_request:
author: George Andrinopoulos
---
title: Fix Ctrl+Click support for Todos and Merge Request page tabs
merge_request: 8898
author:
---
title: Refactor MergeRequests::BuildService
merge_request: 8462
author: Rydkin Maxim
---
title: 'Allows to search within project by commit hash'
merge_request:
author: YarNayar
---
title: Fix nested tasks in ordered list
merge_request: 8626
author:
---
title: Show organisation membership and delete comment on smaller viewports, plus change comment author name to username
merge_request:
author:
---
title: Prevent removal of input fields if it is the parent dropdown element
merge_request: 8397
author:
---
title: Remove flash warning from login page
merge_request: 8864
author: Gerald J. Padilla
---
title: Replace word user with member
merge_request: 8872
author:
---
title: Remove turbolinks.
merge_request: !8570
author:
---
title: Update pipeline and commit links when CI status is updated
merge_request: 8351
author:
---
title: Convert pipeline action icons to svg to have them propperly positioned
merge_request:
author:
---
title: Remove rogue scrollbars for issue comments with inline elements
merge_request:
author:
---
title: Align Segoe UI label text
merge_request:
author:
---
title: Don’t count tasks that are not defined as list items correctly
merge_request: 8526
author:
---
title: Added AsciiDoc Snippet to CI/CD Badges
merge_request: 9164
author: Jan Christophersen
---
title: Add sorting pipeline for a commit
merge_request: 8319
author: Takuya Noguchi
---
title: Color + and - signs in diffs to increase code legibility
merge_request:
author:
---
title: Clean-up Groups navigation order
merge_request: 9309
author:
---
title: Improve button accessibility on pipelines page
merge_request: 8561
author:
---
title: Fix tab index order on branch commits list page
merge_request:
author: Ryan Harris
---
title: Fix Sort by Recent Sign-in in Admin Area
merge_request: 8637
author: Poornima M
---
title: Add hover style to copy icon on commit page header
merge_request:
author: Ryan Harris
---
title: prevent diff unfolding link from appearing when there are no more lines to
show
merge_request: 8761
author:
---
title: Avoid repeated dashes in $CI_ENVIRONMENT_SLUG
merge_request: 8638
author:
---
title: Remove hover animation from row elements
merge_request:
author:
---
title: Add `copy` backup strategy to combat file changed errors
merge_request: 8728
author:
---
title: Fixes hover cursor on pipeline pagenation
merge_request: 9003
author:
---
title: Add link verification to badge partial in order to render a badge without a link
merge_request: 8740
author:
---
title: Fix commit title bar and repository view copy clipboard button order on last commit in repository view
merge_request:
author:
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment