Commit a6997e33 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'master' into dashboard-titles

parents e4b30f9d dadf6daa
...@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date. ...@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date.
v 8.0.0 (unreleased) v 8.0.0 (unreleased)
- Fix URL construction for merge requests, issues, notes, and commits for relative URL config (Stan Hu) - Fix URL construction for merge requests, issues, notes, and commits for relative URL config (Stan Hu)
- Fix emoji URLs in Markdown when relative_url_root is used (Stan Hu)
- Omit filename in Content-Disposition header in raw file download to avoid RFC 6266 encoding issues (Stan HU) - Omit filename in Content-Disposition header in raw file download to avoid RFC 6266 encoding issues (Stan HU)
- Fix broken Wiki Page History (Stan Hu) - Fix broken Wiki Page History (Stan Hu)
- Prevent anchors from being hidden by header (Stan Hu) - Prevent anchors from being hidden by header (Stan Hu)
...@@ -40,13 +41,19 @@ v 8.0.0 (unreleased) ...@@ -40,13 +41,19 @@ v 8.0.0 (unreleased)
- Add ability to get user information by ID of an SSH key via the API - Add ability to get user information by ID of an SSH key via the API
- Fix bug which IE cannot show image at markdown when the image is raw file of gitlab - Fix bug which IE cannot show image at markdown when the image is raw file of gitlab
- Add support for Crowd - Add support for Crowd
- Global Labels that are available to all projects
- Fix highlighting of deleted lines in diffs.
v 7.14.1 v 7.14.1
- Improve abuse reports management from admin area - Improve abuse reports management from admin area
- Fix "Reload with full diff" URL button in compare branch view (Stan Hu) - Fix "Reload with full diff" URL button in compare branch view (Stan Hu)
- Disabled DNS lookups for SSH in docker image (Rowan Wookey)
v 7.14.1 (unreleased)
- Only include base URL in OmniAuth full_host parameter (Stan Hu) - Only include base URL in OmniAuth full_host parameter (Stan Hu)
- Fix Error 500 in API when accessing a group that has an avatar (Stan Hu) - Fix Error 500 in API when accessing a group that has an avatar (Stan Hu)
- Ability to enable SSL verification for Webhooks - Ability to enable SSL verification for Webhooks
- Add FogBugz project import (Jared Szechy)
v 7.14.0 v 7.14.0
- Fix bug where non-project members of the target project could set labels on new merge requests. - Fix bug where non-project members of the target project could set labels on new merge requests.
......
...@@ -157,6 +157,9 @@ gem "slack-notifier", "~> 1.0.0" ...@@ -157,6 +157,9 @@ gem "slack-notifier", "~> 1.0.0"
# Asana integration # Asana integration
gem 'asana', '~> 0.0.6' gem 'asana', '~> 0.0.6'
# FogBugz integration
gem 'ruby-fogbugz'
# d3 # d3
gem 'd3_rails', '~> 3.5.5' gem 'd3_rails', '~> 3.5.5'
...@@ -259,6 +262,7 @@ group :test do ...@@ -259,6 +262,7 @@ group :test do
gem 'email_spec', '~> 1.6.0' gem 'email_spec', '~> 1.6.0'
gem 'webmock', '~> 1.21.0' gem 'webmock', '~> 1.21.0'
gem 'test_after_commit' gem 'test_after_commit'
gem 'sham_rack'
end end
group :production do group :production do
......
...@@ -575,6 +575,8 @@ GEM ...@@ -575,6 +575,8 @@ GEM
powerpack (~> 0.0.6) powerpack (~> 0.0.6)
rainbow (>= 1.99.1, < 3.0) rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.4) ruby-progressbar (~> 1.4)
ruby-fogbugz (0.1.1)
crack
ruby-progressbar (1.7.1) ruby-progressbar (1.7.1)
ruby-saml (1.0.0) ruby-saml (1.0.0)
nokogiri (>= 1.5.10) nokogiri (>= 1.5.10)
...@@ -609,6 +611,8 @@ GEM ...@@ -609,6 +611,8 @@ GEM
thor (~> 0.14) thor (~> 0.14)
settingslogic (2.0.9) settingslogic (2.0.9)
sexp_processor (4.4.5) sexp_processor (4.4.5)
sham_rack (1.3.6)
rack
shoulda-matchers (2.8.0) shoulda-matchers (2.8.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
sidekiq (3.3.0) sidekiq (3.3.0)
...@@ -845,12 +849,14 @@ DEPENDENCIES ...@@ -845,12 +849,14 @@ DEPENDENCIES
rqrcode-rails3 rqrcode-rails3
rspec-rails (~> 3.3.0) rspec-rails (~> 3.3.0)
rubocop (= 0.28.0) rubocop (= 0.28.0)
ruby-fogbugz
sanitize (~> 2.0) sanitize (~> 2.0)
sass-rails (~> 4.0.5) sass-rails (~> 4.0.5)
sdoc sdoc
seed-fu seed-fu
select2-rails (~> 3.5.9) select2-rails (~> 3.5.9)
settingslogic settingslogic
sham_rack
shoulda-matchers (~> 2.8.0) shoulda-matchers (~> 2.8.0)
sidekiq (~> 3.3) sidekiq (~> 3.3)
sidetiq (= 0.6.3) sidetiq (= 0.6.3)
......
...@@ -85,14 +85,14 @@ ...@@ -85,14 +85,14 @@
// Labels // Labels
.label { .label {
padding: 2px 4px; padding: 2px 4px;
font-size: 12px; font-size: 13px;
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
display: inline-block; display: inline-block;
&.label-gray { &.label-gray {
background-color: #eee; background-color: #f8fafc;
color: #999; color: $gl-gray;
text-shadow: none; text-shadow: none;
} }
...@@ -156,10 +156,16 @@ ...@@ -156,10 +156,16 @@
* Add some extra stuff to panels * Add some extra stuff to panels
* *
*/ */
.container-blank .panel .panel-heading {
font-size: 17px;
line-height: 38px;
}
.panel { .panel {
.panel-heading { box-shadow: none;
font-weight: bold;
.panel-heading {
.panel-head-actions { .panel-head-actions {
position: relative; position: relative;
top: -5px; top: -5px;
...@@ -182,6 +188,10 @@ ...@@ -182,6 +188,10 @@
.pagination { .pagination {
margin: 0; margin: 0;
} }
.btn {
min-width: 124px;
}
} }
&.panel-small { &.panel-small {
...@@ -209,6 +219,12 @@ ...@@ -209,6 +219,12 @@
} }
} }
.alert-help {
background-color: $background-color;
border: 1px solid $border-color;
color: $gl-gray;
}
// Typography ================================================================= // Typography =================================================================
.text-primary, .text-primary,
......
...@@ -22,6 +22,10 @@ $brand-info: $gl-info; ...@@ -22,6 +22,10 @@ $brand-info: $gl-info;
$brand-warning: $gl-warning; $brand-warning: $gl-warning;
$brand-danger: $gl-danger; $brand-danger: $gl-danger;
$border-radius-base: 3px !default;
$border-radius-large: 5px !default;
$border-radius-small: 2px !default;
//== Scaffolding //== Scaffolding
// //
...@@ -110,11 +114,12 @@ $alert-border-radius: 0; ...@@ -110,11 +114,12 @@ $alert-border-radius: 0;
// //
//## //##
$panel-border-radius: 0; $panel-border-radius: 2px;
$panel-default-text: $text-color; $panel-default-text: $text-color;
$panel-default-border: #E7E9ED; $panel-default-border: $border-color;
$panel-default-heading-bg: #F8FAFC; $panel-default-heading-bg: $background-color;
$panel-footer-bg: $background-color;
$panel-inner-border: $border-color;
//== Wells //== Wells
// //
...@@ -144,3 +149,10 @@ $btn-default-border: #e7e9ed; ...@@ -144,3 +149,10 @@ $btn-default-border: #e7e9ed;
// //
//## //##
$nav-link-padding: 13px $gl-padding; $nav-link-padding: 13px $gl-padding;
//== Code
//
//##
$pre-bg: #f8fafc !default;
$pre-color: $gl-gray !default;
$pre-border-color: #e7e9ed;
...@@ -177,7 +177,7 @@ ...@@ -177,7 +177,7 @@
margin: 0px; margin: 0px;
&:last-child { &:last-child {
border:none border-bottom: none;
} }
&.active { &.active {
...@@ -215,3 +215,39 @@ ...@@ -215,3 +215,39 @@
font-size: 16px; font-size: 16px;
line-height: 24px; line-height: 24px;
} }
@mixin nav-menu {
padding: 0;
margin: 0;
list-style: none;
margin-top: 5px;
height: 56px;
li {
display: inline-block;
a {
padding: 14px;
font-size: 17px;
line-height: 28px;
color: #7f8fa4;
border-bottom: 2px solid transparent;
&:hover, &:active, &:focus {
text-decoration: none;
}
}
&.active a {
color: #4c4e54;
border-bottom: 2px solid #1cacfc;
}
.badge {
font-weight: normal;
background-color: #fff;
background-color: #eee;
color: #78a;
}
}
}
...@@ -27,6 +27,15 @@ ...@@ -27,6 +27,15 @@
border-bottom: 1px solid #e7e9ed; border-bottom: 1px solid #e7e9ed;
color: $gl-gray; color: $gl-gray;
&.top-block {
border-top: none;
}
&.middle-block {
margin-top: 0;
margin-bottom: 0;
}
&.second-block { &.second-block {
margin-top: -1px; margin-top: -1px;
margin-bottom: 0; margin-bottom: 0;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
} }
&.btn-save { &.btn-save {
@extend .btn-primary; @extend .btn-success;
} }
&.btn-remove { &.btn-remove {
......
...@@ -370,41 +370,11 @@ table { ...@@ -370,41 +370,11 @@ table {
} }
.center-top-menu { .center-top-menu {
padding: 0; @include nav-menu;
margin: 0;
list-style: none;
text-align: center; text-align: center;
margin-top: 5px; margin-top: 5px;
margin-bottom: $gl-padding; margin-bottom: $gl-padding;
height: 56px; height: 56px;
margin-top: -$gl-padding; margin-top: -$gl-padding;
padding-top: $gl-padding; padding-top: $gl-padding;
li {
display: inline-block;
a {
padding: 14px;
font-size: 17px;
line-height: 28px;
color: #7f8fa4;
border-bottom: 2px solid transparent;
&:hover, &:active, &:focus {
text-decoration: none;
}
}
&.active a {
color: #4c4e54;
border-bottom: 2px solid #1cacfc;
}
.badge {
font-weight: normal;
background-color: #fff;
background-color: #eee;
color: #78a;
}
}
} }
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
*/ */
.issue-box { .issue-box {
@include border-radius(3px);
display: inline-block; display: inline-block;
padding: 4px 13px; padding: 10px $gl-padding;
font-weight: normal; font-weight: normal;
margin-right: 5px; margin-right: 10px;
font-size: $gl-font-size;
&.issue-box-closed { &.issue-box-closed {
background-color: $gl-danger; background-color: $gl-danger;
...@@ -21,7 +24,7 @@ ...@@ -21,7 +24,7 @@
} }
&.issue-box-open { &.issue-box-open {
background-color: $gl-success; background-color: #019875;
color: #FFF; color: #FFF;
} }
......
...@@ -65,8 +65,11 @@ ...@@ -65,8 +65,11 @@
position: relative; position: relative;
} }
.md-header ul { .md-header {
float: left; ul {
float: left;
margin-bottom: 1px;
}
} }
.referenced-users { .referenced-users {
...@@ -80,7 +83,7 @@ ...@@ -80,7 +83,7 @@
.md-preview-holder { .md-preview-holder {
background: #FFF; background: #FFF;
border: 1px solid #ddd; border: 1px solid #ddd;
min-height: 100px; min-height: 169px;
padding: 5px; padding: 5px;
box-shadow: none; box-shadow: none;
} }
...@@ -105,7 +108,7 @@ ...@@ -105,7 +108,7 @@
.markdown-area { .markdown-area {
background: #FFF; background: #FFF;
border: 1px solid #ddd; border: 1px solid #ddd;
min-height: 100px; min-height: 140px;
padding: 5px; padding: 5px;
box-shadow: none; box-shadow: none;
width: 100%; width: 100%;
......
...@@ -28,12 +28,18 @@ ...@@ -28,12 +28,18 @@
padding: $gl-padding; padding: $gl-padding;
border: 1px solid #e7e9ed; border: 1px solid #e7e9ed;
min-height: 90vh; min-height: 90vh;
&.container-blank {
background: none;
padding: 0;
border: none;
}
} }
} }
.nav-sidebar { .nav-sidebar {
margin-top: 14 + $header-height; margin-top: 14 + $header-height;
margin-bottom: 50px; margin-bottom: 100px;
transition-duration: .3s; transition-duration: .3s;
list-style: none; list-style: none;
overflow: hidden; overflow: hidden;
......
.timeline { .timeline {
list-style: none; @include basic-list;
padding: 20px 0 20px;
position: relative;
&:before { margin: 0;
top: 0; padding: 0;
bottom: 0;
position: absolute;
content: " ";
width: 3px;
background-color: #eeeeee;
margin-left: 29px;
}
.timeline-entry { .timeline-entry {
position: relative; padding: $gl-padding;
margin-top: 5px; border-color: #f1f2f4;
margin-left: 30px; margin-left: -$gl-padding;
margin-bottom: 10px; margin-right: -$gl-padding;
clear: both; color: $gl-gray;
border-bottom: 1px solid #f1f2f4;
border-right: 1px solid #f1f2f4;
&:target {
.timeline-entry-inner .timeline-content { &:last-child {
-webkit-animation:target-note 2s linear; border-bottom: none;
background: $hover;
}
} }
.timeline-entry-inner { .avatar {
position: relative; margin-right: 15px;
margin-left: -20px; }
&:before, &:after {
content: " ";
display: table;
}
.timeline-icon {
margin-top: 2px;
background: #fff;
color: #737881;
float: left;
@include border-radius($avatar_radius);
@include box-shadow(0 0 0 3px #EEE);
overflow: hidden;
.avatar {
margin: 0;
padding: 0;
}
}
.timeline-content {
position: relative;
background: $background-color;
padding: 10px 15px;
margin-left: 60px;
img {
max-width: 100%;
}
&:after { .controls {
content: ''; padding-top: 10px;
display: block; float: right;
position: absolute;
width: 0;
height: 0;
border-style: solid;
border-width: 9px 9px 9px 0;
border-color: transparent $background-color transparent transparent;
left: 0;
top: 10px;
margin-left: -9px;
}
}
} }
} }
.system-note .timeline-entry-inner { .note-text {
.timeline-icon { p:last-child {
background: none; margin-bottom: 0;
margin-left: 12px;
margin-top: 0;
@include box-shadow(none);
span {
margin: 0 2px;
font-size: 16px;
color: #eeeeee;
}
} }
}
.timeline-content { .system-note {
background: none; .note-text {
margin-left: 45px; color: $gl-gray !important;
padding: 0px 15px;
&:after { border: 0; }
.note-header {
span { font-size: 12px; }
.avatar {
margin-right: 5px;
}
}
.note-text {
font-size: 12px;
margin-left: 20px;
}
} }
} }
.diff-file {
border: 1px solid $border-color;
border-bottom: none;
margin-left: 0;
margin-right: 0;
}
} }
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
...@@ -132,3 +63,8 @@ ...@@ -132,3 +63,8 @@
} }
} }
} }
.discussion .timeline-entry {
margin: 0;
border-right: none;
}
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
} }
.zen-enter-link { .zen-enter-link {
color: #888; color: $gl-gray;
position: absolute; position: absolute;
top: 0px; top: 0px;
right: 4px; right: 4px;
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
.zen-leave-link { .zen-leave-link {
display: none; display: none;
color: #888; color: $gl-text-color;
position: absolute; position: absolute;
top: 10px; top: 10px;
right: 10px; right: 10px;
......
...@@ -26,14 +26,6 @@ ...@@ -26,14 +26,6 @@
margin-top: 10px; margin-top: 10px;
} }
.commit-stat-summary {
color: #666;
font-size: 14px;
font-weight: normal;
padding: 3px 0;
margin-bottom: 10px;
}
.commit-info-row { .commit-info-row {
margin-bottom: 10px; margin-bottom: 10px;
.avatar { .avatar {
...@@ -47,11 +39,6 @@ ...@@ -47,11 +39,6 @@
} }
.commit-box { .commit-box {
margin: 10px 0;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
padding: 20px 0;
.commit-title { .commit-title {
margin: 0; margin: 0;
} }
......
.diff-file { .diff-file {
border: 1px solid $border-color; margin-left: -16px;
margin-bottom: 1em; margin-right: -16px;
border: none;
border-bottom: 1px solid #E7E9EE;
.diff-header { .diff-header {
position: relative; position: relative;
...@@ -45,7 +47,7 @@ ...@@ -45,7 +47,7 @@
overflow-y: hidden; overflow-y: hidden;
background: #FFF; background: #FFF;
color: #333; color: #333;
font-size: $code_font_size;
.old { .old {
span.idiff { span.idiff {
background-color: #f8cbcb; background-color: #f8cbcb;
...@@ -82,7 +84,7 @@ ...@@ -82,7 +84,7 @@
border: none; border: none;
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
td { .line_holder td {
line-height: $code_line_height; line-height: $code_line_height;
font-size: $code_font_size; font-size: $code_font_size;
} }
...@@ -367,3 +369,7 @@ ...@@ -367,3 +369,7 @@
white-space: pre-wrap; white-space: pre-wrap;
} }
.inline-parallel-buttons {
float: right;
margin-top: -5px;
}
...@@ -25,8 +25,6 @@ ...@@ -25,8 +25,6 @@
} }
.issuable-context-title { .issuable-context-title {
font-size: 14px;
line-height: 1.4;
margin-bottom: 5px; margin-bottom: 5px;
.avatar { .avatar {
...@@ -34,18 +32,12 @@ ...@@ -34,18 +32,12 @@
} }
label { label {
color: #666; color: $gl-gray;
font-weight: normal; font-weight: normal;
margin-right: 4px; margin-right: 4px;
} }
} }
.issuable-affix .context {
font-size: 13px;
.btn { font-size: 13px; }
}
.project-issuable-filter { .project-issuable-filter {
.controls { .controls {
float: right; float: right;
...@@ -56,3 +48,34 @@ ...@@ -56,3 +48,34 @@
text-align: left; text-align: left;
} }
} }
.issuable-details {
.page-title {
margin-top: -15px;
padding: 10px 0;
margin-bottom: 0;
color: $gl-gray;
font-size: 16px;
.author {
color: $gl-gray;
}
.issue-id {
font-size: 19px;
color: $gl-text-color;
}
}
.issue-title {
margin: 0;
}
.description {
margin-top: 6px;
p:last-child {
margin-bottom: 0;
}
}
}
.issues-list { .issues-list {
.issue { .issue {
padding: 10px 15px; padding: 10px $gl-padding;
position: relative; position: relative;
.issue-title { .issue-title {
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
.issue-info { .issue-info {
color: $gl-gray; color: $gl-gray;
font-size: 13px;
} }
.issue-check { .issue-check {
...@@ -47,10 +46,6 @@ ...@@ -47,10 +46,6 @@
} }
} }
.participants {
margin-bottom: 20px;
}
.issue-search-form { .issue-search-form {
margin: 0; margin: 0;
height: 24px; height: 24px;
...@@ -137,11 +132,6 @@ form.edit-issue { ...@@ -137,11 +132,6 @@ form.edit-issue {
} }
} }
h2.issue-title {
margin-top: 0;
font-weight: bold;
}
.issue-form .select2-container { .issue-form .select2-container {
width: 250px !important; width: 250px !important;
} }
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
* *
*/ */
.mr-state-widget { .mr-state-widget {
background: #FAFAFA; background: #f8fafc;
margin-bottom: 20px; margin-bottom: 20px;
color: #666; color: $gl-gray;
border: 1px solid #e5e5e5; border: 1px solid #eef0f2;
@include box-shadow(0 1px 1px rgba(0, 0, 0, 0.05)); @include box-shadow(0 1px 1px rgba(0, 0, 0, 0.05));
@include border-radius(3px); @include border-radius(3px);
...@@ -29,6 +29,14 @@ ...@@ -29,6 +29,14 @@
padding: 5px; padding: 5px;
line-height: 20px; line-height: 20px;
&.right {
float: right;
padding-top: 12px;
a {
color: $gl-gray;
}
}
.remove_source_checkbox { .remove_source_checkbox {
margin: 0; margin: 0;
} }
...@@ -36,7 +44,7 @@ ...@@ -36,7 +44,7 @@
} }
.ci_widget { .ci_widget {
border-bottom: 1px solid #EEE; border-bottom: 1px solid #eef0f2;
i { i {
margin-right: 4px; margin-right: 4px;
...@@ -89,20 +97,14 @@ ...@@ -89,20 +97,14 @@
} }
} }
@media(min-width: $screen-sm-max) {
.merge-request .merge-request-tabs{
li {
a {
padding: 15px 40px;
font-size: 14px;
}
}
}
}
.merge-request .merge-request-tabs{ .merge-request .merge-request-tabs{
margin-top: 30px; @include nav-menu;
margin-bottom: 20px; margin: -$gl-padding;
padding: $gl-padding;
text-align: center;
border-top: 1px solid #e7e9ed;
margin-top: 18px;
margin-bottom: 3px;
} }
.mr_source_commit, .mr_source_commit,
...@@ -137,7 +139,6 @@ ...@@ -137,7 +139,6 @@
.merge-request-info { .merge-request-info {
color: $gl-gray; color: $gl-gray;
font-size: 13px;
} }
} }
......
...@@ -6,4 +6,8 @@ li.milestone { ...@@ -6,4 +6,8 @@ li.milestone {
h4 { h4 {
font-weight: bold; font-weight: bold;
} }
.progress {
height: 6px;
}
} }
...@@ -72,9 +72,13 @@ ...@@ -72,9 +72,13 @@
.common-note-form { .common-note-form {
margin: 0; margin: 0;
background: #F9F9F9; background: #f8fafc;
padding: 5px; padding: $gl-padding;
border: 1px solid #DDD; margin-left: -$gl-padding;
margin-right: -$gl-padding;
border-right: 1px solid #f1f2f4;
border-top: 1px solid #f1f2f4;
margin-bottom: -$gl-padding;
} }
.note-form-actions { .note-form-actions {
...@@ -142,9 +146,9 @@ ...@@ -142,9 +146,9 @@
} }
.discussion-reply-holder { .discussion-reply-holder {
background: #f9f9f9; background: $background-color;
padding: 10px 15px; padding: 10px 15px;
border-top: 1px solid #DDD; border-top: 1px solid $border-color;
} }
} }
...@@ -166,6 +170,6 @@ ...@@ -166,6 +170,6 @@
background: #FFF; background: #FFF;
padding: 5px; padding: 5px;
margin-top: -11px; margin-top: -11px;
border: 1px solid #DDD; border: 1px solid $border-color;
font-size: 13px; font-size: 13px;
} }
...@@ -14,6 +14,19 @@ ul.notes { ...@@ -14,6 +14,19 @@ ul.notes {
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
.system-note {
font-size: 14px;
padding-top: 10px;
padding-bottom: 10px;
background: #f8fafc;
.timeline-icon {
.avatar {
visibility: hidden;
}
}
}
.discussion-header, .discussion-header,
.note-header { .note-header {
@extend .cgray; @extend .cgray;
...@@ -34,10 +47,8 @@ ul.notes { ...@@ -34,10 +47,8 @@ ul.notes {
content: "\00b7"; content: "\00b7";
} }
font-size: 13px;
a { a {
@extend .cgray; color: $gl-gray;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
...@@ -45,8 +56,9 @@ ul.notes { ...@@ -45,8 +56,9 @@ ul.notes {
} }
} }
.author { .author {
color: #333; color: #4c4e54;
font-weight: bold; margin-right: 3px;
&:hover { &:hover {
color: $gl-link-color; color: $gl-link-color;
} }
...@@ -59,7 +71,7 @@ ul.notes { ...@@ -59,7 +71,7 @@ ul.notes {
margin-top: 1px; margin-top: 1px;
border: 1px solid #bbb; border: 1px solid #bbb;
background-color: transparent; background-color: transparent;
color: #999; color: $gl-gray;
} }
} }
...@@ -133,8 +145,6 @@ ul.notes { ...@@ -133,8 +145,6 @@ ul.notes {
} }
.diff-file .notes_holder { .diff-file .notes_holder {
font-size: 13px;
line-height: 18px;
font-family: $regular_font; font-family: $regular_font;
td { td {
...@@ -176,8 +186,7 @@ ul.notes { ...@@ -176,8 +186,7 @@ ul.notes {
a { a {
margin-left: 5px; margin-left: 5px;
color: $gl-gray;
color: #999;
i.fa { i.fa {
font-size: 16px; font-size: 16px;
......
class Admin::LabelsController < Admin::ApplicationController
before_action :set_label, only: [:show, :edit, :update, :destroy]
def index
@labels = Label.templates.page(params[:page]).per(PER_PAGE)
end
def show
end
def new
@label = Label.new
end
def edit
end
def create
@label = Label.new(label_params)
@label.template = true
if @label.save
redirect_to admin_labels_url, notice: "Label was created"
else
render :new
end
end
def update
if @label.update(label_params)
redirect_to admin_labels_path, notice: 'label was successfully updated.'
else
render :edit
end
end
def destroy
@label.destroy
@labels = Label.templates
respond_to do |format|
format.html do
redirect_to(admin_labels_path, notice: 'Label was removed')
end
format.js
end
end
private
def set_label
@label = Label.find(params[:id])
end
def label_params
params[:label].permit(:title, :color)
end
end
require 'gon' require 'gon'
require 'fogbugz'
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
include Gitlab::CurrentSettings include Gitlab::CurrentSettings
...@@ -20,7 +21,7 @@ class ApplicationController < ActionController::Base ...@@ -20,7 +21,7 @@ class ApplicationController < ActionController::Base
protect_from_forgery with: :exception protect_from_forgery with: :exception
helper_method :abilities, :can?, :current_application_settings helper_method :abilities, :can?, :current_application_settings
helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :git_import_enabled? helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled?
rescue_from Encoding::CompatibilityError do |exception| rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception) log_exception(exception)
...@@ -337,6 +338,10 @@ class ApplicationController < ActionController::Base ...@@ -337,6 +338,10 @@ class ApplicationController < ActionController::Base
current_application_settings.import_sources.include?('google_code') current_application_settings.import_sources.include?('google_code')
end end
def fogbugz_import_enabled?
current_application_settings.import_sources.include?('fogbugz')
end
def git_import_enabled? def git_import_enabled?
current_application_settings.import_sources.include?('git') current_application_settings.import_sources.include?('git')
end end
......
class Import::FogbugzController < Import::BaseController
before_action :verify_fogbugz_import_enabled
before_action :user_map, only: [:new_user_map, :create_user_map]
# Doesn't work yet due to bug in ruby-fogbugz, see below
rescue_from Fogbugz::AuthenticationException, with: :fogbugz_unauthorized
def new
end
def callback
begin
res = Gitlab::FogbugzImport::Client.new(import_params.symbolize_keys)
rescue
# Needed until https://github.com/firmafon/ruby-fogbugz/pull/9 is merged
return redirect_to :back, alert: 'Could not authenticate with FogBugz, check your URL, email, and password'
end
session[:fogbugz_token] = res.get_token
session[:fogbugz_uri] = params[:uri]
redirect_to new_user_map_import_fogbugz_path
end
def new_user_map
end
def create_user_map
user_map = params[:users]
unless user_map.is_a?(Hash) && user_map.all? { |k, v| !v[:name].blank? }
flash.now[:alert] = 'All users must have a name.'
render 'new_user_map' and return
end
session[:fogbugz_user_map] = user_map
flash[:notice] = 'The user map has been saved. Continue by selecting the projects you want to import.'
redirect_to status_import_fogbugz_path
end
def status
unless client.valid?
return redirect_to new_import_fogbugz_path
end
@repos = client.repos
@already_added_projects = current_user.created_projects.where(import_type: 'fogbugz')
already_added_projects_names = @already_added_projects.pluck(:import_source)
@repos.reject! { |repo| already_added_projects_names.include? repo.name }
end
def jobs
jobs = current_user.created_projects.where(import_type: 'fogbugz').to_json(only: [:id, :import_status])
render json: jobs
end
def create
@repo_id = params[:repo_id]
repo = client.repo(@repo_id)
fb_session = { uri: session[:fogbugz_uri], token: session[:fogbugz_token] }
@target_namespace = current_user.namespace
@project_name = repo.name
namespace = @target_namespace
umap = session[:fogbugz_user_map] || client.user_map
@project = Gitlab::FogbugzImport::ProjectCreator.new(repo, fb_session, namespace, current_user, umap).execute
end
private
def client
@client ||= Gitlab::FogbugzImport::Client.new(token: session[:fogbugz_token], uri: session[:fogbugz_uri])
end
def user_map
@user_map ||= begin
user_map = client.user_map
stored_user_map = session[:fogbugz_user_map]
user_map.update(stored_user_map) if stored_user_map
user_map
end
end
def fogbugz_unauthorized(exception)
flash[:alert] = exception.message
redirect_to new_import_fogbugz_path
end
def import_params
params.permit(:uri, :email, :password)
end
def verify_fogbugz_import_enabled
not_found! unless fogbugz_import_enabled?
end
end
...@@ -31,4 +31,26 @@ module PageLayoutHelper ...@@ -31,4 +31,26 @@ module PageLayoutHelper
@fluid_layout @fluid_layout
end end
end end
def blank_container(enabled = false)
if @blank_container.nil?
@blank_container = enabled
else
@blank_container
end
end
def container_class
css_class = "container-fluid"
unless fluid_layout
css_class += " container-limited"
end
if blank_container
css_class += " container-blank"
end
css_class
end
end end
...@@ -83,7 +83,7 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -83,7 +83,7 @@ class ApplicationSetting < ActiveRecord::Base
default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
restricted_signup_domains: Settings.gitlab['restricted_signup_domains'], restricted_signup_domains: Settings.gitlab['restricted_signup_domains'],
import_sources: ['github','bitbucket','gitlab','gitorious','google_code','git'] import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git']
) )
end end
......
...@@ -24,7 +24,7 @@ class Label < ActiveRecord::Base ...@@ -24,7 +24,7 @@ class Label < ActiveRecord::Base
validates :color, validates :color,
format: { with: /\A#[0-9A-Fa-f]{6}\Z/ }, format: { with: /\A#[0-9A-Fa-f]{6}\Z/ },
allow_blank: false allow_blank: false
validates :project, presence: true validates :project, presence: true, unless: Proc.new { |service| service.template? }
# Don't allow '?', '&', and ',' for label titles # Don't allow '?', '&', and ',' for label titles
validates :title, validates :title,
...@@ -34,6 +34,8 @@ class Label < ActiveRecord::Base ...@@ -34,6 +34,8 @@ class Label < ActiveRecord::Base
default_scope { order(title: :asc) } default_scope { order(title: :asc) }
scope :templates, -> { where(template: true) }
alias_attribute :name, :title alias_attribute :name, :title
def self.reference_prefix def self.reference_prefix
...@@ -78,4 +80,8 @@ class Label < ActiveRecord::Base ...@@ -78,4 +80,8 @@ class Label < ActiveRecord::Base
def open_issues_count def open_issues_count
issues.opened.count issues.opened.count
end end
def template?
template
end
end end
...@@ -43,6 +43,8 @@ class Project < ActiveRecord::Base ...@@ -43,6 +43,8 @@ class Project < ActiveRecord::Base
extend Gitlab::ConfigHelper extend Gitlab::ConfigHelper
extend Enumerize extend Enumerize
UNKNOWN_IMPORT_URL = 'http://unknown.git'
default_value_for :archived, false default_value_for :archived, false
default_value_for :visibility_level, gitlab_config_features.visibility_level default_value_for :visibility_level, gitlab_config_features.visibility_level
default_value_for :issues_enabled, gitlab_config_features.issues default_value_for :issues_enabled, gitlab_config_features.issues
...@@ -401,6 +403,15 @@ class Project < ActiveRecord::Base ...@@ -401,6 +403,15 @@ class Project < ActiveRecord::Base
end end
end end
def create_labels
Label.templates.each do |label|
label = label.dup
label.template = nil
label.project_id = self.id
label.save
end
end
def find_service(list, name) def find_service(list, name)
list.find { |service| service.to_param == name } list.find { |service| service.to_param == name }
end end
......
...@@ -87,6 +87,8 @@ module Projects ...@@ -87,6 +87,8 @@ module Projects
@project.build_missing_services @project.build_missing_services
@project.create_labels
event_service.create_project(@project, current_user) event_service.create_project(@project, current_user)
system_hook_service.execute_hooks_for(@project, :create) system_hook_service.execute_hooks_for(@project, :create)
......
module Projects
class DownloadService < BaseService
WHITELIST = [
/^[^.]+\.fogbugz.com$/
]
def initialize(project, url)
@project, @url = project, url
end
def execute
return nil unless valid_url?(@url)
uploader = FileUploader.new(@project)
uploader.download!(@url)
uploader.store!
filename = uploader.image? ? uploader.file.basename : uploader.file.filename
{
'alt' => filename,
'url' => uploader.secure_url,
'is_image' => uploader.image?
}
end
private
def valid_url?(url)
url && http?(url) && valid_domain?(url)
end
def http?(url)
url =~ /\A#{URI::regexp(['http', 'https'])}\z/
end
def valid_domain?(url)
host = URI.parse(url).host
WHITELIST.any? { |entry| entry === host }
end
end
end
= form_for [:admin, @label], html: { class: 'form-horizontal label-form js-requires-input' } do |f|
-if @label.errors.any?
.row
.col-sm-offset-2.col-sm-10
.alert.alert-danger
- @label.errors.full_messages.each do |msg|
%span= msg
%br
.form-group
= f.label :title, class: 'control-label'
.col-sm-10
= f.text_field :title, class: "form-control", required: true
.form-group
= f.label :color, "Background Color", class: 'control-label'
.col-sm-10
.input-group
.input-group-addon.label-color-preview &nbsp;
= f.color_field :color, class: "form-control"
.help-block
Choose any color.
%br
Or you can choose one of suggested colors below
.suggest-colors
- suggested_colors.each do |color|
= link_to '#', style: "background-color: #{color}", data: { color: color } do
&nbsp;
.form-actions
= f.submit 'Save', class: 'btn btn-save js-save-button'
= link_to "Cancel", admin_labels_path, class: 'btn btn-cancel'
:coffeescript
new Labels
%li{id: dom_id(label)}
= render_colored_label(label)
.pull-right
= link_to 'Edit', edit_admin_label_path(label), class: 'btn btn-sm'
= link_to 'Remove', admin_label_path(label), class: 'btn btn-sm btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?"}
- if @labels.size == 0
$('.labels').load(document.URL + ' .light-well').hide().fadeIn(1000)
- page_title "Edit", @label.name, "Labels"
%h3
Edit label
%span.light #{@label.name}
.back-link
= link_to admin_labels_path do
&larr; To labels list
%hr
= render 'form'
- page_title "Labels"
= link_to new_admin_label_path, class: "pull-right btn btn-new" do
New label
%h3.page-title
Labels
%hr
.labels
- if @labels.present?
%ul.bordered-list.manage-labels-list
= render @labels
= paginate @labels, theme: 'gitlab'
- else
.light-well
.nothing-here-block There are no any labels yet
\ No newline at end of file
- page_title "New Label"
%h3 New label
.back-link
= link_to admin_labels_path do
&larr; To labels list
%hr
= render 'form'
%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) } %li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) }
%h4 .row
= link_to_gfm truncate(milestone.title, length: 100), dashboard_milestone_path(milestone.safe_title, title: milestone.title) .col-sm-6
%strong
= link_to_gfm truncate(milestone.title, length: 100), dashboard_milestone_path(milestone.safe_title, title: milestone.title)
.col-sm-6
.pull-right.light #{milestone.percent_complete}% complete
.row .row
.col-sm-6 .col-sm-6
= link_to issues_dashboard_path(milestone_title: milestone.title) do = link_to issues_dashboard_path(milestone_title: milestone.title) do
= pluralize milestone.issue_count, 'Issue' = pluralize milestone.issue_count, 'Issue'
&nbsp; &middot;
= link_to merge_requests_dashboard_path(milestone_title: milestone.title) do = link_to merge_requests_dashboard_path(milestone_title: milestone.title) do
= pluralize milestone.merge_requests_count, 'Merge Request' = pluralize milestone.merge_requests_count, 'Merge Request'
&nbsp;
%span.light #{milestone.percent_complete}% complete
.col-sm-6 .col-sm-6
= milestone_progress_bar(milestone) = milestone_progress_bar(milestone)
%div .row
- milestone.milestones.each do |milestone| .col-sm-6
= link_to milestone_path(milestone) do - milestone.milestones.each do |milestone|
%span.label.label-gray = link_to milestone_path(milestone) do
= milestone.project.name_with_namespace %span.label.label-gray
= milestone.project.name_with_namespace
- @blank_container = true
.panel.panel-default .panel.panel-default
.panel-heading .panel-heading
%strong= @group.name %strong= @group.name
......
- page_title "Members" - page_title "Members"
- header_title group_title(@group, "Members", group_group_members_path(@group))
- show_roles = should_user_see_group_roles?(current_user, @group) - show_roles = should_user_see_group_roles?(current_user, @group)
%h3.page-title
Group members
- if show_roles - if show_roles
%p.light %p.light
Members of group have access to all group projects. Members of group have access to all group projects.
Read more about permissions Read more about permissions
%strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
%hr
.clearfix.js-toggle-container .clearfix.js-toggle-container
= form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do = form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do
......
%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) } %li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) }
.pull-right .row
- if can?(current_user, :admin_group, @group) .col-sm-6
- if milestone.closed? %strong
= link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen" = link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title, title: milestone.title)
- else .col-sm-6
= link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-sm btn-close" .pull-right.light #{milestone.percent_complete}% complete
%h4
= link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title, title: milestone.title)
.row .row
.col-sm-6 .col-sm-6
= link_to issues_group_path(@group, milestone_title: milestone.title) do = link_to issues_group_path(@group, milestone_title: milestone.title) do
= pluralize milestone.issue_count, 'Issue' = pluralize milestone.issue_count, 'Issue'
&nbsp; &middot;
= link_to merge_requests_group_path(@group, milestone_title: milestone.title) do = link_to merge_requests_group_path(@group, milestone_title: milestone.title) do
= pluralize milestone.merge_requests_count, 'Merge Request' = pluralize milestone.merge_requests_count, 'Merge Request'
&nbsp;
%span.light #{milestone.percent_complete}% complete
.col-sm-6 .col-sm-6
= milestone_progress_bar(milestone) = milestone_progress_bar(milestone)
%div .row
- milestone.milestones.each do |milestone| .col-sm-6
= link_to milestone_path(milestone) do %div
%span.label.label-gray - milestone.milestones.each do |milestone|
= milestone.project.name = link_to milestone_path(milestone) do
%span.label.label-gray
= milestone.project.name
.col-sm-6
- if can?(current_user, :admin_group, @group)
- if milestone.closed?
= link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-xs btn-grouped btn-reopen"
- else
= link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-xs btn-close"
- page_title "FogBugz Import"
%h3.page-title
%i.fa.fa-bug
Import projects from FogBugz
%hr
= form_tag callback_import_fogbugz_path, class: 'form-horizontal' do
%p
To get started you enter your FogBugz URL and login information below.
In the next steps, you'll be able to map users and select the projects
you want to import.
.form-group
= label_tag :uri, 'FogBugz URL', class: 'control-label'
.col-sm-4
= text_field_tag :uri, nil, placeholder: 'https://mycompany.fogbugz.com', class: 'form-control'
.form-group
= label_tag :email, 'FogBugz Email', class: 'control-label'
.col-sm-4
= text_field_tag :email, nil, class: 'form-control'
.form-group
= label_tag :password, 'FogBugz Password', class: 'control-label'
.col-sm-4
= password_field_tag :password, nil, class: 'form-control'
.form-actions
= submit_tag 'Continue to the next step', class: 'btn btn-create'
- page_title 'User map', 'FogBugz import'
%h3.page-title
%i.fa.fa-bug
Import projects from FogBugz
%hr
= form_tag create_user_map_import_fogbugz_path, class: 'form-horizontal' do
%p
Customize how FogBugz email addresses and usernames are imported into GitLab.
In the next step, you'll be able to select the projects you want to import.
%p
The user map is a mapping of the FogBugz users that participated on your projects to the way their email address and usernames wil be imported into GitLab. You can change this by populating the table below.
%ul
%li
%strong Default: Map a FogBugz account ID to a full name
%p
An empty GitLab User field will add the FogBugz user's full name
(e.g. "By John Smith") in the description of all issues and comments.
It will also associate and/or assign these issues and comments with
the project creator.
%li
%strong Map a FogBugz account ID to a GitLab user
%p
Selecting a GitLab user will add a link to the GitLab user in the descriptions
of issues and comments (e.g. "By <a href="#">@johnsmith</a>"). It will also
associate and/or assign these issues and comments with the selected user.
%table.table
%thead
%tr
%th ID
%th Name
%th Email
%th GitLab User
%tbody
- @user_map.each do |id, user|
%tr
%td= id
%td= text_field_tag "users[#{id}][name]", user[:name], class: 'form-control'
%td= text_field_tag "users[#{id}][email]", user[:email], class: 'form-control'
%td
= users_select_tag("users[#{id}][gitlab_user]", class: 'custom-form-control',
scope: :all, email_user: true, selected: user[:gitlab_user])
.form-actions
= submit_tag 'Continue to the next step', class: 'btn btn-create'
:coffeescript
new UsersSelect()
- page_title "FogBugz import"
%h3.page-title
%i.fa.fa-bug
Import projects from FogBugz
- if @repos.any?
%p.light
Select projects you want to import.
%p.light
Optionally, you can
= link_to 'customize', new_user_map_import_fogbugz_path
how FogBugz email addresses and usernames are imported into GitLab.
%hr
%p
= button_tag 'Import all projects', class: 'btn btn-success js-import-all'
%table.table.import-jobs
%thead
%tr
%th From FogBugz
%th To GitLab
%th Status
%tbody
- @already_added_projects.each do |project|
%tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"}
%td
= project.import_source
%td
%strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project]
%td.job-status
- if project.import_status == 'finished'
%span
%i.fa.fa-check
done
- elsif project.import_status == 'started'
%i.fa.fa-spinner.fa-spin
started
- else
= project.human_import_status_name
- @repos.each do |repo|
%tr{id: "repo_#{repo.id}"}
%td
= repo.name
%td.import-target
= "#{current_user.username}/#{repo.name}"
%td.import-actions.job-status
= button_tag "Import", class: "btn js-add-to-import"
:coffeescript
new ImporterStatus("#{jobs_import_fogbugz_path}", "#{import_fogbugz_path}")
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
%meta{charset: "utf-8"} %meta{charset: "utf-8"}
%meta{'http-equiv' => 'X-UA-Compatible', content: 'IE=edge'} %meta{'http-equiv' => 'X-UA-Compatible', content: 'IE=edge'}
%meta{content: "GitLab Community Edition", name: "description"} %meta{content: "GitLab Community Edition", name: "description"}
%meta{name: 'referrer', content: 'origin'}
%title= page_title %title= page_title
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
= current_user.username = current_user.username
.content-wrapper .content-wrapper
= render "layouts/flash" = render "layouts/flash"
%div{ class: fluid_layout ? "container-fluid" : "container-fluid container-limited" } %div{ class: container_class }
.content .content
.clearfix .clearfix
= yield = yield
...@@ -57,6 +57,12 @@ ...@@ -57,6 +57,12 @@
%span %span
Service Templates Service Templates
= nav_link(controller: :labels) do
= link_to admin_labels_path, title: 'Labels', data: {placement: 'right'} do
= icon('tags fw')
%span
Labels
= nav_link(controller: :abuse_reports) do = nav_link(controller: :abuse_reports) do
= link_to admin_abuse_reports_path, title: "Abuse reports" do = link_to admin_abuse_reports_path, title: "Abuse reports" do
= icon('exclamation-circle fw') = icon('exclamation-circle fw')
......
...@@ -36,13 +36,13 @@ ...@@ -36,13 +36,13 @@
= icon('clipboard fw') = icon('clipboard fw')
%span %span
Snippets Snippets
= nav_link(controller: :profile) do
= link_to profile_path, title: 'Profile settings', data: {placement: 'bottom'} do
= icon('user fw')
%span
Profile Settings
= nav_link(controller: :help) do = nav_link(controller: :help) do
= link_to help_path, title: 'Help', data: {placement: 'right'} do = link_to help_path, title: 'Help', data: {placement: 'right'} do
= icon('question-circle fw') = icon('question-circle fw')
%span %span
Help Help
= nav_link(controller: :profile) do
= link_to profile_path, title: 'Profile settings', data: {placement: 'bottom'} do
= icon('user fw')
%span
Profile Settings
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
= link_to profile_path, title: 'Profile', data: {placement: 'right'} do = link_to profile_path, title: 'Profile', data: {placement: 'right'} do
= icon('user fw') = icon('user fw')
%span %span
Profile Profile Settings
= nav_link(controller: [:accounts, :two_factor_auths]) do = nav_link(controller: [:accounts, :two_factor_auths]) do
= link_to profile_account_path, title: 'Account', data: {placement: 'right'} do = link_to profile_account_path, title: 'Account', data: {placement: 'right'} do
= icon('gear fw') = icon('gear fw')
......
- page_title "Profile Settings" - page_title "Profile Settings"
- header_title "Profile Settings", profile_path - unless @header_title
- header_title "Profile Settings", profile_path
- sidebar "profile" - sidebar "profile"
= render template: "layouts/application" = render template: "layouts/application"
- page_title "Account" - page_title "Account"
%h3.page-title - header_title page_title, profile_account_path
= page_title - @blank_container = true
%p.light
Change your username and basic account settings.
%hr
- if current_user.ldap_user? - if current_user.ldap_user?
.alert.alert-info .alert.alert-info
Some options are unavailable for LDAP accounts Some options are unavailable for LDAP accounts
...@@ -69,7 +67,7 @@ ...@@ -69,7 +67,7 @@
- button_based_providers.each do |provider| - button_based_providers.each do |provider|
.btn-group .btn-group
= link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: "btn btn-lg #{'active' if auth_active?(provider)}", "data-no-turbolink" => "true" = link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: "btn btn-lg #{'active' if auth_active?(provider)}", "data-no-turbolink" => "true"
- if auth_active?(provider) - if auth_active?(provider)
= link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do = link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do
= icon('close') = icon('close')
......
- page_title "Applications" - page_title "Applications"
%h3.page-title - header_title page_title, applications_profile_path
= page_title
%p.light .gray-content-block.top-block
- if user_oauth_applications? - if user_oauth_applications?
Manage applications that can use GitLab as an OAuth provider, Manage applications that can use GitLab as an OAuth provider,
and applications that you've authorized to use your account. and applications that you've authorized to use your account.
- else - else
Manage applications that you've authorized to use your account. Manage applications that you've authorized to use your account.
%hr
- if user_oauth_applications? - if user_oauth_applications?
.oauth-applications .oauth-applications
......
- page_title "Audit Log" - page_title "Audit Log"
%h3.page-title Audit Log - header_title page_title, audit_log_profile_path
%p.light History of authentications
= render 'event_table', events: @events .gray-content-block.top-block
\ No newline at end of file History of authentications
.prepend-top-default
= render 'event_table', events: @events
- page_title "Emails" - page_title "Emails"
%h3.page-title - header_title page_title, profile_emails_path
= page_title
%p.light
Control emails linked to your account
%hr
.gray-content-block.top-block
Control emails linked to your account
%ul %ul.prepend-top-default
%li %li
Your Your
%b Primary Email %b Primary Email
......
- page_title "SSH Keys" - page_title "SSH Keys"
%h3.page-title - header_title page_title, profile_keys_path
= page_title
.gray-content-block.top-block
.pull-right .pull-right
= link_to "Add SSH Key", new_profile_key_path, class: "btn btn-new" = link_to "Add SSH Key", new_profile_key_path, class: "btn btn-new"
%p.light .oneline
Before you can add an SSH key you need to Before you can add an SSH key you need to
= link_to "generate it.", help_page_path("ssh", "README") = link_to "generate it.", help_page_path("ssh", "README")
%hr
.prepend-top-default
= render 'key_table' = render 'key_table'
- page_title "Notifications" - page_title "Notifications"
%h3.page-title - header_title page_title, profile_notifications_path
= page_title
%p.light .gray-content-block.top-block
These are your global notification settings. These are your global notification settings.
%hr
.prepend-top-default
= form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications form-horizontal global-notifications-form' } do |f| = form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications form-horizontal global-notifications-form' } do |f|
-if @user.errors.any? -if @user.errors.any?
%div.alert.alert-danger %div.alert.alert-danger
......
- page_title "Password" - page_title "Password"
%h3.page-title - header_title page_title, edit_profile_password_path
= page_title
%p.light .gray-content-block.top-block
- if @user.password_automatically_set? - if @user.password_automatically_set?
Set your password. Set your password.
- else - else
Change your password or recover your current one. Change your password or recover your current one.
%hr
.update-password .update-password.prepend-top-default
= form_for @user, url: profile_password_path, method: :put, html: { class: 'form-horizontal' } do |f| = form_for @user, url: profile_password_path, method: :put, html: { class: 'form-horizontal' } do |f|
%div %div
%p.slead %p.slead
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
%ul %ul
- @user.errors.full_messages.each do |msg| - @user.errors.full_messages.each do |msg|
%li= msg %li= msg
- unless @user.password_automatically_set? - unless @user.password_automatically_set?
.form-group .form-group
= f.label :current_password, class: 'control-label' = f.label :current_password, class: 'control-label'
......
- page_title 'Preferences' - page_title 'Preferences'
%h3.page-title - header_title page_title, profile_preferences_path
= page_title - @blank_container = true
%p.light
.alert.alert-help
These settings allow you to customize the appearance and behavior of the site. These settings allow you to customize the appearance and behavior of the site.
They are saved with your account and will persist to any device you use to They are saved with your account and will persist to any device you use to
access the site. access the site.
%hr
= form_for @user, url: profile_preferences_path, remote: true, method: :put, html: {class: 'js-preferences-form form-horizontal'} do |f| = form_for @user, url: profile_preferences_path, remote: true, method: :put, html: {class: 'js-preferences-form form-horizontal'} do |f|
.panel.panel-default.application-theme .panel.panel-default.application-theme
......
- page_title "Profile" .gray-content-block.top-block
%h3.page-title
= page_title
%p.light
This information will appear on your profile. This information will appear on your profile.
- if current_user.ldap_user? - if current_user.ldap_user?
Some options are unavailable for LDAP accounts Some options are unavailable for LDAP accounts
%hr
.prepend-top-default
= form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit_user form-horizontal" }, authenticity_token: true do |f| = form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit_user form-horizontal" }, authenticity_token: true do |f|
-if @user.errors.any? -if @user.errors.any?
%div.alert.alert-danger %div.alert.alert-danger
......
.md-area .md-area
.md-header.clearfix .md-header.clearfix
%ul.nav.nav-tabs %ul.center-top-menu
%li.active %li.active
= link_to '#md-write-holder', class: 'js-md-write-button', tabindex: '-1' do = link_to '#md-write-holder', class: 'js-md-write-button', tabindex: '-1' do
Write Write
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
You are about to add You are about to add
%strong %strong
%span.js-referenced-users-count 0 %span.js-referenced-users-count 0
people people
to the discussion. Proceed with caution. to the discussion. Proceed with caution.
%div %div
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
.commit-info-row.branches .commit-info-row.branches
%i.fa.fa-spinner.fa-spin %i.fa.fa-spinner.fa-spin
.commit-box .commit-box.gray-content-block.middle-block
%h3.commit-title %h3.commit-title
= gfm escape_once(@commit.title) = gfm escape_once(@commit.title)
- if @commit.description.present? - if @commit.description.present?
......
- if params[:view] == 'parallel' - if params[:view] == 'parallel'
- fluid_layout true - fluid_layout true
.prepend-top-20.append-bottom-20 .gray-content-block.second-block
.pull-right .inline-parallel-buttons
.btn-group .btn-group
= inline_diff_btn = inline_diff_btn
= parallel_diff_btn = parallel_diff_btn
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
and and
%strong.cred #{@commit.stats.deletions} deletions %strong.cred #{@commit.stats.deletions} deletions
.file-stats.js-toggle-content.hide .file-stats.js-toggle-content.hide
%ul.bordered-list %ul
- diffs.each_with_index do |diff, i| - diffs.each_with_index do |diff, i|
%li %li
- if diff.deleted_file - if diff.deleted_file
......
- @blank_container = true
.project-edit-container .project-edit-container
.project-edit-errors .project-edit-errors
.project-edit-content .project-edit-content
%div .panel.panel-default
%h3.page-title .panel-heading
Project settings Project settings
%hr
.panel-body .panel-body
= form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal fieldset-form" }, authenticity_token: true do |f| = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal fieldset-form" }, authenticity_token: true do |f|
......
...@@ -22,15 +22,15 @@ ...@@ -22,15 +22,15 @@
%h5 Git global setup %h5 Git global setup
%pre.light-well %pre.light-well
:preserve :preserve
git config --global user.name "#{git_user_name}" git config --global user.name "#{h git_user_name}"
git config --global user.email "#{git_user_email}" git config --global user.email "#{h git_user_email}"
%fieldset %fieldset
%h5 Create a new repository %h5 Create a new repository
%pre.light-well %pre.light-well
:preserve :preserve
git clone #{ content_tag(:span, default_url_to_repo, class: 'clone')} git clone #{ content_tag(:span, default_url_to_repo, class: 'clone')}
cd #{@project.path} cd #{h @project.path}
touch README.md touch README.md
git add README.md git add README.md
git commit -m "add README" git commit -m "add README"
......
...@@ -7,21 +7,24 @@ ...@@ -7,21 +7,24 @@
= render 'shared/show_aside' = render 'shared/show_aside'
.gray-content-block.second-block
.row
.col-md-9
.votes-holder.pull-right
#votes= render 'votes/votes_block', votable: @issue
.participants
%span= pluralize(@participants.count, 'participant')
- @participants.each do |participant|
= link_to_member(@project, participant, name: false, size: 24)
.col-md-3
%span.slead.has_tooltip{title: 'Cross-project reference'}
= cross_project_reference(@project, @issue)
.row .row
%section.col-md-9 %section.col-md-9
.votes-holder.pull-right
#votes= render 'votes/votes_block', votable: @issue
.participants
%span= pluralize(@participants.count, 'participant')
- @participants.each do |participant|
= link_to_member(@project, participant, name: false, size: 24)
.voting_notes#notes= render 'projects/notes/notes_with_form' .voting_notes#notes= render 'projects/notes/notes_with_form'
%aside.col-md-3 %aside.col-md-3
.issuable-affix .issuable-affix
.clearfix
%span.slead.has_tooltip{title: 'Cross-project reference'}
= cross_project_reference(@project, @issue)
%hr
.context .context
= render 'shared/issuable/context', issuable: @issue = render 'shared/issuable/context', issuable: @issue
......
...@@ -41,4 +41,4 @@ ...@@ -41,4 +41,4 @@
= issue.task_status = issue.task_status
.pull-right.issue-updated-at .pull-right.issue-updated-at
%small updated #{time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago')} %span updated #{time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago')}
- page_title "#{@issue.title} (##{@issue.iid})", "Issues" - page_title "#{@issue.title} (##{@issue.iid})", "Issues"
.issue .issue
.issue-details.issuable-details .issue-details.issuable-details
%h4.page-title .page-title
.issue-box{ class: issue_box_class(@issue) } .issue-box{ class: issue_box_class(@issue) }
- if @issue.closed? - if @issue.closed?
Closed Closed
- else - else
Open Open
Issue ##{@issue.iid} %span.issue-id Issue ##{@issue.iid}
%small.creator %span.creator
&middot; created by #{link_to_member(@project, @issue.author)} &middot; created by #{link_to_member(@project, @issue.author, size: 24)}
&middot;
= time_ago_with_tooltip(@issue.created_at, placement: 'bottom', html_class: 'issue_created_ago') = time_ago_with_tooltip(@issue.created_at, placement: 'bottom', html_class: 'issue_created_ago')
- if @issue.updated_at != @issue.created_at - if @issue.updated_at != @issue.created_at
%span %span
...@@ -32,18 +33,17 @@ ...@@ -32,18 +33,17 @@
= icon('pencil-square-o') = icon('pencil-square-o')
Edit Edit
%hr .gray-content-block.middle-block
%h2.issue-title %h2.issue-title
= gfm escape_once(@issue.title) = gfm escape_once(@issue.title)
%div %div
- if @issue.description.present? - if @issue.description.present?
.description{class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : ''} .description{class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : ''}
.wiki .wiki
= preserve do = preserve do
= markdown(@issue.description) = markdown(@issue.description)
%textarea.hidden.js-task-list-field %textarea.hidden.js-task-list-field
= @issue.description = @issue.description
%hr
.issue-discussion .issue-discussion
= render 'projects/issues/discussion' = render 'projects/issues/discussion'
...@@ -7,18 +7,21 @@ ...@@ -7,18 +7,21 @@
= render 'shared/show_aside' = render 'shared/show_aside'
.gray-content-block.second-block
.row
.col-md-9
.votes-holder.pull-right
#votes= render 'votes/votes_block', votable: @merge_request
= render "projects/merge_requests/show/participants"
.col-md-3
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
= cross_project_reference(@project, @merge_request)
.row .row
%section.col-md-9 %section.col-md-9
.votes-holder.pull-right
#votes= render 'votes/votes_block', votable: @merge_request
= render "projects/merge_requests/show/participants"
= render "projects/notes/notes_with_form" = render "projects/notes/notes_with_form"
%aside.col-md-3 %aside.col-md-3
.issuable-affix .issuable-affix
.clearfix
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
= cross_project_reference(@project, @merge_request)
%hr
.context .context
= render 'shared/issuable/context', issuable: @merge_request = render 'shared/issuable/context', issuable: @merge_request
......
...@@ -43,4 +43,4 @@ ...@@ -43,4 +43,4 @@
= merge_request.task_status = merge_request.task_status
.pull-right.hidden-xs .pull-right.hidden-xs
%small updated #{time_ago_with_tooltip(merge_request.updated_at, placement: 'bottom', html_class: 'merge_request_updated_ago')} %span updated #{time_ago_with_tooltip(merge_request.updated_at, placement: 'bottom', html_class: 'merge_request_updated_ago')}
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
%h4 Compare failed %h4 Compare failed
%p We can't compare selected branches. It may be because of huge diff. Please try again or select different branches. %p We can't compare selected branches. It may be because of huge diff. Please try again or select different branches.
- else - else
.light-well .light-well.append-bottom-10
.center .center
%h4 %h4
There isn't anything to merge. There isn't anything to merge.
......
...@@ -18,15 +18,13 @@ ...@@ -18,15 +18,13 @@
= f.hidden_field :target_branch = f.hidden_field :target_branch
.mr-compare.merge-request .mr-compare.merge-request
%ul.nav.nav-tabs.merge-request-tabs %ul.merge-request-tabs
%li.commits-tab %li.commits-tab
= link_to url_for(params), data: {target: '#commits', action: 'commits', toggle: 'tab'} do = link_to url_for(params), data: {target: '#commits', action: 'commits', toggle: 'tab'} do
= icon('history')
Commits Commits
%span.badge= @commits.size %span.badge= @commits.size
%li.diffs-tab.active %li.diffs-tab.active
= link_to url_for(params), data: {target: '#diffs', action: 'diffs', toggle: 'tab'} do = link_to url_for(params), data: {target: '#diffs', action: 'diffs', toggle: 'tab'} do
= icon('list-alt')
Changes Changes
%span.badge= @diffs.size %span.badge= @diffs.size
......
...@@ -5,10 +5,8 @@ ...@@ -5,10 +5,8 @@
.merge-request{'data-url' => merge_request_path(@merge_request)} .merge-request{'data-url' => merge_request_path(@merge_request)}
.merge-request-details.issuable-details .merge-request-details.issuable-details
= render "projects/merge_requests/show/mr_title" = render "projects/merge_requests/show/mr_title"
%hr
= render "projects/merge_requests/show/mr_box" = render "projects/merge_requests/show/mr_box"
%hr .append-bottom-20.mr-source-target.prepend-top-default
.append-bottom-20.mr-source-target
- if @merge_request.open? - if @merge_request.open?
.pull-right .pull-right
- if @merge_request.source_branch_exists? - if @merge_request.source_branch_exists?
...@@ -39,20 +37,17 @@ ...@@ -39,20 +37,17 @@
= link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
- if @commits.present? - if @commits.present?
%ul.nav.nav-tabs.merge-request-tabs %ul.merge-request-tabs
%li.notes-tab %li.notes-tab
= link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#notes', action: 'notes', toggle: 'tab'} do = link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#notes', action: 'notes', toggle: 'tab'} do
= icon('comments')
Discussion Discussion
%span.badge= @merge_request.mr_and_commit_notes.user.count %span.badge= @merge_request.mr_and_commit_notes.user.count
%li.commits-tab %li.commits-tab
= link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#commits', action: 'commits', toggle: 'tab'} do = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#commits', action: 'commits', toggle: 'tab'} do
= icon('history')
Commits Commits
%span.badge= @commits.size %span.badge= @commits.size
%li.diffs-tab %li.diffs-tab
= link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#diffs', action: 'diffs', toggle: 'tab'} do = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#diffs', action: 'diffs', toggle: 'tab'} do
= icon('list-alt')
Changes Changes
%span.badge= @merge_request.diffs.size %span.badge= @merge_request.diffs.size
......
...@@ -11,12 +11,12 @@ ...@@ -11,12 +11,12 @@
%pre.dark %pre.dark
- if @merge_request.for_fork? - if @merge_request.for_fork?
:preserve :preserve
git fetch #{@merge_request.source_project.http_url_to_repo} #{@merge_request.source_branch} git fetch #{h @merge_request.source_project.http_url_to_repo} #{h @merge_request.source_branch}
git checkout -b #{@merge_request.source_project_path}-#{@merge_request.source_branch} FETCH_HEAD git checkout -b #{h @merge_request.source_project_path}-#{h @merge_request.source_branch} FETCH_HEAD
- else - else
:preserve :preserve
git fetch origin git fetch origin
git checkout -b #{@merge_request.source_branch} origin/#{@merge_request.source_branch} git checkout -b #{h @merge_request.source_branch} origin/#{h @merge_request.source_branch}
%p %p
%strong Step 2. %strong Step 2.
Review the changes locally Review the changes locally
...@@ -27,18 +27,18 @@ ...@@ -27,18 +27,18 @@
%pre.dark %pre.dark
- if @merge_request.for_fork? - if @merge_request.for_fork?
:preserve :preserve
git checkout #{@merge_request.target_branch} git checkout #{h @merge_request.target_branch}
git merge --no-ff #{@merge_request.source_project_path}-#{@merge_request.source_branch} git merge --no-ff #{h @merge_request.source_project_path}-#{h @merge_request.source_branch}
- else - else
:preserve :preserve
git checkout #{@merge_request.target_branch} git checkout #{h @merge_request.target_branch}
git merge --no-ff #{@merge_request.source_branch} git merge --no-ff #{h @merge_request.source_branch}
%p %p
%strong Step 4. %strong Step 4.
Push the result of the merge to GitLab Push the result of the merge to GitLab
%pre.dark %pre.dark
:preserve :preserve
git push origin #{@merge_request.target_branch} git push origin #{h @merge_request.target_branch}
- unless @merge_request.can_be_merged_by?(current_user) - unless @merge_request.can_be_merged_by?(current_user)
%p %p
Note that pushing to GitLab requires write access to this repository. Note that pushing to GitLab requires write access to this repository.
......
%h2.issue-title .gray-content-block.middle-block
= gfm escape_once(@merge_request.title) %h2.issue-title
= gfm escape_once(@merge_request.title)
%div %div
- if @merge_request.description.present? - if @merge_request.description.present?
.description{class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : ''} .description{class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : ''}
.wiki .wiki
= preserve do = preserve do
= markdown(@merge_request.description) = markdown(@merge_request.description)
%textarea.hidden.js-task-list-field %textarea.hidden.js-task-list-field
= @merge_request.description = @merge_request.description
%h4.page-title .page-title
.issue-box{ class: issue_box_class(@merge_request) } .issue-box{ class: issue_box_class(@merge_request) }
= @merge_request.state_human_name = @merge_request.state_human_name
Merge Request ##{@merge_request.iid} %span.issue-id Merge Request ##{@merge_request.iid}
%small.creator %span.creator
&middot;
created by #{link_to_member(@project, @merge_request.author, size: 24)}
&middot; &middot;
created by #{link_to_member(@project, @merge_request.author)}
= time_ago_with_tooltip(@merge_request.created_at) = time_ago_with_tooltip(@merge_request.created_at)
- if @merge_request.updated_at != @merge_request.created_at - if @merge_request.updated_at != @merge_request.created_at
%span %span
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
= label_tag :should_remove_source_branch, class: "remove_source_checkbox" do = label_tag :should_remove_source_branch, class: "remove_source_checkbox" do
= check_box_tag :should_remove_source_branch = check_box_tag :should_remove_source_branch
Remove source branch Remove source branch
.accept-control .accept-control.right
= link_to "#", class: "modify-merge-commit-link js-toggle-button" do = link_to "#", class: "modify-merge-commit-link js-toggle-button" do
= icon('edit') = icon('edit')
Modify commit message Modify commit message
......
%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone) } %li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone) }
.pull-right .row
- if can?(current_user, :admin_milestone, milestone.project) and milestone.active? .col-sm-6
= link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-sm edit-milestone-link btn-grouped" do %strong
%i.fa.fa-pencil-square-o = link_to_gfm truncate(milestone.title, length: 100), namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone)
Edit
= link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-sm btn-close"
= link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-sm btn-remove" do
%i.fa.fa-trash-o
Remove
%h4 .col-sm-6
= link_to_gfm truncate(milestone.title, length: 100), namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) .pull-right.light #{milestone.percent_complete}% complete
- if milestone.expired? and not milestone.closed?
%span.cred (Expired)
%small
= milestone.expires_at
.row .row
.col-sm-6 .col-sm-6
= link_to namespace_project_issues_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title) do = link_to namespace_project_issues_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title) do
= pluralize milestone.issues.count, 'Issue' = pluralize milestone.issues.count, 'Issue'
&nbsp; &middot;
= link_to namespace_project_merge_requests_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title) do = link_to namespace_project_merge_requests_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title) do
= pluralize milestone.merge_requests.count, 'Merge Request' = pluralize milestone.merge_requests.count, 'Merge Request'
&nbsp;
%span.light #{milestone.percent_complete}% complete
.col-sm-6 .col-sm-6
= milestone_progress_bar(milestone) = milestone_progress_bar(milestone)
.row
.col-sm-6
- if milestone.expired? and not milestone.closed?
%span.cred (Expired)
- if milestone.expires_at
%span
= milestone.expires_at
.col-sm-6
- if can?(current_user, :admin_milestone, milestone.project) and milestone.active?
= link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-xs edit-milestone-link btn-grouped" do
%i.fa.fa-pencil-square-o
Edit
= link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close"
= link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-xs btn-remove" do
%i.fa.fa-trash-o
Remove
...@@ -72,6 +72,11 @@ ...@@ -72,6 +72,11 @@
%i.fa.fa-google %i.fa.fa-google
Google Code Google Code
- if fogbugz_import_enabled?
= link_to new_import_fogbugz_path, class: 'btn import_fogbugz' do
%i.fa.fa-bug
Fogbugz
- if git_import_enabled? - if git_import_enabled?
= link_to "#", class: 'btn js-toggle-button import_git' do = link_to "#", class: 'btn js-toggle-button import_git' do
%i.fa.fa-git %i.fa.fa-git
......
%li.timeline-entry{ id: dom_id(note), class: [dom_class(note), "note-row-#{note.id}", ('system-note' if note.system)], data: { discussion: note.discussion_id } } %li.timeline-entry{ id: dom_id(note), class: [dom_class(note), "note-row-#{note.id}", ('system-note' if note.system)], data: { discussion: note.discussion_id } }
.timeline-entry-inner .timeline-entry-inner
.timeline-icon .timeline-icon
- if note.system = link_to user_path(note.author) do
%span= icon('circle') = image_tag avatar_icon(note.author_email), class: 'avatar s40', alt: ''
- else
= link_to user_path(note.author) do
= image_tag avatar_icon(note.author_email), class: 'avatar s40', alt: ''
.timeline-content .timeline-content
.note-header .note-header
- if note_editable?(note) - if note_editable?(note)
...@@ -22,10 +19,6 @@ ...@@ -22,10 +19,6 @@
%span.note-role.label %span.note-role.label
= member.human_access = member.human_access
- if note.system
= link_to user_path(note.author) do
= image_tag avatar_icon(note.author_email), class: 'avatar s16', alt: ''
= link_to_member(note.project, note.author, avatar: false) = link_to_member(note.project, note.author, avatar: false)
%span.author-username %span.author-username
......
%span.pull-right %span.pull-right
- if can?(current_user, :create_wiki, @project)
= link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new btn-grouped", "data-toggle" => "modal" do
%i.fa.fa-plus
New Page
- if (@page && @page.persisted?) - if (@page && @page.persisted?)
= link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn btn-grouped" do = link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn btn-grouped" do
Page History Page History
...@@ -6,3 +11,5 @@ ...@@ -6,3 +11,5 @@
= link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn btn-grouped" do = link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn btn-grouped" do
%i.fa.fa-pencil-square-o %i.fa.fa-pencil-square-o
Edit Edit
= render 'projects/wikis/new'
%ul.nav.nav-tabs %ul.center-top-menu
= nav_link(html_options: {class: params[:id] == 'home' ? 'active' : '' }) do = nav_link(html_options: {class: params[:id] == 'home' ? 'active' : '' }) do
= link_to 'Home', namespace_project_wiki_path(@project.namespace, @project, :home) = link_to 'Home', namespace_project_wiki_path(@project.namespace, @project, :home)
...@@ -7,13 +7,4 @@ ...@@ -7,13 +7,4 @@
= nav_link(path: 'wikis#git_access') do = nav_link(path: 'wikis#git_access') do
= link_to namespace_project_wikis_git_access_path(@project.namespace, @project) do = link_to namespace_project_wikis_git_access_path(@project.namespace, @project) do
%i.fa.fa-download
Git Access Git Access
- if can?(current_user, :create_wiki, @project)
.pull-right
= link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do
%i.fa.fa-plus
New Page
= render 'projects/wikis/new'
- page_title "Git Access", "Wiki" - page_title "Git Access", "Wiki"
= render 'nav' = render 'nav'
.row .gray-content-block
.col-sm-6 .row
%h3.page-title .col-sm-6
Git access for %h3.page-title
%strong= @project_wiki.path_with_namespace Git access for
%strong= @project_wiki.path_with_namespace
.col-sm-6 .col-sm-6
= render "shared/clone_panel", project: @project_wiki = render "shared/clone_panel", project: @project_wiki
.git-empty .git-empty.prepend-top-default
%fieldset %fieldset
%legend Install Gollum: %legend Install Gollum:
%pre.dark %pre.dark
...@@ -20,7 +21,7 @@ ...@@ -20,7 +21,7 @@
%pre.dark %pre.dark
:preserve :preserve
git clone #{ content_tag(:span, default_url_to_repo(@project_wiki), class: 'clone')} git clone #{ content_tag(:span, default_url_to_repo(@project_wiki), class: 'clone')}
cd #{@project_wiki.path} cd #{h @project_wiki.path}
%legend Start Gollum And Edit Locally: %legend Start Gollum And Edit Locally:
%pre.dark %pre.dark
......
- page_title "History", @page.title, "Wiki" - page_title "History", @page.title, "Wiki"
= render 'nav' = render 'nav'
%h3.page-title .gray-content-block
%span.light History for %h3.page-title
= link_to @page.title, namespace_project_wiki_path(@project.namespace, @project, @page) %span.light History for
= link_to @page.title, namespace_project_wiki_path(@project.namespace, @project, @page)
%table.table %table.table
%thead %thead
......
- page_title "All Pages", "Wiki" - page_title "All Pages", "Wiki"
= render 'nav' = render 'nav'
%h3.page-title .gray-content-block
All Pages %h3.page-title
%ul.bordered-list All Pages
%ul.content-list
- @wiki_pages.each do |wiki_page| - @wiki_pages.each do |wiki_page|
%li %li
%h4 %h4
......
- page_title @page.title, "Wiki" - page_title @page.title, "Wiki"
= render 'nav' = render 'nav'
%h3.page-title
= @page.title .gray-content-block
= render 'main_links' = render 'main_links'
%h3.page-title
= @page.title.capitalize
.wiki-last-edit-by .wiki-last-edit-by
Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)} Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)}
- if @page.historical? - if @page.historical?
.warning_message .warning_message
This is an old version of this page. This is an old version of this page.
You can view the #{link_to "most recent version", namespace_project_wiki_path(@project.namespace, @project, @page)} or browse the #{link_to "history", namespace_project_wiki_history_path(@project.namespace, @project, @page)}. You can view the #{link_to "most recent version", namespace_project_wiki_path(@project.namespace, @project, @page)} or browse the #{link_to "history", namespace_project_wiki_history_path(@project.namespace, @project, @page)}.
%hr
.wiki-holder .wiki-holder.prepend-top-default
.wiki .wiki
= preserve do = preserve do
= render_wiki_content(@page) = render_wiki_content(@page)
%hr .gray-content-block.footer-block
.wiki-last-edit-by .wiki-last-edit-by
Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)} Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
= f.label :title, class: 'control-label' do = f.label :title, class: 'control-label' do
%strong= 'Title *' %strong= 'Title *'
.col-sm-10 .col-sm-10
= f.text_field :title, maxlength: 255, autofocus: true, = f.text_field :title, maxlength: 255, autofocus: true, autocomplete: 'off',
class: 'form-control pad js-gfm-input', required: true class: 'form-control pad js-gfm-input', required: true
- if issuable.is_a?(MergeRequest) - if issuable.is_a?(MergeRequest)
......
...@@ -7,22 +7,31 @@ class RepositoryImportWorker ...@@ -7,22 +7,31 @@ class RepositoryImportWorker
def perform(project_id) def perform(project_id)
project = Project.find(project_id) project = Project.find(project_id)
import_result = gitlab_shell.send(:import_repository, unless project.import_url == Project::UNKNOWN_IMPORT_URL
import_result = gitlab_shell.send(:import_repository,
project.path_with_namespace, project.path_with_namespace,
project.import_url) project.import_url)
return project.import_fail unless import_result return project.import_fail unless import_result
else
unless project.create_repository
return project.import_fail
end
end
data_import_result = if project.import_type == 'github' data_import_result = case project.import_type
Gitlab::GithubImport::Importer.new(project).execute when 'github'
elsif project.import_type == 'gitlab' Gitlab::GithubImport::Importer.new(project).execute
Gitlab::GitlabImport::Importer.new(project).execute when 'gitlab'
elsif project.import_type == 'bitbucket' Gitlab::GitlabImport::Importer.new(project).execute
Gitlab::BitbucketImport::Importer.new(project).execute when 'bitbucket'
elsif project.import_type == 'google_code' Gitlab::BitbucketImport::Importer.new(project).execute
Gitlab::GoogleCodeImport::Importer.new(project).execute when 'google_code'
else Gitlab::GoogleCodeImport::Importer.new(project).execute
true when 'fogbugz'
end Gitlab::FogbugzImport::Importer.new(project).execute
else
true
end
return project.import_fail unless data_import_result return project.import_fail unless data_import_result
Gitlab::BitbucketImport::KeyDeleter.new(project).execute if project.import_type == 'bitbucket' Gitlab::BitbucketImport::KeyDeleter.new(project).execute if project.import_type == 'bitbucket'
......
...@@ -158,7 +158,7 @@ Settings.gitlab.default_projects_features['snippets'] = false if Settings. ...@@ -158,7 +158,7 @@ Settings.gitlab.default_projects_features['snippets'] = false if Settings.
Settings.gitlab.default_projects_features['visibility_level'] = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE) Settings.gitlab.default_projects_features['visibility_level'] = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE)
Settings.gitlab['repository_downloads_path'] = File.absolute_path(Settings.gitlab['repository_downloads_path'] || 'tmp/repositories', Rails.root) Settings.gitlab['repository_downloads_path'] = File.absolute_path(Settings.gitlab['repository_downloads_path'] || 'tmp/repositories', Rails.root)
Settings.gitlab['restricted_signup_domains'] ||= [] Settings.gitlab['restricted_signup_domains'] ||= []
Settings.gitlab['import_sources'] ||= ['github','bitbucket','gitlab','gitorious','google_code','git'] Settings.gitlab['import_sources'] ||= ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git']
# #
# Reply by email # Reply by email
......
# Here until https://github.com/jneen/rouge/pull/297 is merged into Rouge and the gem is updated in GitLab.
module Rouge
module Lexers
class Diff
def self.analyze_text(text)
return 1 if text.start_with?('Index: ')
return 1 if text.start_with?('diff ')
return 0.9 if text.start_with?('--- ')
end
state :root do
rule(/^ .*\n/, Text)
rule(/^---\n/, Text)
rule(/^\+.*\n/, Generic::Inserted)
rule(/^-+.*\n/, Generic::Deleted)
rule(/^!.*\n/, Generic::Strong)
rule(/^@.*\n/, Generic::Subheading)
rule(/^([Ii]ndex|diff).*\n/, Generic::Heading)
rule(/^=.*\n/, Generic::Heading)
rule(/.*\n/, Text)
end
end
end
end
...@@ -2,7 +2,12 @@ ...@@ -2,7 +2,12 @@
require 'gitlab/current_settings' require 'gitlab/current_settings'
include Gitlab::CurrentSettings include Gitlab::CurrentSettings
Settings.gitlab['session_expire_delay'] = current_application_settings.session_expire_delay
# allow it to fail: it may to do so when create_from_defaults is executed before migrations are actually done
begin
Settings.gitlab['session_expire_delay'] = current_application_settings.session_expire_delay
rescue
end
Gitlab::Application.config.session_store( Gitlab::Application.config.session_store(
:redis_store, # Using the cookie_store would enable session replay attacks. :redis_store, # Using the cookie_store would enable session replay attacks.
......
...@@ -99,6 +99,15 @@ Gitlab::Application.routes.draw do ...@@ -99,6 +99,15 @@ Gitlab::Application.routes.draw do
get :new_user_map, path: :user_map get :new_user_map, path: :user_map
post :create_user_map, path: :user_map post :create_user_map, path: :user_map
end end
resource :fogbugz, only: [:create, :new], controller: :fogbugz do
get :status
post :callback
get :jobs
get :new_user_map, path: :user_map
post :create_user_map, path: :user_map
end
end end
# #
...@@ -202,6 +211,8 @@ Gitlab::Application.routes.draw do ...@@ -202,6 +211,8 @@ Gitlab::Application.routes.draw do
resources :services resources :services
end end
resources :labels
root to: 'dashboard#index' root to: 'dashboard#index'
end end
......
class AddTemplateToLabel < ActiveRecord::Migration
def change
add_column :labels, :template, :boolean, default: false
end
end
\ No newline at end of file
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150824002011) do ActiveRecord::Schema.define(version: 20150902001023) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -186,6 +186,7 @@ ActiveRecord::Schema.define(version: 20150824002011) do ...@@ -186,6 +186,7 @@ ActiveRecord::Schema.define(version: 20150824002011) do
t.integer "project_id" t.integer "project_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.boolean "template", default: false
end end
add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree
......
...@@ -299,7 +299,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da ...@@ -299,7 +299,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
GitLab Shell is an SSH access and repository management software developed specially for GitLab. GitLab Shell is an SSH access and repository management software developed specially for GitLab.
# Run the installation task for gitlab-shell (replace `REDIS_URL` if needed): # Run the installation task for gitlab-shell (replace `REDIS_URL` if needed):
sudo -u git -H bundle exec rake gitlab:shell:install[v2.6.3] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:shell:install[v2.6.5] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production
# By default, the gitlab-shell config is generated from your main GitLab config. # By default, the gitlab-shell config is generated from your main GitLab config.
# You can review (and modify) the gitlab-shell config as follows: # You can review (and modify) the gitlab-shell config as follows:
......
...@@ -127,7 +127,7 @@ sudo apt-get install nodejs ...@@ -127,7 +127,7 @@ sudo apt-get install nodejs
```bash ```bash
cd /home/git/gitlab-shell cd /home/git/gitlab-shell
sudo -u git -H git fetch sudo -u git -H git fetch
sudo -u git -H git checkout v2.6.4 sudo -u git -H git checkout v2.6.5
``` ```
## 7. Install libs, migrations, etc. ## 7. Install libs, migrations, etc.
...@@ -162,12 +162,12 @@ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab ...@@ -162,12 +162,12 @@ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
TIP: to see what changed in `gitlab.yml.example` in this release use next command: TIP: to see what changed in `gitlab.yml.example` in this release use next command:
``` ```
git diff 6-0-stable:config/gitlab.yml.example 7.14-stable:config/gitlab.yml.example git diff 6-0-stable:config/gitlab.yml.example 7-14-stable:config/gitlab.yml.example
``` ```
* Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-14-stable/config/gitlab.yml.example but with your settings. * Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-14-stable/config/gitlab.yml.example but with your settings.
* Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-14-stable/config/unicorn.rb.example but with your settings. * Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-14-stable/config/unicorn.rb.example but with your settings.
* Make `/home/git/gitlab-shell/config.yml` the same as https://gitlab.com/gitlab-org/gitlab-shell/blob/v2.6.0/config.yml.example but with your settings. * Make `/home/git/gitlab-shell/config.yml` the same as https://gitlab.com/gitlab-org/gitlab-shell/blob/v2.6.5/config.yml.example but with your settings.
* Copy rack attack middleware config * Copy rack attack middleware config
```bash ```bash
......
...@@ -63,7 +63,7 @@ sudo -u git -H git checkout 7-14-stable-ee ...@@ -63,7 +63,7 @@ sudo -u git -H git checkout 7-14-stable-ee
```bash ```bash
cd /home/git/gitlab-shell cd /home/git/gitlab-shell
sudo -u git -H git fetch sudo -u git -H git fetch
sudo -u git -H git checkout v2.6.4 sudo -u git -H git checkout v2.6.5
``` ```
### 5. Install libs, migrations, etc. ### 5. Install libs, migrations, etc.
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
1. [Bitbucket](import_projects_from_bitbucket.md) 1. [Bitbucket](import_projects_from_bitbucket.md)
2. [GitHub](import_projects_from_github.md) 2. [GitHub](import_projects_from_github.md)
3. [GitLab.com](import_projects_from_gitlab_com.md) 3. [GitLab.com](import_projects_from_gitlab_com.md)
4. [FogBugz](import_projects_from_fogbugz.md)
4. [SVN](migrating_from_svn.md) 4. [SVN](migrating_from_svn.md)
### Note ### Note
......
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