Commit dc24b4d7 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'sidebar-nav' into 'master'

Sidebar navigation

This MR changes layout of the GitLab to sidebar navigation.

Layouts:

- [x] Project layout
- [x] Project settings layout
- [x] Dashboard layout
- [x] Profile layout
- [x] Group layout
- [x] Snippets layout
- [x] Admin layout

Pages:

- [x] Activity pages
- [x] Issue/mr pages
- [x] Issues/merge requests pages

Common:

- [x] Fix tests

See merge request !1329
parents 2dece41b 35eec009
...@@ -12,7 +12,7 @@ class @Activities ...@@ -12,7 +12,7 @@ class @Activities
toggleFilter: (sender) -> toggleFilter: (sender) ->
sender.parent().toggleClass "inactive" sender.parent().toggleClass "active"
event_filters = $.cookie("event_filter") event_filters = $.cookie("event_filter")
filter = sender.attr("id").split("_")[0] filter = sender.attr("id").split("_")[0]
if event_filters if event_filters
......
class @Issue class @Issue
constructor: -> constructor: ->
$('.edit-issue.inline-update input[type="submit"]').hide() $('.edit-issue.inline-update input[type="submit"]').hide()
$(".issue-box .inline-update").on "change", "select", -> $(".context .inline-update").on "change", "select", ->
$(this).submit() $(this).submit()
$(".issue-box .inline-update").on "change", "#issue_assignee_id", -> $(".context .inline-update").on "change", "#issue_assignee_id", ->
$(this).submit() $(this).submit()
if $("a.btn-close").length if $("a.btn-close").length
......
...@@ -26,9 +26,9 @@ class @MergeRequest ...@@ -26,9 +26,9 @@ class @MergeRequest
initContextWidget: -> initContextWidget: ->
$('.edit-merge_request.inline-update input[type="submit"]').hide() $('.edit-merge_request.inline-update input[type="submit"]').hide()
$(".issue-box .inline-update").on "change", "select", -> $(".context .inline-update").on "change", "select", ->
$(this).submit() $(this).submit()
$(".issue-box .inline-update").on "change", "#merge_request_assignee_id", -> $(".context .inline-update").on "change", "#merge_request_assignee_id", ->
$(this).submit() $(this).submit()
initMergeWidget: -> initMergeWidget: ->
......
...@@ -375,7 +375,7 @@ class @Notes ...@@ -375,7 +375,7 @@ class @Notes
### ###
addDiffNote: (e) => addDiffNote: (e) =>
e.preventDefault() e.preventDefault()
link = e.target link = e.currentTarget
form = $(".js-new-note-form") form = $(".js-new-note-form")
row = $(link).closest("tr") row = $(link).closest("tr")
nextRow = row.next() nextRow = row.next()
......
...@@ -46,7 +46,7 @@ class @ContributorsGraph ...@@ -46,7 +46,7 @@ class @ContributorsGraph
class @ContributorsMasterGraph extends ContributorsGraph class @ContributorsMasterGraph extends ContributorsGraph
constructor: (@data) -> constructor: (@data) ->
@width = $('.container').width() - 70 @width = $('.container').width() - 345
@height = 200 @height = 200
@x = null @x = null
@y = null @y = null
...@@ -119,7 +119,7 @@ class @ContributorsMasterGraph extends ContributorsGraph ...@@ -119,7 +119,7 @@ class @ContributorsMasterGraph extends ContributorsGraph
class @ContributorsAuthorGraph extends ContributorsGraph class @ContributorsAuthorGraph extends ContributorsGraph
constructor: (@data) -> constructor: (@data) ->
@width = $('.container').width()/2 - 100 @width = $('.container').width()/2 - 225
@height = 200 @height = 200
@x = null @x = null
@y = null @y = null
......
/** /**
* Issue box: * Issue box for showing Open/Closed state:
* Huge block (one per page) for storing title, descripion and other information.
* Used for Issue#show page, MergeRequest#show page etc * Used for Issue#show page, MergeRequest#show page etc
* *
* CLasses:
* .issue-box - Regular box
*/ */
.issue-box { .issue-box {
color: #555; display: inline-block;
margin:20px 0; padding: 0 10px;
background: $box_bg;
@include box-shadow(0 1px 1px rgba(0, 0, 0, 0.09));
&.issue-box-closed { &.issue-box-closed {
.state { background-color: $bg_danger;
background-color: #F3CECE; color: #FFF;
border-color: $border_danger;
}
.state-label {
background-color: $bg_danger;
color: #FFF;
}
} }
&.issue-box-merged { &.issue-box-merged {
.state { background-color: $bg_primary;
background-color: #B7CEE7; color: #FFF;
border-color: $border_primary;
}
.state-label {
background-color: $bg_primary;
color: #FFF;
}
} }
&.issue-box-open { &.issue-box-open {
.state { background-color: $bg_success;
background-color: #D6F1D7; color: #FFF;
border-color: $bg_success;
}
.state-label {
background-color: $bg_success;
color: #FFF;
}
} }
&.issue-box-expired { &.issue-box-expired {
.state { background: #cea61b;
background-color: #EEE9B3; color: #FFF;
border-color: #faebcc;
}
.state-label {
background: #cea61b;
color: #FFF;
}
}
.control-group {
margin-bottom: 0;
}
.state {
background-color: #f9f9f9;
}
.title {
font-size: 28px;
font-weight: normal;
line-height: 1.5;
margin: 0;
color: #333;
padding: 10px 15px;
}
.context {
border: none;
border-top: 1px solid #eee;
padding: 10px 15px;
// Reset text align for children
.text-right > * { text-align: left; }
@media (max-width: $screen-xs-max) {
// Don't right align on mobile
.text-right { text-align: left; }
.row .col-md-6 {
padding-top: 5px;
}
}
}
.description {
padding: 0 15px 10px 15px;
code {
white-space: pre-wrap;
}
}
.title, .context, .description {
.clearfix {
margin: 0;
}
}
.state-label {
font-size: 14px;
float: left;
font-weight: bold;
padding: 10px 15px;
}
.cross-project-ref {
float: left;
padding: 10px 15px;
}
.creator {
float: right;
padding: 10px 15px;
a {
text-decoration: underline;
}
} }
} }
...@@ -148,6 +148,10 @@ $list-group-active-bg: $bg_primary; ...@@ -148,6 +148,10 @@ $list-group-active-bg: $bg_primary;
color: #666; color: #666;
} }
.nav-compact > li > a {
padding: 6px 12px;
}
.nav-small > li > a { .nav-small > li > a {
padding: 3px 5px; padding: 3px 5px;
font-size: 12px; font-size: 12px;
......
...@@ -4,10 +4,6 @@ html { ...@@ -4,10 +4,6 @@ html {
&.touch .tooltip { display: none !important; } &.touch .tooltip { display: none !important; }
} }
body {
padding-bottom: 20px;
}
.container { .container {
padding-top: 0; padding-top: 0;
z-index: 5; z-index: 5;
......
...@@ -23,20 +23,6 @@ ...@@ -23,20 +23,6 @@
} }
} }
.dashboard {
.dash-filter {
width: 205px;
float: left;
height: inherit;
}
}
@media (max-width: 1200px) {
.dashboard .dash-filter {
width: 140px;
}
}
.dash-sidebar-tabs { .dash-sidebar-tabs {
margin-bottom: 2px; margin-bottom: 2px;
border: none; border: none;
......
...@@ -140,36 +140,6 @@ ...@@ -140,36 +140,6 @@
} }
} }
/**
* Event filter
*
*/
.event_filter {
position: absolute;
width: 40px;
margin-left: -55px;
.filter_icon {
a {
text-align:center;
background: $bg_primary;
margin-bottom: 10px;
float: left;
padding: 9px 6px;
font-size: 18px;
width: 40px;
color: #FFF;
@include border-radius(3px);
}
&.inactive {
a {
color: #DDD;
background: #f9f9f9;
}
}
}
}
/* /*
* Last push widget * Last push widget
...@@ -203,3 +173,7 @@ ...@@ -203,3 +173,7 @@
} }
} }
} }
.event_filter li a {
padding: 5px 10px;
}
...@@ -52,8 +52,6 @@ header { ...@@ -52,8 +52,6 @@ header {
border-width: 0; border-width: 0;
font-size: 18px; font-size: 18px;
.app_logo { margin-left: -15px; }
.title { .title {
@include str-truncated(70%); @include str-truncated(70%);
} }
...@@ -86,6 +84,11 @@ header { ...@@ -86,6 +84,11 @@ header {
z-index: 10; z-index: 10;
.container {
width: 100% !important;
padding-left: 0px;
}
/** /**
* *
* Logo holder * Logo holder
...@@ -232,21 +235,6 @@ header { ...@@ -232,21 +235,6 @@ header {
color: #fff; color: #fff;
} }
} }
.app_logo {
.separator {
margin-left: 0;
margin-right: 0;
}
}
.separator {
float: left;
height: 46px;
width: 2px;
margin-left: 10px;
margin-right: 10px;
}
} }
.search .search-input { .search .search-input {
......
...@@ -162,3 +162,7 @@ form.edit-issue { ...@@ -162,3 +162,7 @@ form.edit-issue {
} }
} }
} }
.issue-title {
margin-top: 0;
}
...@@ -20,16 +20,12 @@ ...@@ -20,16 +20,12 @@
} }
.merge-request .merge-request-tabs{ .merge-request .merge-request-tabs{
border-bottom: 2px solid $border_primary;
margin: 20px 0; margin: 20px 0;
li { li {
a { a {
padding: 15px 40px; padding: 15px 40px;
font-size: 14px; font-size: 14px;
margin-bottom: -2px;
border-bottom: 2px solid $border_primary;
@include border-radius(0px);
} }
} }
} }
......
.main-nav {
background: #f5f5f5;
margin: 20px 0;
margin-top: 0;
padding-top: 4px;
border-bottom: 1px solid #E9E9E9;
ul {
padding: 0;
margin: auto;
.count {
font-weight: normal;
display: inline-block;
height: 15px;
padding: 1px 6px;
height: auto;
font-size: 0.82em;
line-height: 14px;
text-align: center;
color: #777;
background: #eee;
@include border-radius(8px);
}
.label {
background: $hover;
text-shadow: none;
color: $style_color;
}
li {
list-style-type: none;
margin: 0;
display: table-cell;
width: 1%;
&.active {
a {
color: $link_color;
font-weight: bold;
border-bottom: 3px solid $link_color;
}
}
&:hover {
a {
color: $link_hover_color;
border-bottom: 3px solid $link_hover_color;
}
}
}
a {
display: block;
text-align: center;
font-weight: bold;
height: 42px;
line-height: 39px;
color: #777;
text-shadow: 0 1px 1px white;
text-decoration: none;
overflow: hidden;
margin-bottom: -1px;
}
}
@media (max-width: $screen-xs-max) {
font-size: 18px;
margin: 0;
max-height: none;
&, .container {
padding: 0;
border-top: 0;
}
ul {
height: auto;
li {
display: list-item;
width: auto;
padding: 5px 0;
&.active {
background-color: $link_hover_color;
a {
color: #fff;
font-weight: normal;
text-shadow: none;
border: none;
&:after { display: none; }
}
}
}
}
}
}
...@@ -155,19 +155,26 @@ ul.notes { ...@@ -155,19 +155,26 @@ ul.notes {
} }
.add-diff-note { .add-diff-note {
background: image-url("diff_note_add.png") no-repeat left 0; margin-top: -4px;
border: none; @include border-radius(40px);
height: 22px; background: #FFF;
margin-left: -65px; padding: 4px;
font-size: 16px;
color: $link_color;
margin-left: -60px;
position: absolute; position: absolute;
width: 22px;
z-index: 10; z-index: 10;
transition: all 0.2s ease;
// "hide" it by default // "hide" it by default
opacity: 0.0; opacity: 0.0;
filter: alpha(opacity=0); filter: alpha(opacity=0);
&:hover { &:hover {
font-size: 24px;
background: $bg_primary;
color: #FFF;
@include show-add-diff-note; @include show-add-diff-note;
} }
} }
......
.page-with-sidebar {
background: #F5F5F5;
}
.sidebar-wrapper {
overflow-y: auto;
background: #F5F5F5;
}
.content-wrapper {
width: 100%;
padding: 15px;
background: #FFF;
}
.nav-sidebar {
margin: 0;
list-style: none;
&.navbar-collapse {
padding: 0px !important;
}
}
.nav-sidebar li a .count {
float: right;
background: #eee;
padding: 0px 8px;
@include border-radius(6px);
}
.nav-sidebar li {
&.active a {
color: #111;
background: #EEE;
font-weight: bold;
&.no-highlight {
background: none;
}
i {
color: #444;
}
}
}
.nav-sidebar li {
&.separate-item {
border-top: 1px solid #ddd;
padding-top: 10px;
margin-top: 10px;
}
a {
color: #555;
display: block;
text-decoration: none;
padding: 6px 15px;
font-size: 13px;
line-height: 20px;
text-shadow: 0 1px 2px #FFF;
padding-left: 67px;
&:hover {
text-decoration: none;
color: #333;
background: #DDD;
}
&:active, &:focus {
text-decoration: none;
}
i {
width: 20px;
color: #888;
}
}
}
.sidebar-subnav {
margin-left: 0px;
padding-left: 0px;
li {
line-height: 28px;
font-size: 12px;
list-style: none;
a {
padding: 5px 15px;
font-size: 12px;
padding-left: 67px;
}
}
}
@media(min-width:768px) {
.page-with-sidebar {
padding-left: 250px;
}
.sidebar-wrapper {
width: 250px;
position: absolute;
left: 250px;
height: 100%;
margin-left: -250px;
.nav-sidebar {
margin-top: 20px;
position: fixed;
top: 45px;
width: 250px;
}
}
.content-wrapper {
padding: 20px;
border-left: 1px solid #EAEAEA;
}
}
...@@ -37,13 +37,3 @@ ...@@ -37,13 +37,3 @@
margin: 0 8px; margin: 0 8px;
} }
.votes-holder {
float: right;
width: 250px;
@media (max-width: $screen-xs-max) {
width: 100%;
margin-top: 5px;
margin-bottom: 10px;
}
}
...@@ -9,17 +9,15 @@ ...@@ -9,17 +9,15 @@
.navbar-inner { .navbar-inner {
background: #F1F1F1; background: #F1F1F1;
border-bottom: 1px solid #DDD; border-bottom: 1px solid #DDD;
.app_logo {
background-color: #DDD;
}
.nav > li > a { .nav > li > a {
color: $style_color; color: $style_color;
} }
.separator {
background: #F9F9F9;
border-left: 1px solid #DDD;
}
} }
} }
} }
.main-nav {
background: #FFF;
}
} }
...@@ -23,9 +23,8 @@ ...@@ -23,9 +23,8 @@
background-color: #436; background-color: #436;
} }
} }
.separator { .app_logo {
background: #436; background-color: #325;
border-left: 1px solid #659;
} }
.nav > li > a { .nav > li > a {
color: #98C; color: #98C;
......
...@@ -23,9 +23,8 @@ ...@@ -23,9 +23,8 @@
background-color: #272727; background-color: #272727;
} }
} }
.separator { .app_logo {
background: #272727; background-color: #222;
border-left: 1px solid #474747;
} }
} }
} }
......
...@@ -23,9 +23,8 @@ ...@@ -23,9 +23,8 @@
background-color: #373D47; background-color: #373D47;
} }
} }
.separator { .app_logo {
background: #373D47; background-color: #24272D;
border-left: 1px solid #575D67;
} }
.nav > li > a { .nav > li > a {
color: #979DA7; color: #979DA7;
......
...@@ -23,9 +23,8 @@ ...@@ -23,9 +23,8 @@
background-color: #018865; background-color: #018865;
} }
} }
.separator { .app_logo {
background: #018865; background-color: #017855;
border-left: 1px solid #11A885;
} }
.nav > li > a { .nav > li > a {
color: #ADC; color: #ADC;
......
...@@ -239,4 +239,67 @@ class ApplicationController < ActionController::Base ...@@ -239,4 +239,67 @@ class ApplicationController < ActionController::Base
redirect_to profile_path, notice: 'Please complete your profile with email address' and return redirect_to profile_path, notice: 'Please complete your profile with email address' and return
end end
end end
def set_filters_params
params[:sort] ||= 'newest'
params[:scope] = 'all' if params[:scope].blank?
params[:state] = 'opened' if params[:state].blank?
@filter_params = params.dup
if @project
@filter_params[:project_id] = @project.id
elsif @group
@filter_params[:group_id] = @group.id
else
# TODO: this filter ignore issues/mr created in public or
# internal repos where you are not a member. Enable this filter
# or improve current implementation to filter only issues you
# created or assigned or mentioned
#@filter_params[:authorized_only] = true
unless @filter_params[:assignee_id]
@filter_params[:assignee_id] = current_user.id
end
end
@filter_params
end
def set_filter_values(collection)
assignee_id = @filter_params[:assignee_id]
author_id = @filter_params[:author_id]
milestone_id = @filter_params[:milestone_id]
@sort = @filter_params[:sort].try(:humanize)
@assignees = User.where(id: collection.pluck(:assignee_id))
@authors = User.where(id: collection.pluck(:author_id))
@milestones = Milestone.where(id: collection.pluck(:milestone_id))
if assignee_id.present? && !assignee_id.to_i.zero?
@assignee = @assignees.find_by(id: assignee_id)
end
if author_id.present? && !author_id.to_i.zero?
@author = @authors.find_by(id: author_id)
end
if milestone_id.present? && !milestone_id.to_i.zero?
@milestone = @milestones.find_by(id: milestone_id)
end
end
def get_issues_collection
set_filters_params
issues = IssuesFinder.new.execute(current_user, @filter_params)
set_filter_values(issues)
issues
end
def get_merge_requests_collection
set_filters_params
merge_requests = MergeRequestsFinder.new.execute(current_user, @filter_params)
set_filter_values(merge_requests)
merge_requests
end
end end
...@@ -3,8 +3,6 @@ class DashboardController < ApplicationController ...@@ -3,8 +3,6 @@ class DashboardController < ApplicationController
before_filter :load_projects, except: [:projects] before_filter :load_projects, except: [:projects]
before_filter :event_filter, only: :show before_filter :event_filter, only: :show
before_filter :default_filter, only: [:issues, :merge_requests]
def show def show
# Fetch only 30 projects. # Fetch only 30 projects.
...@@ -55,13 +53,13 @@ class DashboardController < ApplicationController ...@@ -55,13 +53,13 @@ class DashboardController < ApplicationController
end end
def merge_requests def merge_requests
@merge_requests = MergeRequestsFinder.new.execute(current_user, params) @merge_requests = get_merge_requests_collection
@merge_requests = @merge_requests.page(params[:page]).per(20) @merge_requests = @merge_requests.page(params[:page]).per(20)
@merge_requests = @merge_requests.preload(:author, :target_project) @merge_requests = @merge_requests.preload(:author, :target_project)
end end
def issues def issues
@issues = IssuesFinder.new.execute(current_user, params) @issues = get_issues_collection
@issues = @issues.page(params[:page]).per(20) @issues = @issues.page(params[:page]).per(20)
@issues = @issues.preload(:author, :project) @issues = @issues.preload(:author, :project)
...@@ -76,10 +74,4 @@ class DashboardController < ApplicationController ...@@ -76,10 +74,4 @@ class DashboardController < ApplicationController
def load_projects def load_projects
@projects = current_user.authorized_projects.sorted_by_activity.non_archived @projects = current_user.authorized_projects.sorted_by_activity.non_archived
end end
def default_filter
params[:scope] = 'assigned-to-me' if params[:scope].blank?
params[:state] = 'opened' if params[:state].blank?
params[:authorized_only] = true
end
end end
...@@ -11,8 +11,6 @@ class GroupsController < ApplicationController ...@@ -11,8 +11,6 @@ class GroupsController < ApplicationController
# Load group projects # Load group projects
before_filter :load_projects, except: [:new, :create, :projects, :edit, :update] before_filter :load_projects, except: [:new, :create, :projects, :edit, :update]
before_filter :default_filter, only: [:issues, :merge_requests]
layout :determine_layout layout :determine_layout
before_filter :set_title, only: [:new, :create] before_filter :set_title, only: [:new, :create]
...@@ -47,13 +45,13 @@ class GroupsController < ApplicationController ...@@ -47,13 +45,13 @@ class GroupsController < ApplicationController
end end
def merge_requests def merge_requests
@merge_requests = MergeRequestsFinder.new.execute(current_user, params) @merge_requests = get_merge_requests_collection
@merge_requests = @merge_requests.page(params[:page]).per(20) @merge_requests = @merge_requests.page(params[:page]).per(20)
@merge_requests = @merge_requests.preload(:author, :target_project) @merge_requests = @merge_requests.preload(:author, :target_project)
end end
def issues def issues
@issues = IssuesFinder.new.execute(current_user, params) @issues = get_issues_collection
@issues = @issues.page(params[:page]).per(20) @issues = @issues.page(params[:page]).per(20)
@issues = @issues.preload(:author, :project) @issues = @issues.preload(:author, :project)
...@@ -148,18 +146,6 @@ class GroupsController < ApplicationController ...@@ -148,18 +146,6 @@ class GroupsController < ApplicationController
end end
end end
def default_filter
if params[:scope].blank?
if current_user
params[:scope] = 'assigned-to-me'
else
params[:scope] = 'all'
end
end
params[:state] = 'opened' if params[:state].blank?
params[:group_id] = @group.id
end
def group_params def group_params
params.require(:group).permit(:name, :description, :path, :avatar) params.require(:group).permit(:name, :description, :path, :avatar)
end end
......
...@@ -29,31 +29,4 @@ class Projects::ApplicationController < ApplicationController ...@@ -29,31 +29,4 @@ class Projects::ApplicationController < ApplicationController
redirect_to project_tree_path(@project, @ref), notice: "This action is not allowed unless you are on top of a branch" redirect_to project_tree_path(@project, @ref), notice: "This action is not allowed unless you are on top of a branch"
end end
end end
def set_filter_variables(collection)
params[:sort] ||= 'newest'
params[:scope] = 'all' if params[:scope].blank?
params[:state] = 'opened' if params[:state].blank?
@sort = params[:sort].humanize
assignee_id = params[:assignee_id]
author_id = params[:author_id]
milestone_id = params[:milestone_id]
if assignee_id.present? && !assignee_id.to_i.zero?
@assignee = @project.team.find(assignee_id)
end
if author_id.present? && !author_id.to_i.zero?
@author = @project.team.find(assignee_id)
end
if milestone_id.present? && !milestone_id.to_i.zero?
@milestone = @project.milestones.find(milestone_id)
end
@assignees = User.where(id: collection.pluck(:assignee_id))
@authors = User.where(id: collection.pluck(:author_id))
end
end end
...@@ -18,9 +18,7 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -18,9 +18,7 @@ class Projects::IssuesController < Projects::ApplicationController
def index def index
terms = params['issue_search'] terms = params['issue_search']
set_filter_variables(@project.issues) @issues = get_issues_collection
@issues = IssuesFinder.new.execute(current_user, params.merge(project_id: @project.id))
@issues = @issues.full_search(terms) if terms.present? @issues = @issues.full_search(terms) if terms.present?
@issues = @issues.page(params[:page]).per(20) @issues = @issues.page(params[:page]).per(20)
......
...@@ -17,9 +17,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -17,9 +17,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort] before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort]
def index def index
set_filter_variables(@project.merge_requests) @merge_requests = get_merge_requests_collection
@merge_requests = MergeRequestsFinder.new.execute(current_user, params.merge(project_id: @project.id))
@merge_requests = @merge_requests.page(params[:page]).per(20) @merge_requests = @merge_requests.page(params[:page]).per(20)
end end
......
...@@ -275,4 +275,22 @@ module ApplicationHelper ...@@ -275,4 +275,22 @@ module ApplicationHelper
def promo_url def promo_url
'https://' + promo_host 'https://' + promo_host
end end
def page_filter_path(options={})
exist_opts = {
state: params[:state],
scope: params[:scope],
label_name: params[:label_name],
milestone_id: params[:milestone_id],
assignee_id: params[:assignee_id],
author_id: params[:author_id],
sort: params[:sort],
}
options = exist_opts.merge(options)
path = request.path
path << "?#{options.to_param}"
path
end
end end
module DashboardHelper module DashboardHelper
def filter_path(entity, options={})
exist_opts = {
state: params[:state],
scope: params[:scope],
project_id: params[:project_id],
}
options = exist_opts.merge(options)
path = request.path
path << "?#{options.to_param}"
path
end
def entities_per_project(project, entity) def entities_per_project(project, entity)
case entity.to_sym case entity.to_sym
when :issue then @issues.where(project_id: project.id) when :issue then @issues.where(project_id: project.id)
......
...@@ -21,15 +21,14 @@ module EventsHelper ...@@ -21,15 +21,14 @@ module EventsHelper
def event_filter_link(key, tooltip) def event_filter_link(key, tooltip)
key = key.to_s key = key.to_s
inactive = if @event_filter.active? key active = if @event_filter.active? key
nil 'active'
else end
'inactive'
end
content_tag :div, class: "filter_icon #{inactive}" do content_tag :li, class: "filter_icon #{active}" do
link_to request.path, class: 'has_tooltip event_filter_link', id: "#{key}_event_filter", 'data-original-title' => tooltip do link_to request.path, class: 'has_tooltip event_filter_link', id: "#{key}_event_filter", 'data-original-title' => tooltip do
content_tag :i, nil, class: icon_for_event[key] content_tag(:i, nil, class: icon_for_event[key]) +
content_tag(:span, ' ' + tooltip)
end end
end end
end end
......
...@@ -6,7 +6,7 @@ module GroupsHelper ...@@ -6,7 +6,7 @@ module GroupsHelper
def leave_group_message(group) def leave_group_message(group)
"Are you sure you want to leave \"#{group}\" group?" "Are you sure you want to leave \"#{group}\" group?"
end end
def should_user_see_group_roles?(user, group) def should_user_see_group_roles?(user, group)
if user if user
user.is_admin? || group.members.exists?(user_id: user.id) user.is_admin? || group.members.exists?(user_id: user.id)
...@@ -44,4 +44,12 @@ module GroupsHelper ...@@ -44,4 +44,12 @@ module GroupsHelper
path << "?#{options.to_param}" path << "?#{options.to_param}"
path path
end end
def group_settings_page?
if current_controller?('groups')
current_action?('edit') || current_action?('projects')
else
false
end
end
end end
...@@ -52,8 +52,11 @@ module NotesHelper ...@@ -52,8 +52,11 @@ module NotesHelper
discussion_id: discussion_id discussion_id: discussion_id
} }
button_tag '', class: 'btn add-diff-note js-add-diff-note-button', button_tag(class: 'btn add-diff-note js-add-diff-note-button',
data: data, title: 'Add a comment to this line' data: data,
title: 'Add a comment to this line') do
content_tag :i, nil, class: 'fa fa-comment-o'
end
end end
def link_to_reply_diff(note) def link_to_reply_diff(note)
......
...@@ -68,48 +68,6 @@ module ProjectsHelper ...@@ -68,48 +68,6 @@ module ProjectsHelper
project_nav_tabs.include? name project_nav_tabs.include? name
end end
def selected_label?(label_name)
params[:label_name].to_s.split(',').include?(label_name)
end
def labels_filter_path(label_name)
label_name =
if selected_label?(label_name)
params[:label_name].split(',').reject { |l| l == label_name }.join(',')
elsif params[:label_name].present?
"#{params[:label_name]},#{label_name}"
else
label_name
end
project_filter_path(label_name: label_name)
end
def label_filter_class(label_name)
if selected_label?(label_name)
'label-filter-item active'
else
'label-filter-item light'
end
end
def project_filter_path(options={})
exist_opts = {
state: params[:state],
scope: params[:scope],
label_name: params[:label_name],
milestone_id: params[:milestone_id],
assignee_id: params[:assignee_id],
sort: params[:sort],
}
options = exist_opts.merge(options)
path = request.path
path << "?#{options.to_param}"
path
end
def project_active_milestones def project_active_milestones
@project.milestones.active.order("due_date, title ASC") @project.milestones.active.order("due_date, title ASC")
end end
......
.panel.panel-default .panel.panel-default
.panel-heading.clearfix .panel-heading.clearfix
= search_field_tag :filter_group, nil, placeholder: 'Filter by name', class: 'dash-filter form-control' .input-group
- if current_user.can_create_group? = search_field_tag :filter_group, nil, placeholder: 'Filter by name', class: 'dash-filter form-control'
= link_to new_group_path, class: "btn btn-new pull-right" do - if current_user.can_create_group?
%i.fa.fa-plus .input-group-addon
New group = link_to new_group_path, class: "" do
%strong New group
%ul.well-list.dash-list %ul.well-list.dash-list
- groups.each do |group| - groups.each do |group|
%li.group-row %li.group-row
......
.panel.panel-default .panel.panel-default
.panel-heading.clearfix .panel-heading.clearfix
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'dash-filter form-control' .input-group
- if current_user.can_create_project? = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'dash-filter form-control'
= link_to new_project_path, class: "btn btn-new pull-right" do - if current_user.can_create_project?
%i.fa.fa-plus .input-group-addon
New project = link_to new_project_path, class: "" do
%strong New project
%ul.well-list.dash-list %ul.well-list.dash-list
- projects.each do |project| - projects.each do |project|
......
...@@ -15,11 +15,4 @@ ...@@ -15,11 +15,4 @@
= render "groups", groups: @groups = render "groups", groups: @groups
.prepend-top-20 .prepend-top-20
%span.rss-icon = render 'shared/promo'
= link_to dashboard_path(:atom, { private_token: current_user.private_token }) do
%strong
%i.fa.fa-rss
News Feed
%hr
= render 'shared/promo'
...@@ -5,10 +5,6 @@ ...@@ -5,10 +5,6 @@
List all issues from all projects you have access to. List all issues from all projects you have access to.
%hr %hr
.row .append-bottom-20
.fixed.sidebar-expand-button.hidden-lg.hidden-md = render 'shared/issuable_filter'
%i.fa.fa-list.fa-2x = render 'shared/issues'
.col-md-3.responsive-side
= render 'shared/filter', entity: 'issue'
.col-md-9
= render 'shared/issues'
...@@ -5,10 +5,6 @@ ...@@ -5,10 +5,6 @@
%p.light %p.light
List all merge requests from all projects you have access to. List all merge requests from all projects you have access to.
%hr %hr
.row .append-bottom-20
.fixed.sidebar-expand-button.hidden-lg.hidden-md = render 'shared/issuable_filter'
%i.fa.fa-list.fa-2x = render 'shared/merge_requests'
.col-md-3.responsive-side
= render 'shared/filter', entity: 'merge_request'
.col-md-9
= render 'shared/merge_requests'
%ul.nav.nav-pills.nav-stacked.nav-stacked-menu %ul.sidebar-subnav
= nav_link(path: 'groups#edit') do = nav_link(path: 'groups#edit') do
= link_to edit_group_path(@group) do = link_to edit_group_path(@group) do
%i.fa.fa-pencil-square-o %i.fa.fa-pencil-square-o
......
.row .panel.panel-default
.col-md-2 .panel-heading
= render 'settings_nav' %strong= @group.name
.col-md-10 group settings:
.panel.panel-default .panel-body
.panel-heading = form_for @group, html: { multipart: true, class: "form-horizontal" }, authenticity_token: true do |f|
%strong= @group.name - if @group.errors.any?
group settings: .alert.alert-danger
.panel-body %span= @group.errors.full_messages.first
= form_for @group, html: { multipart: true, class: "form-horizontal" }, authenticity_token: true do |f| = render 'shared/group_form', f: f
- if @group.errors.any?
.alert.alert-danger
%span= @group.errors.full_messages.first
= render 'shared/group_form', f: f
.form-group .form-group
.col-sm-2 .col-sm-2
.col-sm-10 .col-sm-10
= image_tag group_icon(@group.to_param), alt: '', class: 'avatar s160' = image_tag group_icon(@group.to_param), alt: '', class: 'avatar s160'
%p.light %p.light
- if @group.avatar? - if @group.avatar?
You can change your group avatar here You can change your group avatar here
- else - else
You can upload a group avatar here You can upload a group avatar here
= render 'shared/choose_group_avatar_button', f: f = render 'shared/choose_group_avatar_button', f: f
- if @group.avatar? - if @group.avatar?
%hr %hr
= link_to 'Remove avatar', group_avatar_path(@group.to_param), data: { confirm: "Group avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar" = link_to 'Remove avatar', group_avatar_path(@group.to_param), data: { confirm: "Group avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar"
.form-actions .form-actions
= f.submit 'Save group', class: "btn btn-save" = f.submit 'Save group', class: "btn btn-save"
.panel.panel-danger .panel.panel-danger
.panel-heading Remove group .panel-heading Remove group
.panel-body .panel-body
%p %p
Removing group will cause all child projects and resources to be removed. Removing group will cause all child projects and resources to be removed.
%br %br
%strong Removed group can not be restored! %strong Removed group can not be restored!
= link_to 'Remove Group', @group, data: {confirm: 'Removed group can not be restored! Are you sure?'}, method: :delete, class: "btn btn-remove" = link_to 'Remove Group', @group, data: {confirm: 'Removed group can not be restored! Are you sure?'}, method: :delete, class: "btn btn-remove"
...@@ -9,10 +9,6 @@ ...@@ -9,10 +9,6 @@
To see all issues you should visit #{link_to 'dashboard', issues_dashboard_path} page. To see all issues you should visit #{link_to 'dashboard', issues_dashboard_path} page.
%hr %hr
.row .append-bottom-20
.fixed.sidebar-expand-button.hidden-lg.hidden-md = render 'shared/issuable_filter'
%i.fa.fa-list.fa-2x = render 'shared/issues'
.col-md-3.responsive-side
= render 'shared/filter', entity: 'issue'
.col-md-9
= render 'shared/issues'
...@@ -8,10 +8,6 @@ ...@@ -8,10 +8,6 @@
- if current_user - if current_user
To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page. To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page.
%hr %hr
.row .append-bottom-20
.fixed.sidebar-expand-button.hidden-lg.hidden-md = render 'shared/issuable_filter'
%i.fa.fa-list.fa-2x = render 'shared/merge_requests'
.col-md-3.responsive-side
= render 'shared/filter', entity: 'merge_request'
.col-md-9
= render 'shared/merge_requests'
.row .panel.panel-default
.col-md-2 .panel-heading
= render 'settings_nav' %strong= @group.name
.col-md-10 projects:
.panel.panel-default - if can? current_user, :manage_group, @group
.panel-heading .panel-head-actions
%strong= @group.name = link_to new_project_path(namespace_id: @group.id), class: "btn btn-new" do
projects: %i.fa.fa-plus
- if can? current_user, :manage_group, @group New Project
.panel-head-actions %ul.well-list
= link_to new_project_path(namespace_id: @group.id), class: "btn btn-new" do - @projects.each do |project|
%i.fa.fa-plus %li
New Project .list-item-name
%ul.well-list = visibility_level_icon(project.visibility_level)
- @projects.each do |project| %strong= link_to project.name_with_namespace, project
%li %span.label.label-gray
.list-item-name = repository_size(project)
= visibility_level_icon(project.visibility_level) .pull-right
%strong= link_to project.name_with_namespace, project = link_to 'Members', project_team_index_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small"
%span.label.label-gray = link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small"
= repository_size(project) = link_to 'Remove', project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-small btn-remove"
.pull-right - if @projects.blank?
= link_to 'Members', project_team_index_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small" .nothing-here-block This group has no projects yet
= link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small"
= link_to 'Remove', project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-small btn-remove"
- if @projects.blank?
.nothing-here-block This group has no projects yet
= paginate @projects, theme: "gitlab" = paginate @projects, theme: "gitlab"
.dashboard .dashboard
%section.activities.col-md-8.hidden-sm.hidden-xs %div
- if current_user = image_tag group_icon(@group.path), class: "avatar s90"
= render "events/event_last_push", event: @last_push .clearfix
= link_to dashboard_path, class: 'btn btn-tiny' do %h2
&larr; To dashboard = @group.name
&nbsp; - if @group.description.present?
%span.cgray %p
Currently you are only seeing events from the = escaped_autolink(@group.description)
= @group.name %hr
group .row
%hr %section.activities.col-md-8.hidden-sm.hidden-xs
= render 'shared/event_filter' - if current_user
- if @events.any? = render "events/event_last_push", event: @last_push
.content_list = render 'shared/event_filter'
- else - if @events.any?
.nothing-here-block Project activity will be displayed here .content_list
= spinner - else
%aside.side.col-md-4 .nothing-here-block Project activity will be displayed here
.light-well.append-bottom-20 = spinner
= image_tag group_icon(@group.path), class: "avatar s90" %aside.side.col-md-4
.clearfix.light = render "projects", projects: @projects
%h3.page-title
= @group.name
- if @group.description.present?
%p
= escaped_autolink(@group.description)
= render "projects", projects: @projects
- if current_user
.prepend-top-20
= link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed" do
%strong
%i.fa.fa-rss
News Feed
%hr
= render 'shared/promo'
...@@ -2,10 +2,8 @@ ...@@ -2,10 +2,8 @@
.navbar-inner .navbar-inner
.container .container
%div.app_logo %div.app_logo
%span.separator
= link_to root_path, class: "home has_bottom_tooltip", title: "Dashboard" do = link_to root_path, class: "home has_bottom_tooltip", title: "Dashboard" do
%h1 GITLAB %h1 GITLAB
%span.separator
%h1.title= title %h1.title= title
%button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"} %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"}
......
- if defined?(sidebar)
.page-with-sidebar
.sidebar-wrapper
= render(sidebar)
.content-wrapper
.container-fluid
.content
= render "layouts/flash"
.clearfix
= yield
- else
.container.navless-container
.content
= yield
= yield :embedded_scripts
...@@ -4,10 +4,4 @@ ...@@ -4,10 +4,4 @@
%body{class: "#{app_theme} #{theme_type} admin", :'data-page' => body_data_page} %body{class: "#{app_theme} #{theme_type} admin", :'data-page' => body_data_page}
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/head_panel", title: "Admin area" = render "layouts/head_panel", title: "Admin area"
%nav.main-nav.navbar-collapse.collapse = render 'layouts/page', sidebar: 'layouts/nav/admin'
.container= render 'layouts/nav/admin'
.container
.content
= render "layouts/flash"
= yield
= yield :embedded_scripts
...@@ -4,9 +4,4 @@ ...@@ -4,9 +4,4 @@
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page } %body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page }
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/head_panel", title: "Dashboard" = render "layouts/head_panel", title: "Dashboard"
%nav.main-nav.navbar-collapse.collapse = render 'layouts/page', sidebar: 'layouts/nav/dashboard'
.container= render 'layouts/nav/dashboard'
.container
.content
= render "layouts/flash"
= yield
...@@ -3,10 +3,5 @@ ...@@ -3,10 +3,5 @@
= render "layouts/head", title: group_head_title = render "layouts/head", title: group_head_title
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page} %body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page}
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/head_panel", title: "group: #{@group.name}" = render "layouts/head_panel", title: @group.name
%nav.main-nav.navbar-collapse.collapse = render 'layouts/page', sidebar: 'layouts/nav/group'
.container= render 'layouts/nav/group'
.container
.content
= render "layouts/flash"
= yield
%ul %ul.nav-sidebar.navbar-collapse.collapse
= nav_link(controller: :dashboard, html_options: {class: 'home'}) do = nav_link(controller: :dashboard, html_options: {class: 'home'}) do
= link_to admin_root_path, title: "Stats" do = link_to admin_root_path, title: "Stats" do
Overview Overview
......
%ul %ul.nav.nav-sidebar.navbar-collapse.collapse
= nav_link(path: 'dashboard#show', html_options: {class: 'home'}) do = nav_link(path: 'dashboard#show', html_options: {class: 'home'}) do
= link_to root_path, title: 'Home', class: 'shortcuts-activity' do = link_to root_path, title: 'Home', class: 'shortcuts-activity' do
%i.fa.fa-dashboard
Activity Activity
= nav_link(path: 'dashboard#projects') do = nav_link(path: 'dashboard#projects') do
= link_to projects_dashboard_path, class: 'shortcuts-projects' do = link_to projects_dashboard_path, class: 'shortcuts-projects' do
%i.fa.fa-cube
Projects Projects
= nav_link(path: 'dashboard#issues') do = nav_link(path: 'dashboard#issues') do
= link_to issues_dashboard_path, class: 'shortcuts-issues' do = link_to issues_dashboard_path, class: 'shortcuts-issues' do
%i.fa.fa-exclamation-circle
Issues Issues
%span.count= current_user.assigned_issues.opened.count %span.count= current_user.assigned_issues.opened.count
= nav_link(path: 'dashboard#merge_requests') do = nav_link(path: 'dashboard#merge_requests') do
= link_to merge_requests_dashboard_path, class: 'shortcuts-merge_requests' do = link_to merge_requests_dashboard_path, class: 'shortcuts-merge_requests' do
%i.fa.fa-tasks
Merge Requests Merge Requests
%span.count= current_user.assigned_merge_requests.opened.count %span.count= current_user.assigned_merge_requests.opened.count
= nav_link(controller: :help) do = nav_link(controller: :help) do
= link_to "Help", help_path = link_to help_path do
%i.fa.fa-question-circle
Help
%ul %ul.nav.nav-sidebar.navbar-collapse.collapse
= nav_link(path: 'groups#show', html_options: {class: 'home'}) do = nav_link(path: 'groups#show', html_options: {class: 'home'}) do
= link_to group_path(@group), title: "Home" do = link_to group_path(@group), title: "Home" do
%i.fa.fa-dashboard
Activity Activity
= nav_link(controller: [:group, :milestones]) do - if current_user
= link_to group_milestones_path(@group) do = nav_link(controller: [:group, :milestones]) do
Milestones = link_to group_milestones_path(@group) do
%i.fa.fa-clock-o
Milestones
= nav_link(path: 'groups#issues') do = nav_link(path: 'groups#issues') do
= link_to issues_group_path(@group) do = link_to issues_group_path(@group) do
%i.fa.fa-exclamation-circle
Issues Issues
- if current_user - if current_user
%span.count= current_user.assigned_issues.opened.of_group(@group).count %span.count= Issue.opened.of_group(@group).count
= nav_link(path: 'groups#merge_requests') do = nav_link(path: 'groups#merge_requests') do
= link_to merge_requests_group_path(@group) do = link_to merge_requests_group_path(@group) do
%i.fa.fa-tasks
Merge Requests Merge Requests
- if current_user - if current_user
%span.count= current_user.cared_merge_requests.opened.of_group(@group).count %span.count= MergeRequest.opened.of_group(@group).count
= nav_link(path: 'groups#members') do = nav_link(path: 'groups#members') do
= link_to "Members", members_group_path(@group) = link_to members_group_path(@group) do
%i.fa.fa-users
Members
- if can?(current_user, :manage_group, @group) - if can?(current_user, :manage_group, @group)
= nav_link(path: 'groups#edit') do = nav_link(html_options: { class: "#{"active" if group_settings_page?} separate-item" }) do
= link_to edit_group_path(@group), class: "tab " do = link_to edit_group_path(@group), class: "tab no-highlight" do
%i.fa.fa-cogs
Settings Settings
%i.fa.fa-angle-down
- if group_settings_page?
= render 'groups/settings_nav'
%ul %ul.nav-sidebar.navbar-collapse.collapse
= nav_link(path: 'profiles#show', html_options: {class: 'home'}) do = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
= link_to profile_path, title: "Profile" do = link_to profile_path, title: "Profile" do
%i.fa.fa-user
Profile Profile
= nav_link(controller: :accounts) do = nav_link(controller: :accounts) do
= link_to "Account", profile_account_path = link_to profile_account_path do
%i.fa.fa-gear
Account
= nav_link(controller: :emails) do = nav_link(controller: :emails) do
= link_to profile_emails_path do = link_to profile_emails_path do
%i.fa.fa-envelope-o
Emails Emails
%span.count= current_user.emails.count + 1 %span.count= current_user.emails.count + 1
- unless current_user.ldap_user? - unless current_user.ldap_user?
= nav_link(controller: :passwords) do = nav_link(controller: :passwords) do
= link_to "Password", edit_profile_password_path = link_to edit_profile_password_path do
%i.fa.fa-lock
Password
= nav_link(controller: :notifications) do = nav_link(controller: :notifications) do
= link_to "Notifications", profile_notifications_path = link_to profile_notifications_path do
%i.fa.fa-inbox
Notifications
= nav_link(controller: :keys) do = nav_link(controller: :keys) do
= link_to profile_keys_path do = link_to profile_keys_path do
%i.fa.fa-key
SSH Keys SSH Keys
%span.count= current_user.keys.count %span.count= current_user.keys.count
= nav_link(path: 'profiles#design') do = nav_link(path: 'profiles#design') do
= link_to "Design", design_profile_path = link_to design_profile_path do
%i.fa.fa-image
Design
= nav_link(controller: :groups) do = nav_link(controller: :groups) do
= link_to "Groups", profile_groups_path = link_to profile_groups_path do
%i.fa.fa-group
Groups
= nav_link(path: 'profiles#history') do = nav_link(path: 'profiles#history') do
= link_to "History", history_profile_path = link_to history_profile_path do
%i.fa.fa-history
History
%ul.project-navigation %ul.project-navigation.nav.nav-sidebar.navbar-collapse.collapse
= nav_link(path: 'projects#show', html_options: {class: "home"}) do = nav_link(path: 'projects#show', html_options: {class: "home"}) do
= link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do = link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do
%i.fa.fa-dashboard
Project Project
- if project_nav_tab? :files - if project_nav_tab? :files
= nav_link(controller: %w(tree blob blame edit_tree new_tree)) do = nav_link(controller: %w(tree blob blame edit_tree new_tree)) do
= link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref), class: 'shortcuts-tree' = link_to project_tree_path(@project, @ref || @repository.root_ref), class: 'shortcuts-tree' do
%i.fa.fa-files-o
Files
- if project_nav_tab? :commits - if project_nav_tab? :commits
= nav_link(controller: %w(commit commits compare repositories tags branches)) do = nav_link(controller: %w(commit commits compare repositories tags branches)) do
= link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref), class: 'shortcuts-commits' = link_to project_commits_path(@project, @ref || @repository.root_ref), class: 'shortcuts-commits' do
%i.fa.fa-history
Commits
- if project_nav_tab? :network - if project_nav_tab? :network
= nav_link(controller: %w(network)) do = nav_link(controller: %w(network)) do
= link_to "Network", project_network_path(@project, @ref || @repository.root_ref), class: 'shortcuts-network' = link_to project_network_path(@project, @ref || @repository.root_ref), class: 'shortcuts-network' do
%i.fa.fa-code-fork
Network
- if project_nav_tab? :graphs - if project_nav_tab? :graphs
= nav_link(controller: %w(graphs)) do = nav_link(controller: %w(graphs)) do
= link_to "Graphs", project_graph_path(@project, @ref || @repository.root_ref), class: 'shortcuts-graphs' = link_to project_graph_path(@project, @ref || @repository.root_ref), class: 'shortcuts-graphs' do
%i.fa.fa-area-chart
Graphs
- if project_nav_tab? :issues - if project_nav_tab? :issues
= nav_link(controller: %w(issues milestones labels)) do = nav_link(controller: %w(issues milestones labels)) do
= link_to url_for_project_issues, class: 'shortcuts-issues' do = link_to url_for_project_issues, class: 'shortcuts-issues' do
%i.fa.fa-exclamation-circle
Issues Issues
- if @project.used_default_issues_tracker? - if @project.used_default_issues_tracker?
%span.count.issue_counter= @project.issues.opened.count %span.count.issue_counter= @project.issues.opened.count
...@@ -28,18 +39,28 @@ ...@@ -28,18 +39,28 @@
- if project_nav_tab? :merge_requests - if project_nav_tab? :merge_requests
= nav_link(controller: :merge_requests) do = nav_link(controller: :merge_requests) do
= link_to project_merge_requests_path(@project), class: 'shortcuts-merge_requests' do = link_to project_merge_requests_path(@project), class: 'shortcuts-merge_requests' do
%i.fa.fa-tasks
Merge Requests Merge Requests
%span.count.merge_counter= @project.merge_requests.opened.count %span.count.merge_counter= @project.merge_requests.opened.count
- if project_nav_tab? :wiki - if project_nav_tab? :wiki
= nav_link(controller: :wikis) do = nav_link(controller: :wikis) do
= link_to 'Wiki', project_wiki_path(@project, :home), class: 'shortcuts-wiki' = link_to project_wiki_path(@project, :home), class: 'shortcuts-wiki' do
%i.fa.fa-book
Wiki
- if project_nav_tab? :snippets - if project_nav_tab? :snippets
= nav_link(controller: :snippets) do = nav_link(controller: :snippets) do
= link_to 'Snippets', project_snippets_path(@project), class: 'shortcuts-snippets' = link_to project_snippets_path(@project), class: 'shortcuts-snippets' do
%i.fa.fa-file-text-o
Snippets
- if project_nav_tab? :settings - if project_nav_tab? :settings
= nav_link(html_options: {class: "#{project_tab_class}"}) do = nav_link(html_options: {class: "#{project_tab_class} separate-item"}) do
= link_to edit_project_path(@project), class: "stat-tab tab " do = link_to edit_project_path(@project), class: "stat-tab tab no-highlight" do
%i.fa.fa-cogs
Settings Settings
%i.fa.fa-angle-down
- if @project_settings_nav
= render 'projects/settings_nav'
...@@ -4,9 +4,4 @@ ...@@ -4,9 +4,4 @@
%body{class: "#{app_theme} #{theme_type} profile", :'data-page' => body_data_page} %body{class: "#{app_theme} #{theme_type} profile", :'data-page' => body_data_page}
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/head_panel", title: "Profile" = render "layouts/head_panel", title: "Profile"
%nav.main-nav.navbar-collapse.collapse = render 'layouts/page', sidebar: 'layouts/nav/profile'
.container= render 'layouts/nav/profile'
.container
.content
= render "layouts/flash"
= yield
...@@ -7,13 +7,6 @@ ...@@ -7,13 +7,6 @@
= render "layouts/init_auto_complete" = render "layouts/init_auto_complete"
- if can?(current_user, :download_code, @project) - if can?(current_user, :download_code, @project)
= render 'shared/no_ssh' = render 'shared/no_ssh'
%nav.main-nav.navbar-collapse.collapse
.container= render 'layouts/nav/project' - @project_settings_nav = true
.container = render 'layouts/page', sidebar: 'layouts/nav/project'
.content
= render "layouts/flash"
.row
.col-md-2
= render "projects/settings_nav"
.col-md-10
= yield
...@@ -7,10 +7,4 @@ ...@@ -7,10 +7,4 @@
= render "layouts/init_auto_complete" = render "layouts/init_auto_complete"
- if can?(current_user, :download_code, @project) - if can?(current_user, :download_code, @project)
= render 'shared/no_ssh' = render 'shared/no_ssh'
%nav.main-nav.navbar-collapse.collapse = render 'layouts/page', sidebar: 'layouts/nav/project'
.container= render 'layouts/nav/project'
.container
.content
= render "layouts/flash"
= yield
= yield :embedded_scripts
...@@ -4,7 +4,4 @@ ...@@ -4,7 +4,4 @@
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page} %body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page}
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/public_head_panel", title: "group: #{@group.name}" = render "layouts/public_head_panel", title: "group: #{@group.name}"
%nav.main-nav.navbar-collapse.collapse = render 'layouts/page', sidebar: 'layouts/nav/group'
.container= render 'layouts/nav/group'
.container
.content= yield
...@@ -4,7 +4,4 @@ ...@@ -4,7 +4,4 @@
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page} %body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page}
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/public_head_panel", title: project_title(@project) = render "layouts/public_head_panel", title: project_title(@project)
%nav.main-nav.navbar-collapse.collapse = render 'layouts/page', sidebar: 'layouts/nav/project'
.container= render 'layouts/nav/project'
.container
.content= yield
...@@ -4,5 +4,4 @@ ...@@ -4,5 +4,4 @@
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page} %body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page}
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/public_head_panel", title: @title = render "layouts/public_head_panel", title: @title
.container.navless-container = render 'layouts/page'
.content= yield
...@@ -2,15 +2,22 @@ ...@@ -2,15 +2,22 @@
- if project_nav_tab? :issues - if project_nav_tab? :issues
= nav_link(controller: :issues) do = nav_link(controller: :issues) do
= link_to project_issues_path(@project), class: "tab" do = link_to project_issues_path(@project), class: "tab" do
%i.fa.fa-exclamation-circle
Issues Issues
- if project_nav_tab? :merge_requests - if project_nav_tab? :merge_requests
= nav_link(controller: :merge_requests) do = nav_link(controller: :merge_requests) do
= link_to project_merge_requests_path(@project), class: "tab" do = link_to project_merge_requests_path(@project), class: "tab" do
%i.fa.fa-tasks
Merge Requests Merge Requests
= nav_link(controller: :milestones) do = nav_link(controller: :milestones) do
= link_to 'Milestones', project_milestones_path(@project), class: "tab" = link_to project_milestones_path(@project), class: "tab" do
%i.fa.fa-clock-o
Milestones
= nav_link(controller: :labels) do = nav_link(controller: :labels) do
= link_to 'Labels', project_labels_path(@project), class: "tab" = link_to project_labels_path(@project), class: "tab" do
%i.fa.fa-tags
Labels
- if current_controller?(:milestones) - if current_controller?(:milestones)
%li.pull-right %li.pull-right
......
%ul.nav.nav-pills.nav-stacked.nav-stacked-menu.append-bottom-20.project-settings-nav %ul.project-settings-nav.sidebar-subnav
= nav_link(path: 'projects#edit') do = nav_link(path: 'projects#edit') do
= link_to edit_project_path(@project), class: "stat-tab tab " do = link_to edit_project_path(@project), class: "stat-tab tab " do
%i.fa.fa-pencil-square-o %i.fa.fa-pencil-square-o
......
= form_for [@project, @issue], remote: true, html: {class: 'edit-issue inline-update'} do |f| = form_for [@project, @issue], remote: true, html: {class: 'edit-issue inline-update'} do |f|
.row %div.prepend-top-20
.col-sm-6 %p
%strong.append-right-10 Assignee:
Assignee:
- if can?(current_user, :modify_issue, @issue) - if can?(current_user, :modify_issue, @issue)
= project_users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @issue.assignee_id) = project_users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @issue.assignee_id)
- elsif issue.assignee - elsif issue.assignee
= link_to_member(@project, @issue.assignee) = link_to_member(@project, @issue.assignee)
- else - else
None None
.col-sm-6.text-right %div.prepend-top-20
%strong.append-right-10 %p
Milestone: Milestone:
- if can?(current_user, :modify_issue, @issue) - if can?(current_user, :modify_issue, @issue)
= f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'}) = f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :issue_context = hidden_field_tag :issue_context
= f.submit class: 'btn' = f.submit class: 'btn'
- elsif issue.milestone - elsif issue.milestone
= link_to project_milestone_path(@project, @issue.milestone) do = link_to project_milestone_path(@project, @issue.milestone) do
= @issue.milestone.title = @issue.milestone.title
- else - else
None None
.append-bottom-10 .append-bottom-10
.check-all-holder .check-all-holder
= check_box_tag "check_all_issues", nil, false, class: "check_all_issues left" = check_box_tag "check_all_issues", nil, false, class: "check_all_issues left"
= render 'projects/issuable_filter' = render 'shared/issuable_filter'
.clearfix .clearfix
.issues_bulk_update.hide .issues_bulk_update.hide
......
= render "projects/issues_nav" = render "projects/issues_nav"
.row
.fixed.fixed.sidebar-expand-button.hidden-lg.hidden-md.hidden-xs .issues-holder
%i.fa.fa-list.fa-2x = render "issues"
.col-md-3.responsive-side
= render 'shared/project_filter', project_entities_path: project_issues_path(@project),
labels: true, redirect: 'issues', entity: 'issue'
.col-md-9.issues-holder
= render "issues"
%h3.page-title %h3.page-title
Issue ##{@issue.iid} .issue-box{ class: issue_box_class(@issue) }
%span.pull-right.issue-btn-group
- if can?(current_user, :write_issue, @project)
= link_to new_project_issue_path(@project), class: "btn btn-grouped", title: "New Issue", id: "new_issue_link" do
%i.fa.fa-plus
New Issue
- if can?(current_user, :modify_issue, @issue)
- if @issue.closed?
= link_to 'Reopen', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-grouped btn-reopen"
- else
= link_to 'Close', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close", title: "Close Issue"
= link_to edit_project_issue_path(@project, @issue), class: "btn btn-grouped" do
%i.fa.fa-pencil-square-o
Edit
.clearfix
.votes-holder
#votes= render 'votes/votes_block', votable: @issue
.back-link
= link_to project_issues_path(@project) do
&larr; To issues list
%span.milestone-nav-link
- if @issue.milestone
|
%span.light Milestone
= link_to project_milestone_path(@project, @issue.milestone) do
= @issue.milestone.title
.issue-box{ class: issue_box_class(@issue) }
.state.clearfix
.state-label
- if @issue.closed?
Closed
- else
Open
.cross-project-ref
%i.fa.fa-link.has_tooltip{:"data-original-title" => 'Cross-project reference'}
= cross_project_reference(@project, @issue)
.creator
Created by #{link_to_member(@project, @issue.author)} #{issue_timestamp(@issue)}
%h4.title
= gfm escape_once(@issue.title)
- if @issue.description.present?
.description
.wiki
= preserve do
= markdown(@issue.description, parse_tasks: true)
.context
%cite.cgray
= render partial: 'issue_context', locals: { issue: @issue }
- content_for :note_actions do
- if can?(current_user, :modify_issue, @issue)
- if @issue.closed? - if @issue.closed?
= link_to 'Reopen Issue', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-grouped btn-reopen js-note-target-reopen", title: 'Reopen Issue' Closed
- else - else
= link_to 'Close Issue', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close js-note-target-close", title: "Close Issue" Open
Issue ##{@issue.iid}
.participants .pull-right.creator
%cite.cgray %small Created by #{link_to_member(@project, @issue.author)} #{issue_timestamp(@issue)}
= pluralize(@issue.participants.count, 'participant') %hr
- @issue.participants.each do |participant| .row
= link_to_member(@project, participant, name: false, size: 24) .col-sm-9
%h3.issue-title
= gfm escape_once(@issue.title)
%div
- if @issue.description.present?
.description
.wiki
= preserve do
= markdown(@issue.description, parse_tasks: true)
%hr
- content_for :note_actions do
- if can?(current_user, :modify_issue, @issue)
- if @issue.closed?
= link_to 'Reopen Issue', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-grouped btn-reopen js-note-target-reopen", title: 'Reopen Issue'
- else
= link_to 'Close Issue', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close js-note-target-close", title: "Close Issue"
.participants
%cite.cgray
= pluralize(@issue.participants.count, 'participant')
- @issue.participants.each do |participant|
= link_to_member(@project, participant, name: false, size: 24)
.issue-show-labels.pull-right
- @issue.labels.each do |label|
= link_to project_issues_path(@project, label_name: label.name) do
= render_colored_label(label)
.issue-show-labels.pull-right .voting_notes#notes= render "projects/notes/notes_with_form"
- @issue.labels.each do |label| .col-sm-3
= link_to project_issues_path(@project, label_name: label.name) do %div
= render_colored_label(label) - if can?(current_user, :write_issue, @project)
= link_to new_project_issue_path(@project), class: "btn btn-block", title: "New Issue", id: "new_issue_link" do
%i.fa.fa-plus
New Issue
- if can?(current_user, :modify_issue, @issue)
- if @issue.closed?
= link_to 'Reopen', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-block btn-reopen"
- else
= link_to 'Close', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-block btn-close", title: "Close Issue"
.voting_notes#notes= render "projects/notes/notes_with_form" = link_to edit_project_issue_path(@project, @issue), class: "btn btn-block issuable-edit" do
%i.fa.fa-pencil-square-o
Edit
.clearfix
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
= cross_project_reference(@project, @issue)
%hr
.clearfix
.votes-holder
%h6 Votes
#votes= render 'votes/votes_block', votable: @issue
%hr
.context
%cite.cgray
= render partial: 'issue_context', locals: { issue: @issue }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
:plain :plain
$("##{dom_id(@issue)}").fadeOut(); $("##{dom_id(@issue)}").fadeOut();
- elsif params[:issue_context] - elsif params[:issue_context]
$('.issue-box .context').effect('highlight'); $('.context').effect('highlight');
- if @issue.milestone - if @issue.milestone
$('.milestone-nav-link').replaceWith("<span class='milestone-nav-link'>| <span class='light'>Milestone</span> #{escape_javascript(link_to @issue.milestone.title, project_milestone_path(@issue.project, @issue.milestone))}</span>") $('.milestone-nav-link').replaceWith("<span class='milestone-nav-link'>| <span class='light'>Milestone</span> #{escape_javascript(link_to @issue.milestone.title, project_milestone_path(@issue.project, @issue.milestone))}</span>")
- else - else
......
.merge-request .merge-request
= render "projects/merge_requests/show/mr_title" = render "projects/merge_requests/show/mr_title"
= render "projects/merge_requests/show/how_to_merge" %hr
= render "projects/merge_requests/show/mr_box" .row
= render "projects/merge_requests/show/state_widget" .col-sm-9
= render "projects/merge_requests/show/commits" = render "projects/merge_requests/show/how_to_merge"
= render "projects/merge_requests/show/participants" = render "projects/merge_requests/show/mr_box"
%hr
.append-bottom-20
%p.slead
%span From
- if @merge_request.for_fork?
%strong.label-branch<
- if @merge_request.source_project
= link_to @merge_request.source_project_namespace, project_path(@merge_request.source_project)
- else
\ #{@merge_request.source_project_namespace}
\:#{@merge_request.source_branch}
%span into
%strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch}
- else
%strong.label-branch #{@merge_request.source_branch}
%span into
%strong.label-branch #{@merge_request.target_branch}
= render "projects/merge_requests/show/state_widget"
= render "projects/merge_requests/show/commits"
= render "projects/merge_requests/show/participants"
.col-sm-3
.issue-btn-group
- if can?(current_user, :modify_merge_request, @merge_request)
- if @merge_request.open?
.btn-group-justified.append-bottom-20
.btn-group
%a.btn.dropdown-toggle{ data: {toggle: :dropdown} }
%i.fa.fa-download
Download as
%span.caret
%ul.dropdown-menu
%li= link_to "Email Patches", project_merge_request_path(@project, @merge_request, format: :patch)
%li= link_to "Plain Diff", project_merge_request_path(@project, @merge_request, format: :diff)
= link_to 'Close', project_merge_request_path(@project, @merge_request, merge_request: { state_event: :close }), method: :put, class: "btn btn-block btn-close", title: "Close merge request"
= link_to edit_project_merge_request_path(@project, @merge_request), class: "btn btn-block issuable-edit", id: "edit_merge_request" do
%i.fa.fa-pencil-square-o
Edit
- if @merge_request.closed?
= link_to 'Reopen', project_merge_request_path(@project, @merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-block btn-reopen reopen-mr-link", title: "Close merge request"
.clearfix
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
= cross_project_reference(@project, @merge_request)
%hr
.votes-holder.hidden-sm.hidden-xs
%h6 Votes
#votes= render 'votes/votes_block', votable: @merge_request
%hr
.context
%cite.cgray
= render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request }
- if @commits.present? - if @commits.present?
%ul.nav.nav-pills.merge-request-tabs %ul.nav.nav-tabs.merge-request-tabs
%li.notes-tab{data: {action: 'notes'}} %li.notes-tab{data: {action: 'notes'}}
= link_to project_merge_request_path(@project, @merge_request) do = link_to project_merge_request_path(@project, @merge_request) do
%i.fa.fa-comment %i.fa.fa-comment
...@@ -30,10 +81,13 @@ ...@@ -30,10 +81,13 @@
- if current_page?(action: 'diffs') - if current_page?(action: 'diffs')
= render "projects/merge_requests/show/diffs" = render "projects/merge_requests/show/diffs"
.notes.tab-content.voting_notes#notes{ class: (controller.action_name == 'show') ? "" : "hide" } .notes.tab-content.voting_notes#notes{ class: (controller.action_name == 'show') ? "" : "hide" }
= render "projects/notes/notes_with_form" .row
.col-sm-9
= render "projects/notes/notes_with_form"
.mr-loading-status .mr-loading-status
= spinner = spinner
:javascript :javascript
var merge_request; var merge_request;
......
= render "projects/issues_nav" = render "projects/issues_nav"
.row .merge-requests-holder
.col-md-3.responsive-side .append-bottom-10
= render 'shared/project_filter', project_entities_path: project_merge_requests_path(@project), = render 'shared/issuable_filter'
labels: true, redirect: 'merge_requests', entity: 'merge_request' .panel.panel-default
.col-md-9 %ul.well-list.mr-list
.append-bottom-10 = render @merge_requests
= render 'projects/issuable_filter' - if @merge_requests.blank?
.panel.panel-default %li
%ul.well-list.mr-list .nothing-here-block No merge requests to show
= render @merge_requests - if @merge_requests.present?
- if @merge_requests.blank? .pull-right
%li %span.cgray.pull-right #{@merge_requests.total_count} merge requests for this filter
.nothing-here-block No merge requests to show
- if @merge_requests.present?
.pull-right
%span.cgray.pull-right #{@merge_requests.total_count} merge requests for this filter
= paginate @merge_requests, theme: "gitlab" = paginate @merge_requests, theme: "gitlab"
:javascript :javascript
$(merge_requestsPage); $(merge_requestsPage);
= form_for [@project, @merge_request], remote: true, html: {class: 'edit-merge_request inline-update'} do |f| = form_for [@project, @merge_request], remote: true, html: {class: 'edit-merge_request inline-update'} do |f|
.row %div.prepend-top-20
.col-sm-6 %p
%strong.append-right-10 Assignee:
Assignee:
- if can?(current_user, :modify_merge_request, @merge_request) - if can?(current_user, :modify_merge_request, @merge_request)
= project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @merge_request.assignee_id) = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @merge_request.assignee_id)
- elsif merge_request.assignee - elsif merge_request.assignee
= link_to_member(@project, @merge_request.assignee) = link_to_member(@project, @merge_request.assignee)
- else - else
None None
.col-sm-6.text-right %div.prepend-top-20
%strong.append-right-10 %p
Milestone: Milestone:
- if can?(current_user, :modify_merge_request, @merge_request) - if can?(current_user, :modify_merge_request, @merge_request)
= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'}) = f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :merge_request_context = hidden_field_tag :merge_request_context
= f.submit class: 'btn' = f.submit class: 'btn'
- elsif merge_request.milestone - elsif merge_request.milestone
= link_to merge_request.milestone.title, project_milestone_path = link_to merge_request.milestone.title, project_milestone_path
- else - else
None None
.issue-box{ class: issue_box_class(@merge_request) } %h3.issue-title
.state.clearfix = gfm escape_once(@merge_request.title)
.state-label
- if @merge_request.merged?
Merged
- elsif @merge_request.closed?
Closed
- else
Open
.cross-project-ref
%i.fa.fa-link.has_tooltip{:"data-original-title" => 'Cross-project reference'}
= cross_project_reference(@project, @merge_request)
.creator
Created by #{link_to_member(@project, @merge_request.author)} #{time_ago_with_tooltip(@merge_request.created_at)}
%h4.title
= gfm escape_once(@merge_request.title)
%div
- if @merge_request.description.present? - if @merge_request.description.present?
.description .description
.wiki .wiki
= preserve do = preserve do
= markdown(@merge_request.description, parse_tasks: true) = markdown(@merge_request.description, parse_tasks: true)
.context
%cite.cgray
= render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request }
%h3.page-title %h3.page-title
= "Merge Request ##{@merge_request.iid}" .issue-box{ class: issue_box_class(@merge_request) }
- if @merge_request.merged?
%span.pull-right.issue-btn-group Merged
- if can?(current_user, :modify_merge_request, @merge_request) - elsif @merge_request.closed?
- if @merge_request.open? Closed
.btn-group.pull-left
%a.btn.btn-grouped.dropdown-toggle{ data: {toggle: :dropdown} }
%i.fa.fa-download
Download as
%span.caret
%ul.dropdown-menu
%li= link_to "Email Patches", project_merge_request_path(@project, @merge_request, format: :patch)
%li= link_to "Plain Diff", project_merge_request_path(@project, @merge_request, format: :diff)
= link_to 'Close', project_merge_request_path(@project, @merge_request, merge_request: { state_event: :close }), method: :put, class: "btn btn-grouped btn-close", title: "Close merge request"
= link_to edit_project_merge_request_path(@project, @merge_request), class: "btn btn-grouped", id:"edit_merge_request" do
%i.fa.fa-pencil-square-o
Edit
- if @merge_request.closed?
= link_to 'Reopen', project_merge_request_path(@project, @merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-grouped btn-reopen reopen-mr-link", title: "Close merge request"
.votes-holder.hidden-sm.hidden-xs
#votes= render 'votes/votes_block', votable: @merge_request
.back-link
= link_to project_merge_requests_path(@project) do
&larr; To merge requests
%span.prepend-left-20
%span From
- if @merge_request.for_fork?
%strong.label-branch<
- if @merge_request.source_project
= link_to @merge_request.source_project_namespace, project_path(@merge_request.source_project)
- else
\ #{@merge_request.source_project_namespace}
\:#{@merge_request.source_branch}
%span into
%strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch}
- else - else
%strong.label-branch #{@merge_request.source_branch} Open
%span into = "Merge Request ##{@merge_request.iid}"
%strong.label-branch #{@merge_request.target_branch} .pull-right.creator
%small Created by #{link_to_member(@project, @merge_request.author)} #{time_ago_with_tooltip(@merge_request.created_at)}
- if params[:merge_request_context] - if params[:merge_request_context]
$('.issue-box .context').effect('highlight'); $('.context').effect('highlight');
= render "projects/issues_nav" = render "projects/issues_nav"
%h3.page-title %h3.page-title
.issue-box{ class: issue_box_class(@milestone) }
- if @milestone.closed?
Closed
- elsif @milestone.expired?
Expired
- else
Open
Milestone ##{@milestone.iid} Milestone ##{@milestone.iid}
.pull-right .pull-right.creator
- if can?(current_user, :admin_milestone, @project) %small= @milestone.expires_at
= link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-grouped" do
%i.fa.fa-pencil-square-o
Edit
- if @milestone.active?
= link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-close btn-grouped"
- else
= link_to 'Reopen Milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-grouped"
%hr
- if @milestone.issues.any? && @milestone.can_be_closed? - if @milestone.issues.any? && @milestone.can_be_closed?
.alert.alert-success .alert.alert-success
%span All issues for this milestone are closed. You may close milestone now. %span All issues for this milestone are closed. You may close milestone now.
.row
.col-sm-9
%h3.issue-title
= gfm escape_once(@milestone.title)
%div
- if @milestone.description.present?
.description
.wiki
= preserve do
= markdown @milestone.description
.back-link %hr
= link_to project_milestones_path(@project) do .context
&larr; To milestones list %p.lead
Progress:
#{@milestone.closed_items_count} closed
.issue-box{ class: issue_box_class(@milestone) } &ndash;
.state.clearfix #{@milestone.open_items_count} open
.state-label &nbsp;
- if @milestone.closed? %span.light #{@milestone.percent_complete}% complete
Closed %span.pull-right= @milestone.expires_at
- elsif @milestone.expired? .progress.progress-info
Expired .progress-bar{style: "width: #{@milestone.percent_complete}%;"}
- else
Open
.creator
= @milestone.expires_at
%h4.title
= gfm escape_once(@milestone.title)
- if @milestone.description.present? .col-sm-3
.description %div
.wiki - if can?(current_user, :admin_milestone, @project)
= preserve do = link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-block" do
= markdown @milestone.description %i.fa.fa-pencil-square-o
Edit
- if @milestone.active?
= link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-close btn-block"
- else
= link_to 'Reopen Milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-block"
= link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn btn-block", title: "New Issue" do
%i.fa.fa-plus
New Issue
= link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link btn-block"
.context
%p
Progress:
#{@milestone.closed_items_count} closed
&ndash;
#{@milestone.open_items_count} open
&nbsp;
%span.light #{@milestone.percent_complete}% complete
%span.pull-right= @milestone.expires_at
.progress.progress-info
.progress-bar{style: "width: #{@milestone.percent_complete}%;"}
%ul.nav.nav-tabs %ul.nav.nav-tabs
...@@ -69,10 +71,6 @@ ...@@ -69,10 +71,6 @@
%span.badge= @users.count %span.badge= @users.count
.pull-right .pull-right
= link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn btn-small btn-grouped", title: "New Issue" do
%i.fa.fa-plus
New Issue
= link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn btn-small edit-milestone-link btn-grouped"
.tab-content .tab-content
.tab-pane.active#tab-issues .tab-pane.active#tab-issues
......
.event_filter %ul.nav.nav-pills.event_filter
= event_filter_link EventFilter.push, 'Push events' = event_filter_link EventFilter.push, 'Push events'
= event_filter_link EventFilter.merged, 'Merge events' = event_filter_link EventFilter.merged, 'Merge events'
= event_filter_link EventFilter.comments, 'Comments' = event_filter_link EventFilter.comments, 'Comments'
= event_filter_link EventFilter.team, 'Team' = event_filter_link EventFilter.team, 'Team'
- if current_user
- if current_controller?(:dashboard)
%li.pull-right
= link_to dashboard_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do
%i.fa.fa-rss
News Feed
- if current_controller?(:groups)
%li.pull-right
= link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'rss-btn' do
%i.fa.fa-rss
News Feed
%hr
.side-filters
= form_tag filter_path(entity), method: 'get' do
- if current_user
%fieldset.scope-filter
%ul.nav.nav-pills.nav-stacked
%li{class: ("active" if params[:scope] == 'assigned-to-me')}
= link_to filter_path(entity, scope: 'assigned-to-me') do
Assigned to me
%span.pull-right
= assigned_entities_count(current_user, entity, @group)
%li{class: ("active" if params[:scope] == 'authored')}
= link_to filter_path(entity, scope: 'authored') do
Created by me
%span.pull-right
= authored_entities_count(current_user, entity, @group)
%li{class: ("active" if params[:scope] == 'all')}
= link_to filter_path(entity, scope: 'all') do
Everyone's
%span.pull-right
= authorized_entities_count(current_user, entity, @group)
%fieldset.status-filter
%legend State
%ul.nav.nav-pills
%li{class: ("active" if params[:state] == 'opened')}
= link_to filter_path(entity, state: 'opened') do
Open
%li{class: ("active" if params[:state] == 'closed')}
= link_to filter_path(entity, state: 'closed') do
Closed
%li{class: ("active" if params[:state] == 'all')}
= link_to filter_path(entity, state: 'all') do
All
%fieldset
%legend Projects
%ul.nav.nav-pills.nav-stacked.nav-small
- @projects.each do |project|
- unless entities_per_project(project, entity).zero?
%li{class: ("active" if params[:project_id] == project.id.to_s)}
= link_to filter_path(entity, project_id: project.id) do
= project.name_with_namespace
%small.pull-right= entities_per_project(project, entity)
%fieldset
- if params[:state].present? || params[:project_id].present?
= link_to filter_path(entity, state: nil, project_id: nil), class: 'pull-right cgray' do
%i.fa.fa-times
%strong Clear filter
.issues-filters .issues-filters
.dropdown.inline .pull-left.append-right-20
%ul.nav.nav-pills.nav-compact
%li{class: ("active" if params[:state] == 'opened')}
= link_to page_filter_path(state: 'opened') do
%i.fa.fa-exclamation-circle
Open
%li{class: ("active" if params[:state] == 'closed')}
= link_to page_filter_path(state: 'closed') do
%i.fa.fa-check-circle
Closed
%li{class: ("active" if params[:state] == 'all')}
= link_to page_filter_path(state: 'all') do
%i.fa.fa-compass
All
.dropdown.inline.assignee-filter
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-user %i.fa.fa-user
%span.light assignee: %span.light assignee:
...@@ -12,17 +27,17 @@ ...@@ -12,17 +27,17 @@
%b.caret %b.caret
%ul.dropdown-menu %ul.dropdown-menu
%li %li
= link_to project_filter_path(assignee_id: nil) do = link_to page_filter_path(assignee_id: nil) do
Any Any
= link_to project_filter_path(assignee_id: 0) do = link_to page_filter_path(assignee_id: 0) do
Unassigned Unassigned
- @assignees.sort_by(&:name).each do |user| - @assignees.sort_by(&:name).each do |user|
%li %li
= link_to project_filter_path(assignee_id: user.id) do = link_to page_filter_path(assignee_id: user.id) do
= image_tag avatar_icon(user.email), class: "avatar s16", alt: '' = image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
= user.name = user.name
.dropdown.inline.prepend-left-10 .dropdown.inline.prepend-left-10.author-filter
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-user %i.fa.fa-user
%span.light author: %span.light author:
...@@ -35,17 +50,17 @@ ...@@ -35,17 +50,17 @@
%b.caret %b.caret
%ul.dropdown-menu %ul.dropdown-menu
%li %li
= link_to project_filter_path(author_id: nil) do = link_to page_filter_path(author_id: nil) do
Any Any
= link_to project_filter_path(author_id: 0) do = link_to page_filter_path(author_id: 0) do
Unassigned Unassigned
- @authors.sort_by(&:name).each do |user| - @authors.sort_by(&:name).each do |user|
%li %li
= link_to project_filter_path(author_id: user.id) do = link_to page_filter_path(author_id: user.id) do
= image_tag avatar_icon(user.email), class: "avatar s16", alt: '' = image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
= user.name = user.name
.dropdown.inline.prepend-left-10 .dropdown.inline.prepend-left-10.milestone-filter
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-clock-o %i.fa.fa-clock-o
%span.light milestone: %span.light milestone:
...@@ -58,15 +73,40 @@ ...@@ -58,15 +73,40 @@
%b.caret %b.caret
%ul.dropdown-menu %ul.dropdown-menu
%li %li
= link_to project_filter_path(milestone_id: nil) do = link_to page_filter_path(milestone_id: nil) do
Any Any
= link_to project_filter_path(milestone_id: 0) do = link_to page_filter_path(milestone_id: 0) do
None (backlog) None (backlog)
- project_active_milestones.each do |milestone| - @milestones.each do |milestone|
%li %li
= link_to project_filter_path(milestone_id: milestone.id) do = link_to page_filter_path(milestone_id: milestone.id) do
%strong= milestone.title %strong= milestone.title
%small.light= milestone.expires_at %small.light= milestone.expires_at
- if @project
.dropdown.inline.prepend-left-10.labels-filter
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-tags
%span.light label:
- if params[:label_name].present?
%strong= params[:label_name]
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to page_filter_path(label_name: nil) do
Any
- if @project.labels.any?
- @project.labels.order_by_name.each do |label|
%li
= link_to page_filter_path(label_name: label.name) do
= render_colored_label(label)
- else
%li
= link_to generate_project_labels_path(@project, redirect: request.original_url), method: :post do
%i.fa.fa-plus-circle
Create default labels
.pull-right .pull-right
= render 'shared/sort_dropdown' = render 'shared/sort_dropdown'
.side-filters
= form_tag project_entities_path, method: 'get' do
- if current_user
%fieldset
%ul.nav.nav-pills.nav-stacked
%li{class: ("active" if params[:scope] == 'all')}
= link_to project_filter_path(scope: 'all') do
Everyone's
%span.pull-right
= authorized_entities_count(current_user, entity, @project)
%li{class: ("active" if params[:scope] == 'assigned-to-me')}
= link_to project_filter_path(scope: 'assigned-to-me') do
Assigned to me
%span.pull-right
= assigned_entities_count(current_user, entity, @project)
%li{class: ("active" if params[:scope] == 'created-by-me')}
= link_to project_filter_path(scope: 'created-by-me') do
Created by me
%span.pull-right
= authored_entities_count(current_user, entity, @project)
%fieldset
%legend State
%ul.nav.nav-pills
%li{class: ("active" if params[:state] == 'opened')}
= link_to project_filter_path(state: 'opened') do
Open
%li{class: ("active" if params[:state] == 'closed')}
= link_to project_filter_path(state: 'closed') do
Closed
%li{class: ("active" if params[:state] == 'all')}
= link_to project_filter_path(state: 'all') do
All
- if defined?(labels)
%fieldset
%legend
Labels
%small.pull-right
= link_to project_labels_path(@project), class: 'light' do
%i.fa.fa-pencil-square-o
%ul.nav.nav-pills.nav-stacked.nav-small.labels-filter
- @project.labels.order_by_name.each do |label|
%li{class: label_filter_class(label.name)}
= link_to labels_filter_path(label.name) do
= render_colored_label(label)
- if selected_label?(label.name)
.pull-right
%i.fa.fa-times
- if @project.labels.empty?
.light-well
Create first label at
= link_to 'labels page', project_labels_path(@project)
%br
or #{link_to 'generate', generate_project_labels_path(@project, redirect: redirect), method: :post} default set of labels
%fieldset
- if %w(state scope milestone_id assignee_id label_name).select { |k| params[k].present? }.any?
= link_to project_entities_path, class: 'cgray pull-right' do
%i.fa.fa-times
%strong Clear filter
...@@ -8,15 +8,15 @@ ...@@ -8,15 +8,15 @@
%b.caret %b.caret
%ul.dropdown-menu %ul.dropdown-menu
%li %li
= link_to project_filter_path(sort: 'newest') do = link_to page_filter_path(sort: 'newest') do
= sort_title_recently_created = sort_title_recently_created
= link_to project_filter_path(sort: 'oldest') do = link_to page_filter_path(sort: 'oldest') do
= sort_title_oldest_created = sort_title_oldest_created
= link_to project_filter_path(sort: 'recently_updated') do = link_to page_filter_path(sort: 'recently_updated') do
= sort_title_recently_updated = sort_title_recently_updated
= link_to project_filter_path(sort: 'last_updated') do = link_to page_filter_path(sort: 'last_updated') do
= sort_title_oldest_updated = sort_title_oldest_updated
= link_to project_filter_path(sort: 'milestone_due_soon') do = link_to page_filter_path(sort: 'milestone_due_soon') do
Milestone due soon Milestone due soon
= link_to project_filter_path(sort: 'milestone_due_later') do = link_to page_filter_path(sort: 'milestone_due_later') do
Milestone due later Milestone due later
...@@ -3,4 +3,5 @@ if Rails.env == 'development' ...@@ -3,4 +3,5 @@ if Rails.env == 'development'
# initialization is skipped so trigger it # initialization is skipped so trigger it
Rack::MiniProfilerRails.initialize!(Rails.application) Rack::MiniProfilerRails.initialize!(Rails.application)
Rack::MiniProfiler.config.position = 'right'
end end
...@@ -28,7 +28,6 @@ Feature: Explore Groups ...@@ -28,7 +28,6 @@ Feature: Explore Groups
Given group "TestGroup" has internal project "Internal" Given group "TestGroup" has internal project "Internal"
When I sign in as a user When I sign in as a user
And I visit group "TestGroup" issues page And I visit group "TestGroup" issues page
And I change filter to Everyone's
Then I should see project "Internal" items Then I should see project "Internal" items
And I should not see project "Enterprise" items And I should not see project "Enterprise" items
...@@ -36,7 +35,6 @@ Feature: Explore Groups ...@@ -36,7 +35,6 @@ Feature: Explore Groups
Given group "TestGroup" has internal project "Internal" Given group "TestGroup" has internal project "Internal"
When I sign in as a user When I sign in as a user
And I visit group "TestGroup" merge requests page And I visit group "TestGroup" merge requests page
And I change filter to Everyone's
Then I should see project "Internal" items Then I should see project "Internal" items
And I should not see project "Enterprise" items And I should not see project "Enterprise" items
...@@ -94,7 +92,6 @@ Feature: Explore Groups ...@@ -94,7 +92,6 @@ Feature: Explore Groups
Given group "TestGroup" has public project "Community" Given group "TestGroup" has public project "Community"
When I sign in as a user When I sign in as a user
And I visit group "TestGroup" issues page And I visit group "TestGroup" issues page
And I change filter to Everyone's
Then I should see project "Community" items Then I should see project "Community" items
And I should see project "Internal" items And I should see project "Internal" items
And I should not see project "Enterprise" items And I should not see project "Enterprise" items
...@@ -104,7 +101,6 @@ Feature: Explore Groups ...@@ -104,7 +101,6 @@ Feature: Explore Groups
Given group "TestGroup" has public project "Community" Given group "TestGroup" has public project "Community"
When I sign in as a user When I sign in as a user
And I visit group "TestGroup" merge requests page And I visit group "TestGroup" merge requests page
And I change filter to Everyone's
Then I should see project "Community" items Then I should see project "Community" items
And I should see project "Internal" items And I should see project "Internal" items
And I should not see project "Enterprise" items And I should not see project "Enterprise" items
......
...@@ -35,14 +35,20 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps ...@@ -35,14 +35,20 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps
end end
step 'I click "Authored by me" link' do step 'I click "Authored by me" link' do
within ".scope-filter" do within ".assignee-filter" do
click_link 'Created by me' click_link "Any"
end
within ".author-filter" do
click_link current_user.name
end end
end end
step 'I click "All" link' do step 'I click "All" link' do
within ".scope-filter" do within ".author-filter" do
click_link "Everyone's" click_link "Any"
end
within ".assignee-filter" do
click_link "Any"
end end
end end
......
...@@ -39,14 +39,20 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps ...@@ -39,14 +39,20 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
end end
step 'I click "Authored by me" link' do step 'I click "Authored by me" link' do
within ".scope-filter" do within ".assignee-filter" do
click_link 'Created by me' click_link "Any"
end
within ".author-filter" do
click_link current_user.name
end end
end end
step 'I click "All" link' do step 'I click "All" link' do
within ".scope-filter" do within ".author-filter" do
click_link "Everyone's" click_link "Any"
end
within ".assignee-filter" do
click_link "Any"
end end
end end
......
...@@ -89,7 +89,6 @@ class Spinach::Features::Groups < Spinach::FeatureSteps ...@@ -89,7 +89,6 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
step 'I should see newly created group "Samurai"' do step 'I should see newly created group "Samurai"' do
page.should have_content "Samurai" page.should have_content "Samurai"
page.should have_content "Tokugawa Shogunate" page.should have_content "Tokugawa Shogunate"
page.should have_content "Currently you are only seeing events from the"
end end
step 'I change group "Owned" name to "new-name"' do step 'I change group "Owned" name to "new-name"' do
...@@ -99,7 +98,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps ...@@ -99,7 +98,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
step 'I should see new group "Owned" name' do step 'I should see new group "Owned" name' do
within ".navbar-gitlab" do within ".navbar-gitlab" do
page.should have_content "group: new-name" page.should have_content "new-name"
end end
end end
......
...@@ -57,9 +57,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps ...@@ -57,9 +57,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end end
step 'I click link "Close"' do step 'I click link "Close"' do
within '.page-title' do first(:css, '.close-mr-link').click
click_link "Close"
end
end end
step 'I submit new merge request "Wiki Feature"' do step 'I submit new merge request "Wiki Feature"' do
...@@ -181,13 +179,11 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps ...@@ -181,13 +179,11 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end end
step 'I click link "Reopen"' do step 'I click link "Reopen"' do
within '.page-title' do first(:css, '.reopen-mr-link').click
click_link "Reopen"
end
end end
step 'I should see reopened merge request "Bug NS-04"' do step 'I should see reopened merge request "Bug NS-04"' do
within '.state-label' do within '.issue-box' do
page.should have_content "Open" page.should have_content "Open"
end end
end end
......
...@@ -2,7 +2,7 @@ module SharedActiveTab ...@@ -2,7 +2,7 @@ module SharedActiveTab
include Spinach::DSL include Spinach::DSL
def ensure_active_main_tab(content) def ensure_active_main_tab(content)
find('.main-nav li.active').should have_content(content) find('.nav-sidebar > li.active').should have_content(content)
end end
def ensure_active_sub_tab(content) def ensure_active_sub_tab(content)
...@@ -10,11 +10,11 @@ module SharedActiveTab ...@@ -10,11 +10,11 @@ module SharedActiveTab
end end
def ensure_active_sub_nav(content) def ensure_active_sub_nav(content)
find('div.content ul.nav-stacked-menu li.active').should have_content(content) find('.sidebar-subnav > li.active').should have_content(content)
end end
step 'no other main tabs should be active' do step 'no other main tabs should be active' do
page.should have_selector('.main-nav li.active', count: 1) page.should have_selector('.nav-sidebar > li.active', count: 1)
end end
step 'no other sub tabs should be active' do step 'no other sub tabs should be active' do
...@@ -22,7 +22,7 @@ module SharedActiveTab ...@@ -22,7 +22,7 @@ module SharedActiveTab
end end
step 'no other sub navs should be active' do step 'no other sub navs should be active' do
page.should have_selector('div.content ul.nav-stacked-menu li.active', count: 1) page.should have_selector('.sidebar-subnav > li.active', count: 1)
end end
step 'the active main tab should be Home' do step 'the active main tab should be Home' do
......
...@@ -2,7 +2,7 @@ module SharedIssuable ...@@ -2,7 +2,7 @@ module SharedIssuable
include Spinach::DSL include Spinach::DSL
def edit_issuable def edit_issuable
find('.issue-btn-group').click_link 'Edit' find(:css, '.issuable-edit').click
end end
step 'I click link "Edit" for the merge request' do step 'I click link "Edit" for the merge request' do
......
...@@ -12,7 +12,7 @@ describe "Admin::Hooks", feature: true do ...@@ -12,7 +12,7 @@ describe "Admin::Hooks", feature: true do
describe "GET /admin/hooks" do describe "GET /admin/hooks" do
it "should be ok" do it "should be ok" do
visit admin_root_path visit admin_root_path
within ".main-nav" do within ".sidebar-wrapper" do
click_on "Hooks" click_on "Hooks"
end end
current_path.should == admin_hooks_path current_path.should == admin_hooks_path
......
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