summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorLuke Bennett <lukeeeebennettplus@gmail.com>2018-01-10 21:40:28 +0000
committerLuke Bennett <lukeeeebennettplus@gmail.com>2018-01-10 21:40:28 +0000
commitaf86b8477865adb9196e932708cdeae177ebdc5c (patch)
treea1280286b23432c2c807a24ce042ea4e3e94ca37 /app
parentc34a0a815acb1b43f4a33a5832ac8622e9472222 (diff)
parent4b92efd90cedaa0aff218d11fdce279701128bea (diff)
downloadgitlab-ce-af86b8477865adb9196e932708cdeae177ebdc5c.tar.gz
Merge branch '10-4-stable-missing-commits' into 10-4-stable-prepare-rc3-with-missing-commits
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js6
-rw-r--r--app/assets/javascripts/groups/components/group_item.vue3
-rw-r--r--app/assets/javascripts/groups/store/groups_store.js2
-rw-r--r--app/assets/javascripts/monitoring/components/graph.vue49
-rw-r--r--app/assets/javascripts/monitoring/components/graph/deployment.vue129
-rw-r--r--app/assets/javascripts/monitoring/components/graph/flag.vue205
-rw-r--r--app/assets/javascripts/monitoring/mixins/monitoring_mixins.js5
-rw-r--r--app/assets/javascripts/monitoring/utils/date_time_formatters.js2
-rw-r--r--app/assets/javascripts/users_select.js2
-rw-r--r--app/assets/stylesheets/framework/markdown_area.scss12
-rw-r--r--app/assets/stylesheets/pages/environments.scss67
-rw-r--r--app/controllers/projects/application_controller.rb4
-rw-r--r--app/controllers/projects/boards_controller.rb1
-rw-r--r--app/controllers/projects/issues_controller.rb4
-rw-r--r--app/helpers/selects_helper.rb1
-rw-r--r--app/models/commit.rb2
-rw-r--r--app/policies/project_policy.rb1
-rw-r--r--app/serializers/group_child_entity.rb9
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml12
19 files changed, 297 insertions, 219 deletions
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js
index d918d80df8d..df20e1e9c88 100644
--- a/app/assets/javascripts/gfm_auto_complete.js
+++ b/app/assets/javascripts/gfm_auto_complete.js
@@ -57,12 +57,12 @@ class GfmAutoComplete {
displayTpl(value) {
if (GfmAutoComplete.isLoading(value)) return GfmAutoComplete.Loading.template;
// eslint-disable-next-line no-template-curly-in-string
- let tpl = '<li>/${name}';
+ let tpl = '<li><span class="name">/${name}</span>';
if (value.aliases.length > 0) {
- tpl += ' <small>(or /<%- aliases.join(", /") %>)</small>';
+ tpl += ' <small class="aliases">(or /<%- aliases.join(", /") %>)</small>';
}
if (value.params.length > 0) {
- tpl += ' <small><%- params.join(" ") %></small>';
+ tpl += ' <small class="params"><%- params.join(" ") %></small>';
}
if (value.description !== '') {
tpl += '<small class="description"><i><%- description %></i></small>';
diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue
index 02129d39846..42e79a9e17a 100644
--- a/app/assets/javascripts/groups/components/group_item.vue
+++ b/app/assets/javascripts/groups/components/group_item.vue
@@ -141,7 +141,8 @@ export default {
<div
v-if="group.description"
class="description">
- {{group.description}}
+ <span v-html="group.description">
+ </span>
</div>
</div>
<group-folder
diff --git a/app/assets/javascripts/groups/store/groups_store.js b/app/assets/javascripts/groups/store/groups_store.js
index ffc86175548..4a7569078a1 100644
--- a/app/assets/javascripts/groups/store/groups_store.js
+++ b/app/assets/javascripts/groups/store/groups_store.js
@@ -71,7 +71,7 @@ export default class GroupsStore {
id: rawGroupItem.id,
name: rawGroupItem.name,
fullName: rawGroupItem.full_name,
- description: rawGroupItem.description,
+ description: rawGroupItem.markdown_description,
visibility: rawGroupItem.visibility,
avatarUrl: rawGroupItem.avatar_url,
relativePath: rawGroupItem.relative_path,
diff --git a/app/assets/javascripts/monitoring/components/graph.vue b/app/assets/javascripts/monitoring/components/graph.vue
index eede04a06cd..a50b80c23d0 100644
--- a/app/assets/javascripts/monitoring/components/graph.vue
+++ b/app/assets/javascripts/monitoring/components/graph.vue
@@ -69,8 +69,8 @@
currentFlagPosition: 0,
showFlag: false,
showFlagContent: false,
- showDeployInfo: true,
timeSeries: [],
+ realPixelRatio: 1,
};
},
@@ -87,10 +87,7 @@
},
innerViewBox() {
- if ((this.baseGraphWidth - 150) > 0) {
- return `0 0 ${this.baseGraphWidth - 150} ${this.baseGraphHeight}`;
- }
- return '0 0 0 0';
+ return `0 0 ${this.baseGraphWidth - 150} ${this.baseGraphHeight}`;
},
axisTransform() {
@@ -102,6 +99,10 @@
paddingBottom: `${(Math.ceil(this.baseGraphHeight * 100) / this.baseGraphWidth) || 0}%`,
};
},
+
+ deploymentFlagData() {
+ return this.reducedDeploymentData.find(deployment => deployment.showDeploymentFlag);
+ },
},
methods: {
@@ -122,6 +123,10 @@
this.graphHeight = this.graphHeight - this.margin.top - this.margin.bottom;
this.baseGraphHeight = this.graphHeight;
this.baseGraphWidth = this.graphWidth;
+
+ // pixel offsets inside the svg and outside are not 1:1
+ this.realPixelRatio = (this.$refs.baseSvg.clientWidth / this.baseGraphWidth);
+
this.renderAxesPaths();
this.formatDeployments();
},
@@ -261,6 +266,11 @@
:line-color="path.lineColor"
:area-color="path.areaColor"
/>
+ <graph-deployment
+ :deployment-data="reducedDeploymentData"
+ :graph-height="graphHeight"
+ :graph-height-offset="graphHeightOffset"
+ />
<rect
class="prometheus-graph-overlay"
:width="(graphWidth - 70)"
@@ -269,24 +279,21 @@
ref="graphOverlay"
@mousemove="handleMouseOverGraph($event)">
</rect>
- <graph-deployment
- :show-deploy-info="showDeployInfo"
- :deployment-data="reducedDeploymentData"
- :graph-width="graphWidth"
- :graph-height="graphHeight"
- :graph-height-offset="graphHeightOffset"
- />
- <graph-flag
- v-if="showFlag"
- :current-x-coordinate="currentXCoordinate"
- :current-data="currentData"
- :current-flag-position="currentFlagPosition"
- :graph-height="graphHeight"
- :graph-height-offset="graphHeightOffset"
- :show-flag-content="showFlagContent"
- />
</svg>
</svg>
+ <graph-flag
+ :real-pixel-ratio="realPixelRatio"
+ :current-x-coordinate="currentXCoordinate"
+ :current-data="currentData"
+ :graph-height="graphHeight"
+ :graph-height-offset="graphHeightOffset"
+ :show-flag-content="showFlagContent"
+ :time-series="timeSeries"
+ :unit-of-display="unitOfDisplay"
+ :current-data-index="currentDataIndex"
+ :legend-title="legendTitle"
+ :deployment-flag-data="deploymentFlagData"
+ />
</div>
</div>
</template>
diff --git a/app/assets/javascripts/monitoring/components/graph/deployment.vue b/app/assets/javascripts/monitoring/components/graph/deployment.vue
index 026e2fd0c49..8d6393d4ce5 100644
--- a/app/assets/javascripts/monitoring/components/graph/deployment.vue
+++ b/app/assets/javascripts/monitoring/components/graph/deployment.vue
@@ -1,13 +1,6 @@
<script>
- import { dateFormatWithName, timeFormat } from '../../utils/date_time_formatters';
- import Icon from '../../../vue_shared/components/icon.vue';
-
export default {
props: {
- showDeployInfo: {
- type: Boolean,
- required: true,
- },
deploymentData: {
type: Array,
required: true,
@@ -20,14 +13,6 @@
type: Number,
required: true,
},
- graphWidth: {
- type: Number,
- required: true,
- },
- },
-
- components: {
- Icon,
},
computed: {
@@ -37,52 +22,17 @@
},
methods: {
- refText(d) {
- return d.tag ? d.ref : d.sha.slice(0, 8);
- },
-
- formatTime(deploymentTime) {
- return timeFormat(deploymentTime);
- },
-
- formatDate(deploymentTime) {
- return dateFormatWithName(deploymentTime);
- },
-
- nameDeploymentClass(deployment) {
- return `deploy-info-${deployment.id}`;
- },
-
transformDeploymentGroup(deployment) {
- return `translate(${Math.floor(deployment.xPos) + 1}, 20)`;
- },
-
- positionFlag(deployment) {
- let xPosition = 3;
- if (deployment.xPos > (this.graphWidth - 225)) {
- xPosition = -142;
- }
- return xPosition;
- },
-
- svgContainerHeight(tag) {
- let svgHeight = 80;
- if (!tag) {
- svgHeight -= 20;
- }
- return svgHeight;
+ return `translate(${Math.floor(deployment.xPos) - 5}, 20)`;
},
},
};
</script>
<template>
- <g
- class="deploy-info"
- v-if="showDeployInfo">
+ <g class="deploy-info">
<g
v-for="(deployment, index) in deploymentData"
:key="index"
- :class="nameDeploymentClass(deployment)"
:transform="transformDeploymentGroup(deployment)">
<rect
x="0"
@@ -99,81 +49,6 @@
:y2="calculatedHeight"
stroke="#000">
</line>
- <svg
- v-if="deployment.showDeploymentFlag"
- class="js-deploy-info-box"
- :x="positionFlag(deployment)"
- y="0"
- width="134"
- :height="svgContainerHeight(deployment.tag)">
- <rect
- class="rect-text-metric deploy-info-rect rect-metric"
- x="1"
- y="1"
- rx="2"
- width="132"
- :height="svgContainerHeight(deployment.tag) - 2">
- </rect>
- <text
- class="deploy-info-text text-metric-bold"
- transform="translate(5, 2)">
- Deployed
- </text>
- <!--The date info-->
- <g transform="translate(5, 20)">
- <text class="deploy-info-text">
- {{formatDate(deployment.time)}}
- </text>
- <text
- class="deploy-info-text text-metric-bold"
- x="62">
- {{formatTime(deployment.time)}}
- </text>
- </g>
- <line
- class="divider-line"
- x1="0"
- y1="38"
- x2="132"
- :y2="38"
- stroke="#000">
- </line>
- <!--Commit information-->
- <g transform="translate(5, 40)">
- <icon
- name="commit"
- :width="12"
- :height="12"
- :y="3">
- </icon>
- <a :xlink:href="deployment.commitUrl">
- <text
- class="deploy-info-text deploy-info-text-link"
- transform="translate(20, 2)">
- {{refText(deployment)}}
- </text>
- </a>
- </g>
- <!--Tag information-->
- <g
- transform="translate(5, 55)"
- v-if="deployment.tag">
- <icon
- name="label"
- :width="12"
- :height="12"
- :y="5">
- </icon>
- <a :xlink:href="deployment.tagUrl">
- <text
- class="deploy-info-text deploy-info-text-link"
- transform="translate(20, 2)"
- y="2">
- {{deployment.tag}}
- </text>
- </a>
- </g>
- </svg>
</g>
<svg
height="0"
diff --git a/app/assets/javascripts/monitoring/components/graph/flag.vue b/app/assets/javascripts/monitoring/components/graph/flag.vue
index 10fb7ff6803..62ebc3f419c 100644
--- a/app/assets/javascripts/monitoring/components/graph/flag.vue
+++ b/app/assets/javascripts/monitoring/components/graph/flag.vue
@@ -1,5 +1,7 @@
<script>
import { dateFormat, timeFormat } from '../../utils/date_time_formatters';
+ import { formatRelevantDigits } from '../../../lib/utils/number_utils';
+ import Icon from '../../../vue_shared/components/icon.vue';
export default {
props: {
@@ -7,14 +9,15 @@
type: Number,
required: true,
},
- currentFlagPosition: {
- type: Number,
- required: true,
- },
currentData: {
type: Object,
required: true,
},
+ deploymentFlagData: {
+ type: Object,
+ required: false,
+ default: null,
+ },
graphHeight: {
type: Number,
required: true,
@@ -23,71 +26,173 @@
type: Number,
required: true,
},
+ realPixelRatio: {
+ type: Number,
+ required: true,
+ },
showFlagContent: {
type: Boolean,
required: true,
},
+ timeSeries: {
+ type: Array,
+ required: true,
+ },
+ unitOfDisplay: {
+ type: String,
+ required: true,
+ },
+ currentDataIndex: {
+ type: Number,
+ required: true,
+ },
+ legendTitle: {
+ type: String,
+ required: true,
+ },
},
- data() {
- return {
- circleColorRgb: '#8fbce8',
- };
+ components: {
+ Icon,
},
computed: {
formatTime() {
- return timeFormat(this.currentData.time);
+ return this.deploymentFlagData ?
+ timeFormat(this.deploymentFlagData.time) :
+ timeFormat(this.currentData.time);
},
formatDate() {
- return dateFormat(this.currentData.time);
+ return this.deploymentFlagData ?
+ dateFormat(this.deploymentFlagData.time) :
+ dateFormat(this.currentData.time);
+ },
+
+ cursorStyle() {
+ const xCoordinate = this.deploymentFlagData ?
+ this.deploymentFlagData.xPos :
+ this.currentXCoordinate;
+
+ const offsetTop = 20 * this.realPixelRatio;
+ const offsetLeft = (70 + xCoordinate) * this.realPixelRatio;
+ const height = (this.graphHeight - this.graphHeightOffset) * this.realPixelRatio;
+
+ return {
+ top: `${offsetTop}px`,
+ left: `${offsetLeft}px`,
+ height: `${height}px`,
+ };
+ },
+
+ flagOrientation() {
+ if (this.currentXCoordinate * this.realPixelRatio > 120) {
+ return 'left';
+ }
+ return 'right';
+ },
+ },
+
+ methods: {
+ seriesMetricValue(series) {
+ const index = this.deploymentFlagData ?
+ this.deploymentFlagData.seriesIndex :
+ this.currentDataIndex;
+ const value = series.values[index] &&
+ series.values[index].value;
+ if (isNaN(value)) {
+ return '-';
+ }
+ return `${formatRelevantDigits(value)}${this.unitOfDisplay}`;
},
- calculatedHeight() {
- return this.graphHeight - this.graphHeightOffset;
+ seriesMetricLabel(index, series) {
+ if (this.timeSeries.length < 2) {
+ return this.legendTitle;
+ }
+ if (series.metricTag) {
+ return series.metricTag;
+ }
+ return `series ${index + 1}`;
+ },
+
+ strokeDashArray(type) {
+ if (type === 'dashed') return '6, 3';
+ if (type === 'dotted') return '3, 3';
+ return null;
},
},
};
</script>
+
<template>
- <g class="mouse-over-flag">
- <line
- class="selected-metric-line"
- :x1="currentXCoordinate"
- :y1="0"
- :x2="currentXCoordinate"
- :y2="calculatedHeight"
- transform="translate(-5, 20)">
- </line>
- <svg
+ <div
+ class="prometheus-graph-cursor"
+ :style="cursorStyle"
+ >
+ <div
v-if="showFlagContent"
- class="rect-text-metric"
- :x="currentFlagPosition"
- y="0">
- <rect
- class="rect-metric"
- x="4"
- y="1"
- rx="2"
- width="90"
- height="40"
- transform="translate(-3, 20)">
- </rect>
- <text
- class="text-metric text-metric-bold"
- x="16"
- y="35"
- transform="translate(-5, 20)">
- {{formatTime}}
- </text>
- <text
- class="text-metric"
- x="16"
- y="15"
- transform="translate(-5, 20)">
- {{formatDate}}
- </text>
- </svg>
- </g>
+ class="prometheus-graph-flag popover"
+ :class="flagOrientation"
+ >
+ <div class="arrow"></div>
+ <div class="popover-title">
+ <h5 v-if="this.deploymentFlagData">
+ Deployed
+ </h5>
+ {{formatDate}} at
+ <strong>{{formatTime}}</strong>
+ </div>
+ <div
+ v-if="this.deploymentFlagData"
+ class="popover-content deploy-meta-content"
+ >
+ <div>
+ <icon
+ name="commit"
+ :size="12">
+ </icon>
+ <a :href="deploymentFlagData.commitUrl">
+ {{deploymentFlagData.sha.slice(0, 8)}}
+ </a>
+ </div>
+ <div
+ v-if="deploymentFlagData.tag">
+ <icon
+ name="label"
+ :size="12">
+ </icon>
+ <a :href="deploymentFlagData.tagUrl">
+ {{deploymentFlagData.ref}}
+ </a>
+ </div>
+ </div>
+ <div class="popover-content">
+ <table>
+ <tr
+ v-for="(series, index) in timeSeries"
+ :key="index"
+ >
+ <td>
+ <svg width="15" height="6">
+ <line
+ :stroke="series.lineColor"
+ :stroke-dasharray="strokeDashArray(series.lineStyle)"
+ stroke-width="4"
+ x1="0"
+ x2="15"
+ y1="2"
+ y2="2">
+ </line>
+ </svg>
+ </td>
+ <td>{{seriesMetricLabel(index, series)}}</td>
+ <td>
+ <strong>{{seriesMetricValue(series)}}</strong>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </div>
</template>
diff --git a/app/assets/javascripts/monitoring/mixins/monitoring_mixins.js b/app/assets/javascripts/monitoring/mixins/monitoring_mixins.js
index cbca14ede02..6cc67ba57ee 100644
--- a/app/assets/javascripts/monitoring/mixins/monitoring_mixins.js
+++ b/app/assets/javascripts/monitoring/mixins/monitoring_mixins.js
@@ -29,15 +29,18 @@ const mixins = {
time.setSeconds(this.timeSeries[0].values[0].time.getSeconds());
if (xPos >= 0) {
+ const seriesIndex = bisectDate(this.timeSeries[0].values, time, 1);
+
deploymentDataArray.push({
id: deployment.id,
time,
sha: deployment.sha,
commitUrl: `${this.projectPath}/commit/${deployment.sha}`,
tag: deployment.tag,
- tagUrl: `${this.tagsPath}/${deployment.tag}`,
+ tagUrl: deployment.tag ? `${this.tagsPath}/${deployment.ref.name}` : null,
ref: deployment.ref.name,
xPos,
+ seriesIndex,
showDeploymentFlag: false,
});
}
diff --git a/app/assets/javascripts/monitoring/utils/date_time_formatters.js b/app/assets/javascripts/monitoring/utils/date_time_formatters.js
index 068813ddee6..f3c9acdd93e 100644
--- a/app/assets/javascripts/monitoring/utils/date_time_formatters.js
+++ b/app/assets/javascripts/monitoring/utils/date_time_formatters.js
@@ -14,7 +14,7 @@ const d3 = {
timeYear,
};
-export const dateFormat = d3.time('%b %-d, %Y');
+export const dateFormat = d3.time('%a, %b %-d');
export const timeFormat = d3.time('%-I:%M%p');
export const dateFormatWithName = d3.time('%a, %b %-d');
export const bisectDate = d3.bisector(d => d.time).left;
diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js
index 759cc9925f4..f249bd036d6 100644
--- a/app/assets/javascripts/users_select.js
+++ b/app/assets/javascripts/users_select.js
@@ -541,7 +541,6 @@ function UsersSelect(currentUser, els, options = {}) {
options.projectId = $(select).data('project-id');
options.groupId = $(select).data('group-id');
options.showCurrentUser = $(select).data('current-user');
- options.pushCodeToProtectedBranches = $(select).data('push-code-to-protected-branches');
options.authorId = $(select).data('author-id');
options.skipUsers = $(select).data('skip-users');
showNullUser = $(select).data('null-user');
@@ -688,7 +687,6 @@ UsersSelect.prototype.users = function(query, options, callback) {
todo_filter: options.todoFilter || null,
todo_state_filter: options.todoStateFilter || null,
current_user: options.showCurrentUser || null,
- push_code_to_protected_branches: options.pushCodeToProtectedBranches || null,
author_id: options.authorId || null,
skip_users: options.skipUsers || null
},
diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss
index 6b07ffdbd61..938f5f49c09 100644
--- a/app/assets/stylesheets/framework/markdown_area.scss
+++ b/app/assets/stylesheets/framework/markdown_area.scss
@@ -192,6 +192,17 @@
overflow-y: auto;
overflow-x: hidden;
+ .name,
+ small.aliases,
+ small.params {
+ float: left;
+ }
+
+ small.aliases,
+ small.params {
+ padding: 2px 5px;
+ }
+
small.description {
float: right;
padding: 3px 5px;
@@ -209,6 +220,7 @@
}
ul > li {
+ @include clearfix;
white-space: nowrap;
}
diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss
index f4882305c57..794bc668562 100644
--- a/app/assets/stylesheets/pages/environments.scss
+++ b/app/assets/stylesheets/pages/environments.scss
@@ -248,6 +248,73 @@
}
}
+.prometheus-graph-cursor {
+ position: absolute;
+ background: $theme-gray-600;
+ width: 1px;
+}
+
+.prometheus-graph-flag {
+ display: block;
+ min-width: 160px;
+
+ h5 {
+ padding: 0;
+ margin: 0;
+ font-size: 14px;
+ line-height: 1.2;
+ }
+
+ table {
+ border-collapse: collapse;
+ padding: 0;
+ margin: 0;
+ }
+
+ td {
+ vertical-align: middle;
+
+ + td {
+ padding-left: 5px;
+ vertical-align: top;
+ }
+ }
+
+ .deploy-meta-content {
+ border-bottom: 1px solid $white-dark;
+
+ svg {
+ height: 15px;
+ vertical-align: bottom;
+ }
+ }
+
+ &.popover {
+ &.left {
+ left: auto;
+ right: 0;
+ margin-right: 10px;
+ }
+
+ &.right {
+ left: 0;
+ right: auto;
+ margin-left: 10px;
+ }
+
+ > .arrow {
+ top: 40px;
+ }
+
+ > .popover-title,
+ > .popover-content {
+ padding: 5px 8px;
+ font-size: 12px;
+ white-space: nowrap;
+ }
+ }
+}
+
.prometheus-svg-container {
position: relative;
height: 0;
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index 9e79852e378..6025a40348b 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -86,4 +86,8 @@ class Projects::ApplicationController < ApplicationController
def require_pages_enabled!
not_found unless @project.pages_available?
end
+
+ def check_issues_available!
+ return render_404 unless @project.feature_available?(:issues, current_user)
+ end
end
diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb
index e36105ddc11..949e54ff819 100644
--- a/app/controllers/projects/boards_controller.rb
+++ b/app/controllers/projects/boards_controller.rb
@@ -2,6 +2,7 @@ class Projects::BoardsController < Projects::ApplicationController
include BoardsResponses
include IssuableCollections
+ before_action :check_issues_available!
before_action :authorize_read_board!, only: [:index, :show]
before_action :assign_endpoint_vars
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index d7a3441a245..384f18b316c 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -194,10 +194,6 @@ class Projects::IssuesController < Projects::ApplicationController
render_404 unless can?(current_user, :push_code, @project) && @issue.can_be_worked_on?(current_user)
end
- def check_issues_available!
- return render_404 unless @project.feature_available?(:issues, current_user)
- end
-
def render_issue_json
if @issue.valid?
render json: serializer.represent(@issue)
diff --git a/app/helpers/selects_helper.rb b/app/helpers/selects_helper.rb
index 1a4f1431bdc..6cefcde558a 100644
--- a/app/helpers/selects_helper.rb
+++ b/app/helpers/selects_helper.rb
@@ -73,7 +73,6 @@ module SelectsHelper
email_user: opts[:email_user] || false,
first_user: opts[:first_user] && current_user ? current_user.username : false,
current_user: opts[:current_user] || false,
- "push-code-to-protected-branches" => opts[:push_code_to_protected_branches],
author_id: opts[:author_id] || '',
skip_users: opts[:skip_users] ? opts[:skip_users].map(&:id) : nil
}
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 2be07ca7d3c..39d7f5b159d 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -371,7 +371,7 @@ class Commit
#
# Returns a symbol
def uri_type(path)
- entry = @raw.tree.path(path)
+ entry = @raw.rugged_tree_entry(path)
if entry[:type] == :blob
blob = ::Blob.decorate(Gitlab::Git::Blob.new(name: entry[:name]), @project)
blob.image? || blob.video? ? :raw : :blob
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index f599eab42f2..1dd8f0a25a9 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -241,7 +241,6 @@ class ProjectPolicy < BasePolicy
rule { repository_disabled }.policy do
prevent :push_code
- prevent :push_code_to_protected_branches
prevent :download_code
prevent :fork_project
prevent :read_commit_status
diff --git a/app/serializers/group_child_entity.rb b/app/serializers/group_child_entity.rb
index 37240bfb0b1..aca4e4ca488 100644
--- a/app/serializers/group_child_entity.rb
+++ b/app/serializers/group_child_entity.rb
@@ -1,6 +1,7 @@
class GroupChildEntity < Grape::Entity
include ActionView::Helpers::NumberHelper
include RequestAwareEntity
+ include MarkupHelper
expose :id, :name, :description, :visibility, :full_name,
:created_at, :updated_at, :avatar_url
@@ -59,6 +60,10 @@ class GroupChildEntity < Grape::Entity
number_with_delimiter(instance.member_count)
end
+ expose :markdown_description do |instance|
+ markdown_description
+ end
+
private
def membership
@@ -74,4 +79,8 @@ class GroupChildEntity < Grape::Entity
def type
object.class.name.downcase
end
+
+ def markdown_description
+ markdown_field(object, :description)
+ end
end
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index be39f577ba7..1fa3a3041fd 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -299,9 +299,10 @@
Charts
-# Shortcut to Issues > New Issue
- %li.hidden
- = link_to new_project_issue_path(@project), class: 'shortcuts-new-issue' do
- Create a new issue
+ - if project_nav_tab?(:issues)
+ %li.hidden
+ = link_to new_project_issue_path(@project), class: 'shortcuts-new-issue' do
+ Create a new issue
-# Shortcut to Pipelines > Jobs
- if project_nav_tab? :builds
@@ -316,5 +317,6 @@
Commits
-# Shortcut to issue boards
- %li.hidden
- = link_to 'Issue Boards', project_boards_path(@project), title: 'Issue Boards', class: 'shortcuts-issue-boards'
+ - if project_nav_tab?(:issues)
+ %li.hidden
+ = link_to 'Issue Boards', project_boards_path(@project), title: 'Issue Boards', class: 'shortcuts-issue-boards'