diff options
Diffstat (limited to 'app/views')
134 files changed, 1620 insertions, 1305 deletions
diff --git a/app/views/admin/builds/_build.html.haml b/app/views/admin/builds/_build.html.haml index 34d955568f2..588ad767426 100644 --- a/app/views/admin/builds/_build.html.haml +++ b/app/views/admin/builds/_build.html.haml @@ -4,13 +4,13 @@ = ci_status_with_icon(build.status) %td.build-link - - if can?(current_user, :read_build, project) && build.target_url - = link_to build.target_url do + - if can?(current_user, :read_build, build.project) + = link_to namespace_project_build_url(build.project.namespace, build.project, build) do %strong Build ##{build.id} - else %strong Build ##{build.id} - - if build.show_warning? + - if build.stuck? %i.fa.fa-warning.text-warning %td @@ -18,11 +18,11 @@ = link_to project.name_with_namespace, admin_namespace_project_path(project.namespace, project), class: "monospace" %td - = link_to build.short_sha, namespace_project_commit_path(project.namespace, project, build.sha), class: "monospace" + = link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "monospace" %td - if build.ref - = link_to build.ref, namespace_project_commits_path(project.namespace, project, build.ref) + = link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref) - else .light none @@ -61,13 +61,12 @@ %td .pull-right - if can?(current_user, :read_build, project) && build.artifacts? - = link_to build.artifacts_download_url, title: 'Download artifacts' do + = link_to download_namespace_project_build_artifacts_path(build.project.namespace, build.project, build), title: 'Download artifacts' do %i.fa.fa-download - if can?(current_user, :update_build, build.project) - if build.active? - - if build.cancel_url - = link_to build.cancel_url, method: :post, title: 'Cancel' do - %i.fa.fa-remove.cred - - elsif defined?(allow_retry) && allow_retry && build.retry_url - = link_to build.retry_url, method: :post, title: 'Retry' do + = link_to cancel_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Cancel' do + %i.fa.fa-remove.cred + - elsif defined?(allow_retry) && allow_retry && build.retryable? + = link_to retry_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Retry' do %i.fa.fa-repeat diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index f7fd156b84a..264fa1bf0cd 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -50,6 +50,22 @@ .panel-footer = paginate @projects, param_name: 'projects_page', theme: 'gitlab' + - if @group.shared_projects.any? + .panel.panel-default + .panel-heading + Projects shared with #{@group.name} + %span.badge + #{@group.shared_projects.count} + %ul.well-list + - @group.shared_projects.sort_by(&:name).each do |project| + %li + %strong + = link_to project.name_with_namespace, [:admin, project.namespace.becomes(Namespace), project] + %span.label.label-gray + = repository_size(project) + %span.pull-right.light + %span.monospace= project.path_with_namespace + ".git" + .col-md-6 - if can?(current_user, :admin_group_member, @group) .panel.panel-default diff --git a/app/views/admin/labels/_label.html.haml b/app/views/admin/labels/_label.html.haml index 5736a301910..f417b2e44a4 100644 --- a/app/views/admin/labels/_label.html.haml +++ b/app/views/admin/labels/_label.html.haml @@ -1,6 +1,6 @@ %li{id: dom_id(label)} .label-row - = render_colored_label(label) + = render_colored_label(label, tooltip: false) = markdown(label.description, pipeline: :single_line) .pull-right = link_to 'Edit', edit_admin_label_path(label), class: 'btn btn-sm' diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index e18dd9bc905..d2527ede995 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -58,9 +58,15 @@ = f.label :admin, class: 'control-label' - if current_user == @user .col-sm-10= f.check_box :admin, disabled: true - .col-sm-10 You cannot remove your own admin rights + .col-sm-10 You cannot remove your own admin rights. - else .col-sm-10= f.check_box :admin + + .form-group + = f.label :external, class: 'control-label' + .col-sm-10= f.check_box :external + .col-sm-10 External users cannot see internal or private projects unless access is explicitly granted. Also, external users cannot create projects or groups. + %fieldset %legend Profile .form-group diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index b6b1168bd37..0ee8dc962b9 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -19,6 +19,10 @@ = link_to admin_users_path(filter: 'two_factor_disabled') do 2FA Disabled %small.badge= number_with_delimiter(User.without_two_factor.count) + %li.filter-external{class: "#{'active' if params[:filter] == 'external'}"} + = link_to admin_users_path(filter: 'external') do + External + %small.badge= number_with_delimiter(User.external.count) %li{class: "#{'active' if params[:filter] == "blocked"}"} = link_to admin_users_path(filter: "blocked") do Blocked @@ -70,12 +74,14 @@ %li .list-item-name - if user.blocked? - %i.fa.fa-lock.cred + = icon("lock", class: "cred") - else - %i.fa.fa-user.cgreen + = icon("user", class: "cgreen") = link_to user.name, [:admin, user] - if user.admin? %strong.cred (Admin) + - if user.external? + %strong.cred (External) - if user == current_user %span.cred It's you! .pull-right diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 2bdbae19588..d37489bebea 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -48,6 +48,10 @@ Disabled %li + %span.light External User: + %strong + = @user.external? ? "Yes" : "No" + %li %span.light Can create groups: %strong = @user.can_create_group ? "Yes" : "No" diff --git a/app/views/ci/commits/_commit.html.haml b/app/views/ci/commits/_commit.html.haml deleted file mode 100644 index 11163813f3e..00000000000 --- a/app/views/ci/commits/_commit.html.haml +++ /dev/null @@ -1,32 +0,0 @@ -%tr.build - %td.status - = ci_status_with_icon(commit.status) - - if commit.running? - · - = commit.stage - - - %td.build-link - = link_to ci_status_path(commit) do - %strong #{commit.short_sha} - - %td.build-message - %span= truncate_first_line(commit.git_commit_message) - - %td.build-branch - - unless @ref - %span - - commit.refs.each do |ref| - = link_to truncate(ref, length: 25), ci_project_path(@project, ref: ref) - - %td.duration - - if commit.duration > 0 - #{time_interval_in_words commit.duration} - - %td.timestamp - - if commit.finished_at - %span #{time_ago_in_words commit.finished_at} ago - - - if commit.coverage - %td.coverage - #{commit.coverage}% diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml index 40f88261c10..9da3fcbd986 100644 --- a/app/views/dashboard/_projects_head.html.haml +++ b/app/views/dashboard/_projects_head.html.haml @@ -15,7 +15,7 @@ .nav-controls = form_tag request.original_url, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| = search_field_tag :filter_projects, params[:filter_projects], placeholder: 'Filter by name...', class: 'project-filter-form-field form-control input-short projects-list-filter', spellcheck: false, id: 'project-filter-form-field', tabindex: "2" - = render 'explore/projects/dropdown' + = render 'shared/projects/dropdown' - if current_user.can_create_project? = link_to new_project_path, class: 'btn btn-new' do = icon('plus') diff --git a/app/views/dashboard/milestones/_issue.html.haml b/app/views/dashboard/milestones/_issue.html.haml deleted file mode 100644 index 1408ebdd5dc..00000000000 --- a/app/views/dashboard/milestones/_issue.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%li{ id: dom_id(issue, 'sortable'), class: 'issue-row', 'data-iid' => issue.iid } - %span.milestone-row - - project = issue.project - %strong #{project.name_with_namespace} · - = link_to [project.namespace.becomes(Namespace), project, issue] do - %span.cgray ##{issue.iid} - = link_to_gfm issue.title, [project.namespace.becomes(Namespace), project, issue], title: issue.title - .pull-right.assignee-icon - - if issue.assignee - = image_tag avatar_icon(issue.assignee, 16), class: "avatar s16" diff --git a/app/views/dashboard/milestones/_issues.html.haml b/app/views/dashboard/milestones/_issues.html.haml deleted file mode 100644 index 9f350b772bd..00000000000 --- a/app/views/dashboard/milestones/_issues.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.panel.panel-default - .panel-heading= title - %ul{ class: "well-list issues-sortable-list" } - - if issues - - issues.each do |issue| - = render 'issue', issue: issue diff --git a/app/views/dashboard/milestones/_merge_request.html.haml b/app/views/dashboard/milestones/_merge_request.html.haml deleted file mode 100644 index 77c46de030b..00000000000 --- a/app/views/dashboard/milestones/_merge_request.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%li{ id: dom_id(merge_request, 'sortable'), class: 'mr-row', 'data-iid' => merge_request.iid } - %span.milestone-row - - project = merge_request.project - %strong #{project.name_with_namespace} · - = link_to [project.namespace.becomes(Namespace), project, merge_request] do - %span.cgray ##{merge_request.iid} - = link_to_gfm merge_request.title, [project.namespace.becomes(Namespace), project, merge_request], title: merge_request.title - .pull-right.assignee-icon - - if merge_request.assignee - = image_tag avatar_icon(merge_request.assignee, 16), class: "avatar s16" diff --git a/app/views/dashboard/milestones/_merge_requests.html.haml b/app/views/dashboard/milestones/_merge_requests.html.haml deleted file mode 100644 index 50057e2c636..00000000000 --- a/app/views/dashboard/milestones/_merge_requests.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.panel.panel-default - .panel-heading= title - %ul{ class: "well-list merge_requests-sortable-list" } - - if merge_requests - - merge_requests.each do |merge_request| - = render 'merge_request', merge_request: merge_request diff --git a/app/views/dashboard/milestones/_milestone.html.haml b/app/views/dashboard/milestones/_milestone.html.haml index 7c882a32702..6173ca6ab9b 100644 --- a/app/views/dashboard/milestones/_milestone.html.haml +++ b/app/views/dashboard/milestones/_milestone.html.haml @@ -1,25 +1,6 @@ -%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) } - .row - .col-sm-6 - %strong - = link_to_gfm truncate(milestone.title, length: 100), dashboard_milestone_path(milestone.safe_title, title: milestone.title) - .col-sm-6 - .pull-right.light #{milestone.percent_complete}% complete - .row - .col-sm-6 - = link_to issues_dashboard_path(milestone_title: milestone.title) do - = pluralize milestone.issue_count, 'Issue' - · - = link_to merge_requests_dashboard_path(milestone_title: milestone.title) do - = pluralize milestone.merge_requests_count, 'Merge Request' - .col-sm-6 - = milestone_progress_bar(milestone) - .row - .col-sm-6 - .expiration - = render 'shared/milestone_expired', milestone: milestone - .projects - - milestone.milestones.each do |milestone| - = link_to milestone_path(milestone) do - %span.label.label-gray - = milestone.project.name_with_namespace += render 'shared/milestones/milestone', + milestone_path: dashboard_milestone_path(milestone.safe_title, title: milestone.title), + issues_path: issues_dashboard_path(milestone_title: milestone.title), + merge_requests_path: merge_requests_dashboard_path(milestone_title: milestone.title), + milestone: milestone, + dashboard: true diff --git a/app/views/dashboard/milestones/show.html.haml b/app/views/dashboard/milestones/show.html.haml index 3810267577c..60c84a26420 100644 --- a/app/views/dashboard/milestones/show.html.haml +++ b/app/views/dashboard/milestones/show.html.haml @@ -1,105 +1,5 @@ -- page_title @milestone.title, "Milestones" - header_title "Milestones", dashboard_milestones_path -.detail-page-header - .status-box{ class: "status-box-#{@milestone.closed? ? 'closed' : 'open'}" } - - if @milestone.closed? - Closed - - else - Open - %span.identifier - Milestone #{@milestone.title} - -.detail-page-description.gray-content-block.second-block - %h2.title - = markdown escape_once(@milestone.title), pipeline: :single_line - -- if @milestone.complete? && @milestone.active? - .alert.alert-success.prepend-top-default - %span All issues for this milestone are closed. Navigate to the project to close the milestone. - -.table-holder - %table.table - %thead - %tr - %th Project - %th Open issues - %th State - %th Due date - - @milestone.milestones.each do |milestone| - %tr - %td - = link_to "#{milestone.project.name_with_namespace}", namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) - %td - = milestone.issues.opened.count - %td - - if milestone.closed? - Closed - - else - Open - %td - = milestone.expires_at - -.context - %p.lead - Progress: - #{@milestone.closed_items_count} closed - – - #{@milestone.open_items_count} open - = milestone_progress_bar(@milestone) - -%ul.nav-links.no-top.no-bottom - %li.active - = link_to '#tab-issues', 'data-toggle' => 'tab' do - Issues - %span.badge= @milestone.issue_count - %li - = link_to '#tab-merge-requests', 'data-toggle' => 'tab' do - Merge Requests - %span.badge= @milestone.merge_requests_count - %li - = link_to '#tab-participants', 'data-toggle' => 'tab' do - Participants - %span.badge= @milestone.participants.count - -.tab-content - .tab-pane.active#tab-issues - .gray-content-block.middle-block - .pull-right - = link_to 'Browse Issues', issues_dashboard_path(milestone_title: @milestone.title), class: "btn btn-grouped" - - .oneline - All issues in this milestone - - .row.prepend-top-default - .col-md-6 - = render 'issues', title: "Open", issues: @milestone.opened_issues - .col-md-6 - = render 'issues', title: "Closed", issues: @milestone.closed_issues - - .tab-pane#tab-merge-requests - .gray-content-block.middle-block - .pull-right - = link_to 'Browse Merge Requests', merge_requests_dashboard_path(milestone_title: @milestone.title), class: "btn btn-grouped" - - .oneline - All merge requests in this milestone - - .row.prepend-top-default - .col-md-6 - = render 'merge_requests', title: "Open", merge_requests: @milestone.opened_merge_requests - .col-md-6 - = render 'merge_requests', title: "Closed", merge_requests: @milestone.closed_merge_requests - - .tab-pane#tab-participants - .gray-content-block.middle-block - .oneline - All participants to this milestone - %ul.bordered-list - - @milestone.participants.each do |user| - %li - = link_to user, title: user.name, class: "darken" do - = image_tag avatar_icon(user, 32), class: "avatar s32" - %strong= truncate(user.name, lenght: 40) - %br - %small.cgray= user.username += render 'shared/milestones/top', milestone: @milestone += render 'shared/milestones/summary', milestone: @milestone += render 'shared/milestones/tabs', milestone: @milestone, show_full_project_name: true diff --git a/app/views/dashboard/projects/_zero_authorized_projects.html.haml b/app/views/dashboard/projects/_zero_authorized_projects.html.haml index c3efa7727b1..d54c7cad7be 100644 --- a/app/views/dashboard/projects/_zero_authorized_projects.html.haml +++ b/app/views/dashboard/projects/_zero_authorized_projects.html.haml @@ -1,4 +1,4 @@ -- publicish_project_count = Project.publicish(current_user).count +- publicish_project_count = ProjectsFinder.new.execute(current_user).count %h3.page-title Welcome to GitLab! %p.light Self hosted Git management application. %hr @@ -18,7 +18,7 @@ - if current_user.can_create_project? .link_holder = link_to new_project_path, class: "btn btn-new" do - %i.fa.fa-plus + = icon('plus') New Project - if current_user.can_create_group? diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml index f878d36e739..e3a4d64df01 100644 --- a/app/views/dashboard/todos/_todo.html.haml +++ b/app/views/dashboard/todos/_todo.html.haml @@ -2,9 +2,12 @@ .todo-item.todo-block = image_tag avatar_icon(todo.author_email, 40), class: 'avatar s40', alt:'' - .todo-title + .todo-title.title %span.author-name - = link_to_author todo + - if todo.author + = link_to_author(todo) + - else + (removed) %span.todo-label = todo_action_name(todo) = todo_target_link(todo) @@ -13,7 +16,9 @@ - if todo.pending? .todo-actions.pull-right - = link_to 'Done', [:dashboard, todo], method: :delete, class: 'btn' + = link_to [:dashboard, todo], method: :delete, class: 'btn btn-loading done-todo' do + Done + = icon('spinner spin') .todo-body .todo-note diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml index 946d7df3933..f9ec3a89158 100644 --- a/app/views/dashboard/todos/index.html.haml +++ b/app/views/dashboard/todos/index.html.haml @@ -3,13 +3,15 @@ .top-area %ul.nav-links - %li{class: ('active' if params[:state].blank? || params[:state] == 'pending')} + - todo_pending_active = ('active' if params[:state].blank? || params[:state] == 'pending') + %li{class: "todos-pending #{todo_pending_active}"} = link_to todos_filter_path(state: 'pending') do %span To do %span{class: 'badge'} = todos_pending_count - %li{class: ('active' if params[:state] == 'done')} + - todo_done_active = ('active' if params[:state] == 'done') + %li{class: "todos-done #{todo_done_active}"} = link_to todos_filter_path(state: 'done') do %span Done @@ -18,7 +20,9 @@ .nav-controls - if @todos.any?(&:pending?) - = link_to 'Mark all as done', destroy_all_dashboard_todos_path(todos_filter_params), class: 'btn', method: :delete + = link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'btn btn-loading js-todos-mark-all', method: :delete do + Mark all as done + = icon('spinner spin') .todos-filters .gray-content-block.second-block @@ -42,12 +46,12 @@ .prepend-top-default - if @todos.any? - @todos.group_by(&:project).each do |group| - .panel.panel-default.panel-small + .panel.panel-default.panel-small.js-todos-list - project = group[0] .panel-heading = link_to project.name_with_namespace, namespace_project_path(project.namespace, project) - %ul.well-list.todos-list + %ul.content-list.todos-list = render group[1] = paginate @todos, theme: "gitlab" - else diff --git a/app/views/doorkeeper/applications/_delete_form.html.haml b/app/views/doorkeeper/applications/_delete_form.html.haml index 6a5c917049d..001a711b1dd 100644 --- a/app/views/doorkeeper/applications/_delete_form.html.haml +++ b/app/views/doorkeeper/applications/_delete_form.html.haml @@ -1,4 +1,10 @@ - submit_btn_css ||= 'btn btn-link btn-remove btn-sm' = form_tag oauth_application_path(application) do %input{:name => "_method", :type => "hidden", :value => "delete"}/ - = submit_tag 'Destroy', onclick: "return confirm('Are you sure?')", class: submit_btn_css
\ No newline at end of file + - if defined? small + = button_tag type: "submit", class: "btn btn-transparent", data: { confirm: "Are you sure?" } do + %span.sr-only + Destroy + = icon('trash') + - else + = submit_tag 'Destroy', data: { confirm: "Are you sure?" }, class: submit_btn_css diff --git a/app/views/doorkeeper/applications/_form.html.haml b/app/views/doorkeeper/applications/_form.html.haml index 98a61ab211b..906b0676150 100644 --- a/app/views/doorkeeper/applications/_form.html.haml +++ b/app/views/doorkeeper/applications/_form.html.haml @@ -1,4 +1,4 @@ -= form_for application, url: doorkeeper_submit_path(application), html: {class: 'form-horizontal', role: 'form'} do |f| += form_for application, url: doorkeeper_submit_path(application), html: {role: 'form'} do |f| - if application.errors.any? .alert.alert-danger %ul @@ -6,25 +6,20 @@ %li= msg .form-group - = f.label :name, class: 'control-label' - - .col-sm-10 - = f.text_field :name, class: 'form-control', required: true + = f.label :name, class: 'label-light' + = f.text_field :name, class: 'form-control', required: true .form-group - = f.label :redirect_uri, class: 'control-label' - - .col-sm-10 - = f.text_area :redirect_uri, class: 'form-control', required: true + = f.label :redirect_uri, class: 'label-light' + = f.text_area :redirect_uri, class: 'form-control', required: true + %span.help-block + Use one line per URI + - if Doorkeeper.configuration.native_redirect_uri %span.help-block - Use one line per URI - - if Doorkeeper.configuration.native_redirect_uri - %span.help-block - Use - %code= Doorkeeper.configuration.native_redirect_uri - for local tests + Use + %code= Doorkeeper.configuration.native_redirect_uri + for local tests - .form-actions - = f.submit 'Submit', class: "btn btn-create" - = link_to "Cancel", applications_profile_path, class: "btn btn-cancel" + .prepend-top-default + = f.submit 'Save application', class: "btn btn-create" diff --git a/app/views/doorkeeper/applications/index.html.haml b/app/views/doorkeeper/applications/index.html.haml index ba4c5b86efb..ea0b66c932b 100644 --- a/app/views/doorkeeper/applications/index.html.haml +++ b/app/views/doorkeeper/applications/index.html.haml @@ -1,19 +1,83 @@ - page_title "Applications" -%h3.page-title Your applications -%p= link_to 'New Application', new_oauth_application_path, class: 'btn btn-success' +- header_title page_title, applications_profile_path -.table-holder - %table.table.table-striped - %thead - %tr - %th Name - %th Callback URL - %th - %th - %tbody - - @applications.each do |application| - %tr{:id => "application_#{application.id}"} - %td= link_to application.name, oauth_application_path(application) - %td= application.redirect_uri - %td= link_to 'Edit', edit_oauth_application_path(application), class: 'btn btn-link' - %td= render 'delete_form', application: application +.row.prepend-top-default + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0 + = page_title + %p + - if user_oauth_applications? + Manage applications that can use GitLab as an OAuth provider, + and applications that you've authorized to use your account. + - else + Manage applications that you've authorized to use your account. + .col-lg-9 + - if user_oauth_applications? + %h5.prepend-top-0 + Add new application + = render 'form', application: @application + %hr + - if user_oauth_applications? + .oauth-applications + %h5 + Your applications (#{@applications.size}) + - if @applications.any? + .table-responsive + %table.table + %thead + %tr + %th Name + %th Callback URL + %th Clients + %th.last-heading + %tbody + - @applications.each do |application| + %tr{id: "application_#{application.id}"} + %td= link_to application.name, oauth_application_path(application) + %td + - application.redirect_uri.split.each do |uri| + %div= uri + %td= application.access_tokens.count + %td + = link_to edit_oauth_application_path(application), class: "btn btn-transparent append-right-5" do + %span.sr-only + Edit + = icon('pencil') + = render 'delete_form', application: application, small: true + - else + .profile-settings-message.text-center + You don't have any applications + .oauth-authorized-applications.prepend-top-20.append-bottom-default + - if user_oauth_applications? + %h5 + Authorized applications (#{@authorized_tokens.size}) + + - if @authorized_tokens.any? + .table-responsive + %table.table.table-striped + %thead + %tr + %th Name + %th Authorized At + %th Scope + %th + %tbody + - @authorized_apps.each do |app| + - token = app.authorized_tokens.order('created_at desc').first + %tr{id: "application_#{app.id}"} + %td= app.name + %td= token.created_at + %td= token.scopes + %td= render 'delete_form', application: app + - @authorized_anonymous_tokens.each do |token| + %tr + %td + Anonymous + %div.help-block + %em Authorization was granted by entering your username and password in the application. + %td= token.created_at + %td= token.scopes + %td= render 'delete_form', token: token + - else + .profile-settings-message.text-center + You don't have any authorized applications diff --git a/app/views/emojis/index.html.haml b/app/views/emojis/index.html.haml index b66e513e4d2..3443a8e2307 100644 --- a/app/views/emojis/index.html.haml +++ b/app/views/emojis/index.html.haml @@ -2,8 +2,10 @@ .emoji-menu-content = text_field_tag :emoji_search, "", class: "emoji-search search-input form-control" - AwardEmoji.emoji_by_category.each do |category, emojis| - %h5= AwardEmoji::CATEGORIES[category] - %ul + %h5.emoji-menu-title + = AwardEmoji::CATEGORIES[category] + %ul.clearfix.emoji-menu-list - emojis.each do |emoji| - %li - = emoji_icon(emoji["name"], emoji["unicode"], emoji["aliases"])
\ No newline at end of file + %li.pull-left.text-center.emoji-menu-list-item + %button.emoji-menu-btn.text-center.js-emoji-btn{type: "button"} + = emoji_icon(emoji["name"], emoji["unicode"], emoji["aliases"]) diff --git a/app/views/events/_commit.html.haml b/app/views/events/_commit.html.haml index 4ba8b84fd92..dce4081288c 100644 --- a/app/views/events/_commit.html.haml +++ b/app/views/events/_commit.html.haml @@ -1,5 +1,5 @@ %li.commit .commit-row-title - = link_to truncate_sha(commit[:id]), namespace_project_commit_path(project.namespace, project, commit[:id]), class: "commit_short_id", alt: '' + = link_to truncate_sha(commit[:id]), namespace_project_commit_path(project.namespace, project, commit[:id]), class: "commit_short_id", alt: '', title: truncate_sha(commit[:id]) · = markdown event_commit_title(commit[:message]), project: project, pipeline: :single_line diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml index 36fb2d51629..2d9d9dd6342 100644 --- a/app/views/events/_event.html.haml +++ b/app/views/events/_event.html.haml @@ -1,4 +1,4 @@ -- if event.proper? +- if event.proper?(current_user) .event-item{class: "#{event.body? ? "event-block" : "event-inline" }"} .event-item-timestamp #{time_ago_with_tooltip(event.created_at)} diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml index abea86b026a..5753158c24d 100644 --- a/app/views/events/_event_last_push.html.haml +++ b/app/views/events/_event_last_push.html.haml @@ -3,7 +3,7 @@ .event-last-push .event-last-push-text %span You pushed to - = link_to namespace_project_commits_path(event.project.namespace, event.project, event.ref_name) do + = link_to namespace_project_commits_path(event.project.namespace, event.project, event.ref_name), title: h(event.project.name) do %strong= event.ref_name %span at %strong= link_to_project event.project diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml index 8bed5cdb9cc..235bd46107e 100644 --- a/app/views/events/event/_push.html.haml +++ b/app/views/events/event/_push.html.haml @@ -5,7 +5,7 @@ %strong= event.ref_name - else %strong - = link_to event.ref_name, namespace_project_commits_path(event.project.namespace, event.project, event.ref_name) + = link_to event.ref_name, namespace_project_commits_path(event.project.namespace, event.project, event.ref_name), title: h(event.target_title) at = link_to_project event.project diff --git a/app/views/explore/projects/_dropdown.html.haml b/app/views/explore/projects/_dropdown.html.haml deleted file mode 100644 index a4b4cd8d6c7..00000000000 --- a/app/views/explore/projects/_dropdown.html.haml +++ /dev/null @@ -1,20 +0,0 @@ -.dropdown.inline - %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} - %span.light - - if @sort.present? - = sort_options_hash[@sort] - - else - = sort_title_recently_updated - %b.caret - %ul.dropdown-menu.dropdown-menu-align-right - %li - = link_to explore_projects_filter_path(sort: sort_value_name) do - = sort_title_name - = link_to explore_projects_filter_path(sort: sort_value_recently_created) do - = sort_title_recently_created - = link_to explore_projects_filter_path(sort: sort_value_oldest_created) do - = sort_title_oldest_created - = link_to explore_projects_filter_path(sort: sort_value_recently_updated) do - = sort_title_recently_updated - = link_to explore_projects_filter_path(sort: sort_value_oldest_updated) do - = sort_title_oldest_updated diff --git a/app/views/explore/projects/_filter.html.haml b/app/views/explore/projects/_filter.html.haml index 39e3e8e2738..cd485da5104 100644 --- a/app/views/explore/projects/_filter.html.haml +++ b/app/views/explore/projects/_filter.html.haml @@ -10,11 +10,11 @@ %b.caret %ul.dropdown-menu %li - = link_to explore_projects_filter_path(visibility_level: nil) do + = link_to filter_projects_path(visibility_level: nil) do Any - Gitlab::VisibilityLevel.values.each do |level| %li{ class: (level.to_s == params[:visibility_level]) ? 'active' : 'light' } - = link_to explore_projects_filter_path(visibility_level: level) do + = link_to filter_projects_path(visibility_level: level) do = visibility_level_icon(level) = visibility_level_label(level) @@ -30,11 +30,11 @@ %b.caret %ul.dropdown-menu %li - = link_to explore_projects_filter_path(tag: nil) do + = link_to filter_projects_path(tag: nil) do Any - @tags.each do |tag| %li{ class: (tag.name == params[:tag]) ? 'active' : 'light' } - = link_to explore_projects_filter_path(tag: tag.name) do - %i.fa.fa-tag + = link_to filter_projects_path(tag: tag.name) do + = icon('tag') = tag.name diff --git a/app/views/groups/_activities.html.haml b/app/views/groups/_activities.html.haml new file mode 100644 index 00000000000..dc76599b776 --- /dev/null +++ b/app/views/groups/_activities.html.haml @@ -0,0 +1,12 @@ +.hidden-xs + = render "events/event_last_push", event: @last_push + +.nav-block + - if current_user + .controls + = link_to dashboard_projects_path(:atom, { private_token: current_user.private_token }), class: 'btn rss-btn' do + %i.fa.fa-rss + = render 'shared/event_filter' + +.content_list += spinner diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml index 794aa57b55a..cca7dc27b1c 100644 --- a/app/views/groups/_projects.html.haml +++ b/app/views/groups/_projects.html.haml @@ -1,11 +1 @@ -.top-area - .nav-controls - = form_tag request.original_url, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| - - if @projects.present? - = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control', spellcheck: false - - if can? current_user, :create_projects, @group - = link_to new_project_path(namespace_id: @group.id), class: 'btn btn-new pull-right' do - = icon('plus') - New Project - -= render 'shared/projects/list', projects: @projects, stars: false, skip_namespace: true += render 'shared/projects/list', projects: projects, stars: false, skip_namespace: true diff --git a/app/views/groups/_shared_projects.html.haml b/app/views/groups/_shared_projects.html.haml new file mode 100644 index 00000000000..b1694c919d0 --- /dev/null +++ b/app/views/groups/_shared_projects.html.haml @@ -0,0 +1 @@ += render 'shared/projects/list', projects: projects, stars: false, skip_namespace: false diff --git a/app/views/groups/activity.html.haml b/app/views/groups/activity.html.haml new file mode 100644 index 00000000000..f73e1d9e865 --- /dev/null +++ b/app/views/groups/activity.html.haml @@ -0,0 +1,9 @@ += content_for :meta_tags do + - if current_user + = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") + +- page_title "Activity" +- header_title group_title(@group, "Activity", activity_group_path(@group)) + +%section.activities + = render 'activities' diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 3430f56a9c9..83936d39b16 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -23,6 +23,15 @@ %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-sm remove-avatar" + .form-group + %hr + = f.label :share_with_group_lock, class: 'control-label' do + Share with group lock + .col-sm-10 + .checkbox + = f.check_box :share_with_group_lock + %span.descr Prevent sharing a project with another group within this group + .form-actions = f.submit 'Save group', class: "btn btn-save" diff --git a/app/views/groups/milestones/_issue.html.haml b/app/views/groups/milestones/_issue.html.haml deleted file mode 100644 index 9b85d83d6d8..00000000000 --- a/app/views/groups/milestones/_issue.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%li{ id: dom_id(issue, 'sortable'), class: 'issue-row', 'data-iid' => issue.iid } - %span.milestone-row - - project = issue.project - %strong #{project.name} · - = link_to [project.namespace.becomes(Namespace), project, issue] do - %span.cgray ##{issue.iid} - = link_to_gfm issue.title, [project.namespace.becomes(Namespace), project, issue], title: issue.title - .pull-right.assignee-icon - - if issue.assignee - = image_tag avatar_icon(issue.assignee, 16), class: "avatar s16", alt: '' diff --git a/app/views/groups/milestones/_issues.html.haml b/app/views/groups/milestones/_issues.html.haml deleted file mode 100644 index 9f350b772bd..00000000000 --- a/app/views/groups/milestones/_issues.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.panel.panel-default - .panel-heading= title - %ul{ class: "well-list issues-sortable-list" } - - if issues - - issues.each do |issue| - = render 'issue', issue: issue diff --git a/app/views/groups/milestones/_merge_request.html.haml b/app/views/groups/milestones/_merge_request.html.haml deleted file mode 100644 index e3aa4aad198..00000000000 --- a/app/views/groups/milestones/_merge_request.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%li{ id: dom_id(merge_request, 'sortable'), class: 'mr-row', 'data-iid' => merge_request.iid } - %span.milestone-row - - project = merge_request.project - %strong #{project.name} · - = link_to [project.namespace.becomes(Namespace), project, merge_request] do - %span.cgray ##{merge_request.iid} - = link_to_gfm merge_request.title, [project.namespace.becomes(Namespace), project, merge_request], title: merge_request.title - .pull-right.assignee-icon - - if merge_request.assignee - = image_tag avatar_icon(merge_request.assignee, 16), class: "avatar s16", alt: '' diff --git a/app/views/groups/milestones/_merge_requests.html.haml b/app/views/groups/milestones/_merge_requests.html.haml deleted file mode 100644 index 50057e2c636..00000000000 --- a/app/views/groups/milestones/_merge_requests.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.panel.panel-default - .panel-heading= title - %ul{ class: "well-list merge_requests-sortable-list" } - - if merge_requests - - merge_requests.each do |merge_request| - = render 'merge_request', merge_request: merge_request diff --git a/app/views/groups/milestones/_milestone.html.haml b/app/views/groups/milestones/_milestone.html.haml index a20bf75bc39..4c4e0a26728 100644 --- a/app/views/groups/milestones/_milestone.html.haml +++ b/app/views/groups/milestones/_milestone.html.haml @@ -1,29 +1,5 @@ -%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) } - .row - .col-sm-6 - %strong - = link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title, title: milestone.title) - .col-sm-6 - .pull-right.light #{milestone.percent_complete}% complete - .row - .col-sm-6 - = link_to issues_group_path(@group, milestone_title: milestone.title) do - = pluralize milestone.issue_count, 'Issue' - · - = link_to merge_requests_group_path(@group, milestone_title: milestone.title) do - = pluralize milestone.merge_requests_count, 'Merge Request' - .col-sm-6 - = milestone_progress_bar(milestone) - .row - .col-sm-6 - %div - - milestone.milestones.each do |milestone| - = link_to milestone_path(milestone) do - %span.label.label-gray - = milestone.project.name - .col-sm-6 - - if can?(current_user, :admin_milestones, @group) - - if milestone.closed? - = link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-xs btn-grouped btn-reopen" - - else - = link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-xs btn-close" += render 'shared/milestones/milestone', + milestone_path: group_milestone_path(@group, milestone.safe_title, title: milestone.title), + issues_path: issues_group_path(@group, milestone_title: milestone.title), + merge_requests_path: merge_requests_group_path(@group, milestone_title: milestone.title), + milestone: milestone diff --git a/app/views/groups/milestones/show.html.haml b/app/views/groups/milestones/show.html.haml index 1233da85524..fb6f0da28f8 100644 --- a/app/views/groups/milestones/show.html.haml +++ b/app/views/groups/milestones/show.html.haml @@ -1,112 +1,4 @@ -- page_title @milestone.title, "Milestones" = render "header_title" - -.detail-page-header - .status-box{ class: "status-box-#{@milestone.closed? ? 'closed' : 'open'}" } - - if @milestone.closed? - Closed - - else - Open - %span.identifier - Milestone #{@milestone.title} - .pull-right - - if can?(current_user, :admin_milestones, @group) - - if @milestone.active? - = link_to 'Close Milestone', group_milestone_path(@group, @milestone.safe_title, title: @milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-grouped btn-close" - - else - = link_to 'Reopen Milestone', group_milestone_path(@group, @milestone.safe_title, title: @milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-grouped btn-reopen" - -.detail-page-description.gray-content-block.second-block - %h2.title - = markdown escape_once(@milestone.title), pipeline: :single_line - -- if @milestone.complete? && @milestone.active? - .alert.alert-success.prepend-top-default - %span All issues for this milestone are closed. You may close the milestone now. - -.table-holder - %table.table - %thead - %tr - %th Project - %th Open issues - %th State - %th Due date - - @milestone.milestones.each do |milestone| - %tr - %td - = link_to "#{milestone.project.name}", namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) - %td - = milestone.issues.opened.count - %td - - if milestone.closed? - Closed - - else - Open - %td - = milestone.expires_at - -.context - %p.lead - Progress: - #{@milestone.closed_items_count} closed - – - #{@milestone.open_items_count} open - = milestone_progress_bar(@milestone) - -%ul.nav-links.no-top.no-bottom - %li.active - = link_to '#tab-issues', 'data-toggle' => 'tab' do - Issues - %span.badge= @milestone.issue_count - %li - = link_to '#tab-merge-requests', 'data-toggle' => 'tab' do - Merge Requests - %span.badge= @milestone.merge_requests_count - %li - = link_to '#tab-participants', 'data-toggle' => 'tab' do - Participants - %span.badge= @milestone.participants.count - -.tab-content - .tab-pane.active#tab-issues - .gray-content-block.middle-block - .pull-right - = link_to 'Browse Issues', issues_group_path(@group, milestone_title: @milestone.title), class: "btn btn-grouped" - - .oneline - All issues in this milestone - - .row.prepend-top-default - .col-md-6 - = render 'issues', title: "Open", issues: @milestone.opened_issues - .col-md-6 - = render 'issues', title: "Closed", issues: @milestone.closed_issues - - .tab-pane#tab-merge-requests - .gray-content-block.middle-block - .pull-right - = link_to 'Browse Merge Requests', merge_requests_group_path(@group, milestone_title: @milestone.title), class: "btn btn-grouped" - - .oneline - All merge requests in this milestone - - .row.prepend-top-default - .col-md-6 - = render 'merge_requests', title: "Open", merge_requests: @milestone.opened_merge_requests - .col-md-6 - = render 'merge_requests', title: "Closed", merge_requests: @milestone.closed_merge_requests - - .tab-pane#tab-participants - .gray-content-block.middle-block - .oneline - All participants to this milestone - - %ul.bordered-list - - @milestone.participants.each do |user| - %li - = link_to user, title: user.name, class: "darken" do - = image_tag avatar_icon(user, 32), class: "avatar s32" - %strong= truncate(user.name, lenght: 40) - %br - %small.cgray= user.username += render 'shared/milestones/top', milestone: @milestone, group: @group += render 'shared/milestones/summary', milestone: @milestone += render 'shared/milestones/tabs', milestone: @milestone, show_project_name: true diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 6148d8cb3d2..23a34ac36dd 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -27,31 +27,34 @@ .cover-desc.description = markdown(@group.description, pipeline: :description) - - %ul.nav-links - %li.active - = link_to "#activity", 'data-toggle' => 'tab' do - Activity - %li - = link_to "#projects", 'data-toggle' => 'tab' do - Projects - - if can?(current_user, :read_group, @group) %div{ class: container_class } - .tab-content - .tab-pane.active#activity - .activity-filter-block - - if current_user - = render "events/event_last_push", event: @last_push - - = render 'shared/event_filter' + .top-area + %ul.nav-links + %li.active + = link_to "#projects", 'data-toggle' => 'tab' do + All Projects + - if @shared_projects.present? + %li + = link_to "#shared", 'data-toggle' => 'tab' do + Shared Projects + .nav-controls + = form_tag request.original_url, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| + = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control', spellcheck: false + = render 'shared/projects/dropdown' + - if can? current_user, :create_projects, @group + = link_to new_project_path(namespace_id: @group.id), class: 'btn btn-new pull-right' do + = icon('plus') + New Project - .content_list{data: {href: events_group_path}} - = spinner - - .tab-pane#projects + .tab-content + .tab-pane.active#projects = render "projects", projects: @projects + - if @shared_projects.present? + .tab-pane#shared + = render "shared_projects", projects: @shared_projects + - else %p.nav-links.no-top No projects to show diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml index 82d2d4aabed..da3c3711cdd 100644 --- a/app/views/help/_shortcuts.html.haml +++ b/app/views/help/_shortcuts.html.haml @@ -22,6 +22,14 @@ %td.shortcut .key ? %td Show this dialog + %tr + %td.shortcut + - if browser.mac? + .key ⌘ shift p + - else + .key ctrl shift p + + %td Toggle Markdown preview %tbody %tr %th diff --git a/app/views/help/ui.html.haml b/app/views/help/ui.html.haml index a2c0a858930..d084559abc3 100644 --- a/app/views/help/ui.html.haml +++ b/app/views/help/ui.html.haml @@ -19,6 +19,8 @@ %li = link_to 'Buttons', '#buttons' %li + = link_to 'Dropdowns', '#dropdowns' + %li = link_to 'Panels', '#panels' %li = link_to 'Alerts', '#alerts' @@ -180,9 +182,9 @@ .nav-controls = text_field_tag 'sample', nil, class: 'form-control' .dropdown - %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} + %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} %span Sort by name - %b.caret + = icon('chevron-down') %ul.dropdown-menu %li %a Sort by date @@ -212,6 +214,227 @@ %button.btn.btn-danger{:type => "button"} Danger %button.btn.btn-link{:type => "button"} Link + %h2#dropdowns Dropdowns + + .example + .clearfix + .dropdown.inline.pull-left + %button.dropdown-menu-toggle{type: 'button', data: {toggle: 'dropdown'}} + Dropdown + = icon('chevron-down') + %ul.dropdown-menu + %li + %a{href: "#"} + Dropdown Option + .dropdown.inline.pull-right + %button.dropdown-menu-toggle{type: 'button', data: {toggle: 'dropdown'}} + Dropdown + = icon('chevron-down') + %ul.dropdown-menu.dropdown-menu-align-right + %li + %a{href: "#"} + Dropdown Option + .example + %div + .dropdown.inline + %button.dropdown-menu-toggle{type: 'button', data: {toggle: 'dropdown'}} + Dropdown + = icon('chevron-down') + %ul.dropdown-menu.dropdown-menu-selectable + %li + %a.is-active{href: "#"} + Dropdown Option + .example + %div + .dropdown.inline + %button.dropdown-menu-toggle{type: 'button', data: {toggle: 'dropdown'}} + Dropdown + = icon('chevron-down') + .dropdown-menu.dropdown-select.dropdown-menu-selectable + .dropdown-title + %span Dropdown Title + %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} + = icon('times') + .dropdown-input + %input.dropdown-input-field{type: "search", placeholder: "Filter results"} + = icon('search') + .dropdown-content + %ul + %li + %a.is-active{href: "#"} + Dropdown Option + %li + %a{href: "#"} + Dropdown Option + %li.divider + %li + %a{href: "#"} + Dropdown Option + %li + %a{href: "#"} + Dropdown Option + %li + %a{href: "#"} + Dropdown Option + %li + %a{href: "#"} + Dropdown Option + %li + %a{href: "#"} + Dropdown Option + .dropdown-footer + %strong Tip: + If an author is not a member of this project, you can still filter by his name while using the search field. + .dropdown.inline + %button.dropdown-menu-toggle{type: 'button', data: {toggle: 'dropdown'}} + Dropdown loading + = icon('chevron-down') + .dropdown-menu.dropdown-select.dropdown-menu-selectable.is-loading + .dropdown-title + %span Dropdown Title + %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} + = icon('times') + .dropdown-input + %input.dropdown-input-field{type: "search", placeholder: "Filter results"} + = icon('search') + .dropdown-content + %ul + %li + %a.is-active{href: "#"} + Dropdown Option + %li + %a{href: "#"} + Dropdown Option + %li.divider + %li + %a{href: "#"} + Dropdown Option + %li + %a{href: "#"} + Dropdown Option + %li + %a{href: "#"} + Dropdown Option + %li + %a{href: "#"} + Dropdown Option + %li + %a{href: "#"} + Dropdown Option + .dropdown-footer + %strong Tip: + If an author is not a member of this project, you can still filter by his name while using the search field. + .dropdown-loading + = icon('spinner spin') + + .example + %div + .dropdown.inline + %button.dropdown-menu-toggle{type: 'button', data: {toggle: 'dropdown'}} + Dropdown user + = icon('chevron-down') + .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-user + .dropdown-title + %span Dropdown Title + %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} + = icon('times') + .dropdown-input + %input.dropdown-input-field{type: "search", placeholder: "Filter results"} + = icon('search') + .dropdown-content + %ul + %li + %a.dropdown-menu-user-link.is-active{href: "#"} + = link_to_member_avatar(current_user, size: 30) + %strong.dropdown-menu-user-full-name + = current_user.name + .dropdown-menu-user-username + = current_user.to_reference + + .example + %div + .dropdown.inline + %button.dropdown-menu-toggle{type: 'button', data: {toggle: 'dropdown'}} + Dropdown page 2 + = icon('chevron-down') + .dropdown-menu.dropdown-select.dropdown-menu-selectable.dropdown-menu-user.dropdown-menu-paging.is-page-two + .dropdown-page-one + .dropdown-title + %button.dropdown-title-button.dropdown-menu-back{aria: {label: "Go back"}} + = icon('arrow-left') + %span Dropdown Title + %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} + = icon('times') + .dropdown-input + %input.dropdown-input-field{type: "search", placeholder: "Filter results"} + = icon('search') + .dropdown-content + %ul + %li + %a.dropdown-menu-user-link.is-active{href: "#"} + = link_to_member_avatar(current_user, size: 30) + %strong.dropdown-menu-user-full-name + = current_user.name + .dropdown-menu-user-username + = current_user.to_reference + .dropdown-page-two + .dropdown-title + %button.dropdown-title-button.dropdown-menu-back{aria: {label: "Go back"}} + = icon('arrow-left') + %span Create label + %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} + = icon('times') + .dropdown-input + %input.dropdown-input-field{type: "search", placeholder: "Name new label"} + .dropdown-content + %button.btn.btn-primary + Create + + .example + %div + .dropdown.inline + %button#js-project-dropdown.dropdown-menu-toggle{type: 'button', data: {toggle: 'dropdown'}} + Projects + = icon('chevron-down') + .dropdown-menu.dropdown-select.dropdown-menu-selectable + .dropdown-title + %span Go to project + %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} + = icon('times') + .dropdown-input + %input.dropdown-input-field{type: "search", placeholder: "Filter results"} + = icon('search') + .dropdown-content + .dropdown-loading + = icon('spinner spin') + :javascript + $('#js-project-dropdown').glDropdown({ + data: function (term, callback) { + Api.projects(term, "last_activity_at", function (data) { + callback(data); + }); + }, + text: function (project) { + return project.name_with_namespace || project.name; + }, + selectable: true, + fieldName: "author_id", + filterable: true, + search: { + fields: ['name_with_namespace'] + }, + id: function (data) { + return data.id; + }, + isSelected: function (data) { + return data.id === 2; + } + }) + + .example + %div + = dropdown_tag("Projects", options: { title: "Go to project", filter: true, placeholder: "Filter projects" }) + %h2#panels Panels .row diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 77d01a7736c..f3090b96702 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -46,6 +46,8 @@ %h1.title= title = render 'shared/outdated_browser' + - if @project && !@project.empty_repo? - :javascript - var findFileURL = "#{namespace_project_find_file_path(@project.namespace, @project, @ref || @project.repository.root_ref)}"; + - if ref = @ref || @project.repository.root_ref + :javascript + var findFileURL = "#{namespace_project_find_file_path(@project.namespace, @project, ref)}"; diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml index e5e2a59eaed..59411ae1da1 100644 --- a/app/views/layouts/nav/_group.html.haml +++ b/app/views/layouts/nav/_group.html.haml @@ -9,10 +9,15 @@ = nav_link(path: 'groups#show', html_options: {class: 'home'}) do = link_to group_path(@group), title: 'Home' do - = icon('dashboard fw') + = icon('group fw') %span Group - if can?(current_user, :read_group, @group) + = nav_link(path: 'groups#activity') do + = link_to activity_group_path(@group), title: 'Activity' do + = icon('dashboard fw') + %span + Activity - if current_user = nav_link(controller: [:group, :milestones]) do = link_to group_milestones_path(@group), title: 'Milestones' do diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index f3ded04419b..3b9d31a6fc5 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -17,7 +17,7 @@ = icon('gear fw') %span Account - = nav_link(path: ['profiles#applications', 'applications#edit', 'applications#show', 'applications#new', 'applications#create']) do + = nav_link(controller: 'oauth/applications') do = link_to applications_profile_path, title: 'Applications' do = icon('cloud fw') %span diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 319974e12c5..86b46e8c75e 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -16,7 +16,7 @@ = nav_link(path: 'projects#show', html_options: {class: 'home'}) do = link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do - = icon('home fw') + = icon('bookmark fw') %span Project = nav_link(path: 'projects#activity') do @@ -67,7 +67,7 @@ %span Issues - if @project.default_issues_tracker? - %span.count.issue_counter= number_with_delimiter(@project.issues.opened.count) + %span.count.issue_counter= number_with_delimiter(@project.issues.visible_to_user(current_user).opened.count) - if project_nav_tab? :merge_requests = nav_link(controller: :merge_requests) do diff --git a/app/views/layouts/nav/_project_settings.html.haml b/app/views/layouts/nav/_project_settings.html.haml index 970da78a5c9..dc3050f02e5 100644 --- a/app/views/layouts/nav/_project_settings.html.haml +++ b/app/views/layouts/nav/_project_settings.html.haml @@ -13,16 +13,22 @@ = icon('pencil-square-o fw') %span Project Settings + - if @project.allowed_to_share_with_group? + = nav_link(controller: :group_links) do + = link_to namespace_project_group_links_path(@project.namespace, @project), title: "Groups" do + = icon('share-square-o fw') + %span + Groups = nav_link(controller: :deploy_keys) do = link_to namespace_project_deploy_keys_path(@project.namespace, @project), title: 'Deploy Keys' do = icon('key fw') %span Deploy Keys = nav_link(controller: :hooks) do - = link_to namespace_project_hooks_path(@project.namespace, @project), title: 'Web Hooks' do + = link_to namespace_project_hooks_path(@project.namespace, @project), title: 'Webhooks' do = icon('link fw') %span - Web Hooks + Webhooks = nav_link(controller: :services) do = link_to namespace_project_services_path(@project.namespace, @project), title: 'Services' do = icon('cogs fw') diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index 325c68c69dc..2997f59d946 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -1,33 +1,9 @@ %html{lang: "en"} %head %meta{content: "text/html; charset=utf-8", "http-equiv" => "Content-Type"} - %title - GitLab - :css - img { - max-width: 100%; - height: auto; - } - p.details { - font-style:italic; - color:#777 - } - .footer p { - font-size:small; - color:#777 - } - pre.commit-message { - white-space: pre-wrap; - } - .file-stats a { - text-decoration: none; - } - .file-stats .new-file { - color: #090; - } - .file-stats .deleted-file { - color: #B00; - } + %title + GitLab + = stylesheet_link_tag 'notify' %body %div.content = yield @@ -42,12 +18,15 @@ - else #{link_to "View it on GitLab", @target_url}. %br - -# Don't link the host is the line below, one link in the email is easier to quickly click than two. + -# Don't link the host in the line below, one link in the email is easier to quickly click than two. You're receiving this email because of your account on #{Gitlab.config.gitlab.host}. If you'd like to receive fewer emails, you can - - if @sent_notification && @sent_notification.unsubscribable? - = link_to "unsubscribe", unsubscribe_sent_notification_url(@sent_notification) - from this thread or - adjust your notification settings. + - if @labels_url + adjust your #{link_to 'label subscriptions', @labels_url}. + - else + - if @sent_notification && @sent_notification.unsubscribable? + = link_to "unsubscribe", unsubscribe_sent_notification_url(@sent_notification) + from this thread or + adjust your notification settings. = email_action @target_url diff --git a/app/views/notify/_reassigned_issuable_email.text.erb b/app/views/notify/_reassigned_issuable_email.text.erb index 855d37429d9..daf20a226dd 100644 --- a/app/views/notify/_reassigned_issuable_email.text.erb +++ b/app/views/notify/_reassigned_issuable_email.text.erb @@ -1,6 +1,6 @@ Reassigned <%= issuable.class.model_name.human.titleize %> <%= issuable.iid %> -<%= url_for([issuable.project.namespace.becomes(Namespace), issuable.project, issuable, {only_path: false}]) %> +<%= url_for([issuable.project.namespace.becomes(Namespace), issuable.project, issuable, { only_path: false }]) %> Assignee changed <%= "from #{@previous_assignee.name}" if @previous_assignee -%> to <%= "#{issuable.assignee_id ? issuable.assignee_name : 'Unassigned'}" %> diff --git a/app/views/notify/_relabeled_issuable_email.html.haml b/app/views/notify/_relabeled_issuable_email.html.haml new file mode 100644 index 00000000000..80a0de255be --- /dev/null +++ b/app/views/notify/_relabeled_issuable_email.html.haml @@ -0,0 +1,3 @@ +%p + #{'Label'.pluralize(@label_names.size)} added: + %em= @label_names.to_sentence diff --git a/app/views/notify/_relabeled_issuable_email.text.erb b/app/views/notify/_relabeled_issuable_email.text.erb new file mode 100644 index 00000000000..6a83d79fd61 --- /dev/null +++ b/app/views/notify/_relabeled_issuable_email.text.erb @@ -0,0 +1,3 @@ +<%= 'Label'.pluralize(@label_names.size) %> added: <%= @label_names.to_sentence %> + +<%= url_for([issuable.project.namespace.becomes(Namespace), issuable.project, issuable, { only_path: false }]) %> diff --git a/app/views/notify/issue_moved_email.html.haml b/app/views/notify/issue_moved_email.html.haml new file mode 100644 index 00000000000..40f7d61fe19 --- /dev/null +++ b/app/views/notify/issue_moved_email.html.haml @@ -0,0 +1,6 @@ +%p + Issue was moved to another project. +%p + New issue: + = link_to namespace_project_issue_url(@new_project.namespace, @new_project, @new_issue) do + = @new_issue.title diff --git a/app/views/notify/issue_moved_email.text.erb b/app/views/notify/issue_moved_email.text.erb new file mode 100644 index 00000000000..b3bd43c2055 --- /dev/null +++ b/app/views/notify/issue_moved_email.text.erb @@ -0,0 +1,4 @@ +Issue was moved to another project. + +New issue location: +<%= namespace_project_issue_url(@new_project.namespace, @new_project, @new_issue) %> diff --git a/app/views/notify/relabeled_issue_email.html.haml b/app/views/notify/relabeled_issue_email.html.haml new file mode 100644 index 00000000000..b17b16e1814 --- /dev/null +++ b/app/views/notify/relabeled_issue_email.html.haml @@ -0,0 +1 @@ += render 'relabeled_issuable_email', issuable: @issue diff --git a/app/views/notify/relabeled_issue_email.text.erb b/app/views/notify/relabeled_issue_email.text.erb new file mode 100644 index 00000000000..eeced97f601 --- /dev/null +++ b/app/views/notify/relabeled_issue_email.text.erb @@ -0,0 +1 @@ +<%= render 'relabeled_issuable_email', issuable: @issue %> diff --git a/app/views/notify/relabeled_merge_request_email.html.haml b/app/views/notify/relabeled_merge_request_email.html.haml new file mode 100644 index 00000000000..9eaa9afa5b1 --- /dev/null +++ b/app/views/notify/relabeled_merge_request_email.html.haml @@ -0,0 +1 @@ += render 'relabeled_issuable_email', issuable: @merge_request diff --git a/app/views/notify/relabeled_merge_request_email.text.erb b/app/views/notify/relabeled_merge_request_email.text.erb new file mode 100644 index 00000000000..87bc80ead32 --- /dev/null +++ b/app/views/notify/relabeled_merge_request_email.text.erb @@ -0,0 +1 @@ +<%= render 'relabeled_issuable_email', issuable: @merge_request %> diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index 9fa96084f94..6efd119f260 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -5,114 +5,113 @@ .alert.alert-info Some options are unavailable for LDAP accounts -.account-page.prepend-top-default - .panel.panel-default.update-token - .panel-heading - Reset Private token - .panel-body - = form_for @user, url: reset_private_token_profile_path, method: :put do |f| - .data - %p - Your private token is used to access application resources without authentication. - %br - It can be used for atom feeds or the API. - %span.cred - Keep it secret! - - %p.cgray - - if current_user.private_token - = text_field_tag "token", current_user.private_token, class: "form-control" - - else - %span You don`t have one yet. Click generate to fix it. - - .form-actions - - if current_user.private_token - = f.submit 'Reset private token', data: { confirm: "Are you sure?" }, class: "btn btn-default" - - else - = f.submit 'Generate', class: "btn btn-default" - - .panel.panel-default - .panel-heading +.row.prepend-top-default + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0 + Private Token + %p + Your private token is used to access application resources without authentication. + .col-lg-9 + = form_for @user, url: reset_private_token_profile_path, method: :put, html: {class: "private-token"} do |f| + %p.cgray + - if current_user.private_token + = label_tag "token", "Private token", class: "label-light" + = text_field_tag "token", current_user.private_token, class: "form-control" + - else + %span You don`t have one yet. Click generate to fix it. + %p.help-block + It can be used for atom feeds or the API. Keep it secret! + .prepend-top-default + - if current_user.private_token + = f.submit 'Reset private token', data: { confirm: "Are you sure?" }, class: "btn btn-default" + - else + = f.submit 'Generate', class: "btn btn-default" +%hr +.row.prepend-top-default + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0 Two-factor Authentication - .panel-body - - if current_user.two_factor_enabled? - .pull-right - = link_to 'Disable Two-factor Authentication', profile_two_factor_auth_path, method: :delete, class: 'btn btn-close btn-sm', + %p + Increase your account's security by enabling two-factor authentication (2FA). + .col-lg-9 + %p + Status: #{current_user.two_factor_enabled? ? 'enabled' : 'disabled'} + - if !current_user.two_factor_enabled? + %p + Download the Google Authenticator application from App Store for iOS or Google Play for Android and scan this code. + More information is available in the #{link_to('documentation', help_page_path('profile', 'two_factor_authentication'))}. + .append-bottom-10 + = link_to 'Enable two-factor authentication', new_profile_two_factor_auth_path, class: 'btn btn-success' + - else + = link_to 'Disable Two-factor Authentication', profile_two_factor_auth_path, method: :delete, class: 'btn btn-danger', data: { confirm: 'Are you sure?' } - %p.text-success - %strong - Two-factor Authentication is enabled - %p - If you lose your recovery codes you can - %strong - = succeed ',' do - = link_to 'generate new ones', codes_profile_two_factor_auth_path, method: :post, data: { confirm: 'Are you sure?' } - invalidating all previous codes. - - - else - %p - Increase your account's security by enabling two-factor authentication (2FA). - %p - Each time you log in you’ll be required to provide your username and - password as usual, plus a randomly-generated code from your phone. - - .form-actions - = link_to 'Enable Two-factor Authentication', new_profile_two_factor_auth_path, class: 'btn btn-success' - - - if button_based_providers.any? - .panel.panel-default - .panel-heading +%hr +- if button_based_providers.any? + .row.prepend-top-default + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0 + Social sign-in + %p + Activate signin with one of the following services + .col-lg-9 + %label.label-light Connected Accounts - .panel-body - .oauth-buttons.append-bottom-10 - %p Click on icon to activate signin with one of the following services - - button_based_providers.each do |provider| - .btn-group - = link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: "btn btn-lg #{'active' if auth_active?(provider)}", "data-no-turbolink" => "true" - - - if auth_active?(provider) - = link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do - = icon('close') - - - if current_user.can_change_username? - .panel.panel-warning.update-username - .panel-heading - Change Username - .panel-body - = form_for @user, url: update_username_profile_path, method: :put, remote: true do |f| - %p - Changing your username will change path to all personal projects! - %div - .input-group - .input-group-addon - = "#{root_url}u/" - = f.text_field :username, required: true, class: 'form-control' - - .loading-gif.hide - %p - = icon('spinner spin') - Saving new username - .form-actions - = f.submit 'Save username', class: "btn btn-warning" + %p Click on icon to activate signin with one of the following services + - button_based_providers.each do |provider| + .provider-btn-group + .provider-btn-image + = provider_image_tag(provider) + - if auth_active?(provider) + = link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'provider-btn' do + Disconnect + - else + = link_to user_omniauth_authorize_path(provider), method: :post, class: "provider-btn #{'not-active' if !auth_active?(provider)}", "data-no-turbolink" => "true" do + Connect + %hr +- if current_user.can_change_username? + .row.prepend-top-default + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0.change-username-title + Change username + %p + Changing your username will change path to all personal projects! + .col-lg-9 + = form_for @user, url: update_username_profile_path, method: :put, remote: true, html: {class: "update-username"} do |f| + .form-group + = f.label :username, "Path", class: "label-light" + .input-group + .input-group-addon + = "#{root_url}u/" + = f.text_field :username, required: true, class: 'form-control' + .help-block + Current path: + = "#{root_url}u/#{current_user.username}" + .prepend-top-default + = f.button class: "btn btn-warning", type: "submit" do + = icon "spinner spin", class: "hidden loading-username" + Update username + %hr - - if signup_enabled? - .panel.panel-danger.remove-account - .panel-heading +- if signup_enabled? + .row.prepend-top-default + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0.remove-account-title Remove account - .panel-body - - if @user.can_be_removed? - %p Deleting an account has the following effects: - %ul - %li All user content like authored issues, snippets, comments will be removed - - rp = current_user.personal_projects.count - - unless rp.zero? - %li #{pluralize rp, 'personal project'} will be removed and cannot be restored - .form-actions - = link_to 'Delete account', user_registration_path, data: { confirm: "REMOVE #{current_user.name}? Are you sure?" }, method: :delete, class: "btn btn-remove" - - else - - if @user.solo_owned_groups.present? - %p - Your account is currently an owner in these groups: - %strong #{@user.solo_owned_groups.map(&:name).join(', ')} - %p - You must transfer ownership or delete these groups before you can delete your account. + .col-lg-9 + - if @user.can_be_removed? + %p + Deleting an account has the following effects: + %ul + %li All user content like authored issues, snippets, comments will be removed + - rp = current_user.personal_projects.count + - unless rp.zero? + %li #{pluralize rp, 'personal project'} will be removed and cannot be restored + = link_to 'Delete account', user_registration_path, data: { confirm: "REMOVE #{current_user.name}? Are you sure?" }, method: :delete, class: "btn btn-remove" + - else + - if @user.solo_owned_groups.present? + %p + Your account is currently an owner in these groups: + %strong #{@user.solo_owned_groups.map(&:name).join(', ')} + %p + You must transfer ownership or delete these groups before you can delete your account. +.append-bottom-default diff --git a/app/views/profiles/applications.html.haml b/app/views/profiles/applications.html.haml deleted file mode 100644 index 86f35823406..00000000000 --- a/app/views/profiles/applications.html.haml +++ /dev/null @@ -1,70 +0,0 @@ -- page_title "Applications" -- header_title page_title, applications_profile_path - -.alert.alert-help.prepend-top-default - - if user_oauth_applications? - Manage applications that can use GitLab as an OAuth provider, - and applications that you've authorized to use your account. - - else - Manage applications that you've authorized to use your account. - -- if user_oauth_applications? - .oauth-applications - %h3 - Your applications - .pull-right - = link_to 'New Application', new_oauth_application_path, class: 'btn btn-success' - - if @applications.any? - .table-holder - %table.table.table-striped - %thead - %tr - %th Name - %th Callback URL - %th Clients - %th - %th - %tbody - - @applications.each do |application| - %tr{:id => "application_#{application.id}"} - %td= link_to application.name, oauth_application_path(application) - %td - - application.redirect_uri.split.each do |uri| - %div= uri - %td= application.access_tokens.count - %td= link_to 'Edit', edit_oauth_application_path(application), class: 'btn btn-link btn-sm' - %td= render 'doorkeeper/applications/delete_form', application: application - -.oauth-authorized-applications.prepend-top-20 - - if user_oauth_applications? - %h3 - Authorized applications - - - if @authorized_tokens.any? - .table-holder - %table.table.table-striped - %thead - %tr - %th Name - %th Authorized At - %th Scope - %th - %tbody - - @authorized_apps.each do |app| - - token = app.authorized_tokens.order('created_at desc').first - %tr{:id => "application_#{app.id}"} - %td= app.name - %td= token.created_at - %td= token.scopes - %td= render 'doorkeeper/authorized_applications/delete_form', application: app - - @authorized_anonymous_tokens.each do |token| - %tr - %td - Anonymous - %div.help-block - %em Authorization was granted by entering your username and password in the application. - %td= token.created_at - %td= token.scopes - %td= render 'doorkeeper/authorized_applications/delete_form', token: token - - else - %p.light You don't have any authorized applications diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 3d1ba49491c..cd582ba7060 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -1,7 +1,4 @@ = form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit-user prepend-top-default" }, authenticity_token: true do |f| - = f.hidden_field :avatar_crop_x - = f.hidden_field :avatar_crop_y - = f.hidden_field :avatar_crop_size -if @user.errors.any? %div.alert.alert-danger %ul @@ -97,19 +94,3 @@ .prepend-top-default.append-bottom-default = f.submit 'Update profile settings', class: "btn btn-success" = link_to "Cancel", user_path(current_user), class: "btn btn-cancel" - -.modal.modal-profile-crop - .modal-dialog - .modal-content - .modal-header - %button.close{type: 'button', data: {dismiss: 'modal'}} - %span - × - %h4.modal-title - Crop your new profile picture - .modal-body - %p - %img.modal-profile-crop-image - .modal-footer - %button.btn.btn-primary.js-upload-user-avatar{:type => "button"} - Set new profile picture diff --git a/app/views/profiles/two_factor_auths/new.html.haml b/app/views/profiles/two_factor_auths/new.html.haml index b2830aa0834..5d342ef58e5 100644 --- a/app/views/profiles/two_factor_auths/new.html.haml +++ b/app/views/profiles/two_factor_auths/new.html.haml @@ -1,41 +1,41 @@ - page_title 'Two-factor Authentication', 'Account' -%h2.page-title Two-factor Authentication (2FA) -%p - Download the Google Authenticator application from App Store for iOS or Google - Play for Android and scan this code. - - More information is available in the #{link_to('documentation', help_page_path('profile', 'two_factor_authentication'))}. - -%hr - -= form_tag profile_two_factor_auth_path, method: :post, class: 'form-horizontal two-factor-new' do |f| - - if @error - .alert.alert-danger - = @error - .form-group - .col-lg-2.col-lg-offset-2 - = raw @qr_code - .col-lg-7.col-lg-offset-1.manual-instructions - %h3 Can't scan the code? - - %p - To add the entry manually, provide the following details to the - application on your phone. - - %dl - %dt Account - %dd= current_user.email - %dl - %dt Key - %dd= current_user.otp_secret.scan(/.{4}/).join(' ') - %dl - %dt Time based - %dd Yes - .form-group - = label_tag :pin_code, nil, class: "control-label" - .col-lg-10 - = text_field_tag :pin_code, nil, class: "form-control", required: true, autofocus: true - .form-actions - = submit_tag 'Submit', class: 'btn btn-success' - = link_to 'Configure it later', skip_profile_two_factor_auth_path, :method => :patch, class: 'btn btn-cancel' if two_factor_skippable? +.row.prepend-top-default + .col-lg-3 + %h4.prepend-top-0 + Two-factor Authentication (2FA) + %p + Increase your account's security by enabling two-factor authentication (2FA). + .col-lg-9 + %p + Status: #{current_user.two_factor_enabled? ? 'enabled' : 'disabled'} + %p + Download the Google Authenticator application from App Store for iOS or Google Play for Android and scan this code. + More information is available in the #{link_to('documentation', help_page_path('profile', 'two_factor_authentication'))}. + .row.append-bottom-10 + .col-md-3 + = raw @qr_code + .col-md-9 + .account-well + %p.prepend-top-0.append-bottom-0 + Can't scan the code? + %p.prepend-top-0.append-bottom-0 + To add the entry manually, provide the following details to the application on your phone. + %p.prepend-top-0.append-bottom-0 + Account: + = current_user.email + %p.prepend-top-0.append-bottom-0 + Key: + = current_user.otp_secret.scan(/.{4}/).join(' ') + %p.two-factor-new-manual-content + Time based: Yes + = form_tag profile_two_factor_auth_path, method: :post do |f| + - if @error + .alert.alert-danger + = @error + .form-group + = label_tag :pin_code, nil, class: "label-light" + = text_field_tag :pin_code, nil, class: "form-control", required: true + .prepend-top-default + = submit_tag 'Enable two-factor authentication', class: 'btn btn-success' + = link_to 'Configure it later', skip_profile_two_factor_auth_path, :method => :patch, class: 'btn btn-cancel' if two_factor_skippable? diff --git a/app/views/projects/_builds_settings.html.haml b/app/views/projects/_builds_settings.html.haml new file mode 100644 index 00000000000..95ab9ecf3e8 --- /dev/null +++ b/app/views/projects/_builds_settings.html.haml @@ -0,0 +1,60 @@ +%fieldset.builds-feature + %legend + Builds: + .form-group + .col-sm-offset-2.col-sm-10 + %p Get recent application code using the following command: + .radio + = f.label :build_allow_git_fetch_false do + = f.radio_button :build_allow_git_fetch, 'false' + %strong git clone + %br + %span.descr Slower but makes sure you have a clean dir before every build + .radio + = f.label :build_allow_git_fetch_true do + = f.radio_button :build_allow_git_fetch, 'true' + %strong git fetch + %br + %span.descr Faster + + .form-group + = f.label :build_timeout_in_minutes, 'Timeout', class: 'control-label' + .col-sm-10 + = f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0' + %p.help-block per build in minutes + .form-group + = f.label :build_coverage_regex, "Test coverage parsing", class: 'control-label' + .col-sm-10 + .input-group + %span.input-group-addon / + = f.text_field :build_coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered' + %span.input-group-addon / + %p.help-block + We will use this regular expression to find test coverage output in build trace. + Leave blank if you want to disable this feature + .bs-callout.bs-callout-info + %p Below are examples of regex for existing tools: + %ul + %li + Simplecov (Ruby) - + %code \(\d+.\d+\%\) covered + %li + pytest-cov (Python) - + %code \d+\%\s*$ + %li + phpunit --coverage-text --colors=never (PHP) - + %code ^\s*Lines:\s*\d+.\d+\% + + .form-group + .col-sm-offset-2.col-sm-10 + .checkbox + = f.label :public_builds do + = f.check_box :public_builds + %strong Public builds + .help-block Allow everyone to access builds for Public and Internal projects + + .form-group + = f.label :runners_token, "Runners token", class: 'control-label' + .col-sm-10 + = f.text_field :runners_token, class: "form-control", placeholder: 'xEeFCaDAB89' + %p.help-block The secure token used to checkout project. diff --git a/app/views/projects/blob/_image.html.haml b/app/views/projects/blob/_image.html.haml index 3c11b97921f..18caddabd39 100644 --- a/app/views/projects/blob/_image.html.haml +++ b/app/views/projects/blob/_image.html.haml @@ -6,4 +6,4 @@ - blob = sanitize_svg(blob) %img{src: "data:#{blob.mime_type};base64,#{Base64.encode64(blob.data)}"} - else - %img{src: namespace_project_raw_path(@project.namespace, @project, @id)} + %img{src: namespace_project_raw_path(@project.namespace, @project, tree_join(@commit.id, blob.path))} diff --git a/app/views/projects/branches/destroy.js.haml b/app/views/projects/branches/destroy.js.haml index 882a4d0c5e2..a21ddaf4930 100644 --- a/app/views/projects/branches/destroy.js.haml +++ b/app/views/projects/branches/destroy.js.haml @@ -1 +1 @@ -$('.js-totalbranch-count').html("#{@repository.branches.size}") +$('.js-totalbranch-count').html("#{@repository.branch_count}") diff --git a/app/views/projects/builds/index.html.haml b/app/views/projects/builds/index.html.haml index 14f1d3226bb..811d304ea75 100644 --- a/app/views/projects/builds/index.html.haml +++ b/app/views/projects/builds/index.html.haml @@ -55,7 +55,6 @@ %th Coverage %th - - @builds.each do |build| - = render 'projects/commit_statuses/commit_status', commit_status: build, commit_sha: true, stage: true, coverage: @project.build_coverage_enabled?, allow_retry: true + = render @builds, commit_sha: true, stage: true, allow_retry: true, coverage: @project.build_coverage_enabled? = paginate @builds, theme: 'gitlab' diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index 8eec78a557c..b02aee3db21 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -13,9 +13,10 @@ = link_to "merge request ##{merge_request.iid}", merge_request_path(merge_request) #up-build-trace - - if @commit.matrix_for_ref?(@build.ref) + - builds = @build.commit.matrix_builds(@build) + - if builds.size > 1 %ul.nav-links.no-top.no-bottom - - @commit.latest_builds_for_ref(@build.ref).each do |build| + - builds.each do |build| %li{class: ('active' if build == @build) } = link_to namespace_project_build_path(@project.namespace, @project, build) do = ci_icon_for_status(build.status) @@ -44,7 +45,7 @@ .pull-right #{time_ago_with_tooltip(@build.finished_at) if @build.finished_at} - - if @build.show_warning? + - if @build.stuck? - unless @build.any_runners_online? .bs-callout.bs-callout-warning %p @@ -70,7 +71,7 @@ .autoscroll-container %button.btn.btn-success.btn-sm#autoscroll-button{:type => "button", :data => {:state => 'disabled'}} enable autoscroll .clearfix - .scroll-controls + #js-build-scroll.scroll-controls = link_to '#up-build-trace', class: 'btn' do %i.fa.fa-angle-up = link_to '#down-build-trace', class: 'btn' do @@ -100,12 +101,12 @@ %h4.title Build artifacts .center .btn-group{ role: :group } - = link_to @build.artifacts_download_url, class: 'btn btn-sm btn-primary' do + = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-primary' do = icon('download') Download - if @build.artifacts_metadata? - = link_to @build.artifacts_browse_url, class: 'btn btn-sm btn-primary' do + = link_to browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-primary' do = icon('folder-open') Browse @@ -115,10 +116,10 @@ - if can?(current_user, :update_build, @project) .center .btn-group{ role: :group } - - if @build.cancel_url - = link_to "Cancel", @build.cancel_url, class: 'btn btn-sm btn-danger', method: :post - - elsif @build.retry_url - = link_to "Retry", @build.retry_url, class: 'btn btn-sm btn-primary', method: :post + - if @build.active? + = link_to "Cancel", cancel_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-danger', method: :post + - elsif @build.retryable? + = link_to "Retry", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-primary', method: :post - if @build.erasable? = link_to erase_namespace_project_build_path(@project.namespace, @project, @build), diff --git a/app/views/projects/buttons/_download.html.haml b/app/views/projects/buttons/_download.html.haml index 14ee2263b7d..6a60cfeff76 100644 --- a/app/views/projects/buttons/_download.html.haml +++ b/app/views/projects/buttons/_download.html.haml @@ -1,4 +1,4 @@ - unless @project.empty_repo? - if can? current_user, :download_code, @project - = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: @ref, format: 'zip'), class: 'btn has_tooltip', rel: 'nofollow', title: "Download ZIP" do + = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: @ref, format: 'zip'), class: 'btn has_tooltip', data: {container: "body"}, rel: 'nofollow', title: "Download ZIP" do = icon('download') diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml new file mode 100644 index 00000000000..d22d1da8402 --- /dev/null +++ b/app/views/projects/ci/builds/_build.html.haml @@ -0,0 +1,76 @@ +%tr.build + %td.status + - if can?(current_user, :read_build, build) + = ci_status_with_icon(build.status, namespace_project_build_url(build.project.namespace, build.project, build)) + - else + = ci_status_with_icon(build.status) + + %td.build-link + - if can?(current_user, :read_build, build) + = link_to namespace_project_build_url(build.project.namespace, build.project, build) do + %strong ##{build.id} + - else + %strong ##{build.id} + + - if build.stuck? + %i.fa.fa-warning.text-warning + + - if defined?(commit_sha) && commit_sha + %td + = link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "monospace" + + %td + - if build.ref + = link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref) + - else + .light none + + - if defined?(runner) && runner + %td + - if build.try(:runner) + = runner_link(build.runner) + - else + .light none + + - if defined?(stage) && stage + %td + = build.stage + + %td + = build.name + + .pull-right + - if build.tags.any? + - build.tags.each do |tag| + %span.label.label-primary + = tag + - if build.try(:trigger_request) + %span.label.label-info triggered + - if build.try(:allow_failure) + %span.label.label-danger allowed to fail + + %td.duration + - if build.duration + #{duration_in_words(build.finished_at, build.started_at)} + + %td.timestamp + - if build.finished_at + %span #{time_ago_with_tooltip(build.finished_at)} + + - if defined?(coverage) && coverage + %td.coverage + - if build.try(:coverage) + #{build.coverage}% + + %td + .pull-right + - if can?(current_user, :read_build, build) && build.artifacts? + = link_to download_namespace_project_build_artifacts_path(build.project.namespace, build.project, build), title: 'Download artifacts' do + %i.fa.fa-download + - if can?(current_user, :update_build, build) + - if build.active? + = link_to cancel_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Cancel' do + %i.fa.fa-remove.cred + - elsif defined?(allow_retry) && allow_retry && build.retryable? + = link_to retry_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Retry' do + %i.fa.fa-repeat diff --git a/app/views/projects/commit/_builds.html.haml b/app/views/projects/commit/_builds.html.haml index befad27666c..003b7c18d0e 100644 --- a/app/views/projects/commit/_builds.html.haml +++ b/app/views/projects/commit/_builds.html.haml @@ -43,8 +43,8 @@ %th Coverage %th - @ci_commit.refs.each do |ref| - = render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.statuses.for_ref(ref).latest.ordered, - locals: { coverage: @ci_commit.project.build_coverage_enabled?, stage: true, allow_retry: true } + - builds = @ci_commit.statuses.for_ref(ref).latest.ordered + = render builds, coverage: @ci_commit.project.build_coverage_enabled?, stage: true, allow_retry: true - if @ci_commit.retried.any? .gray-content-block.second-block @@ -64,5 +64,4 @@ - if @ci_commit.project.build_coverage_enabled? %th Coverage %th - = render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.retried, - locals: { coverage: @ci_commit.project.build_coverage_enabled?, stage: true } + = render @ci_commit.retried, coverage: @ci_commit.project.build_coverage_enabled?, stage: true diff --git a/app/views/projects/commit_statuses/_commit_status.html.haml b/app/views/projects/commit_statuses/_commit_status.html.haml deleted file mode 100644 index a3449d1ae05..00000000000 --- a/app/views/projects/commit_statuses/_commit_status.html.haml +++ /dev/null @@ -1,79 +0,0 @@ -%tr.commit_status - %td.status - - if can?(current_user, :read_commit_status, commit_status) && commit_status.target_url - = link_to commit_status.target_url, class: "ci-status ci-#{commit_status.status}" do - = ci_icon_for_status(commit_status.status) - = commit_status.status - - else - = ci_status_with_icon(commit_status.status) - - %td.commit_status-link - - if can?(current_user, :read_commit_status, commit_status) && commit_status.target_url - = link_to commit_status.target_url do - %strong ##{commit_status.id} - - else - %strong ##{commit_status.id} - - - if commit_status.show_warning? - %i.fa.fa-warning.text-warning{data: { toggle: "tooltip" }, title: "This build is stuck, open it to know more"} - - - if defined?(commit_sha) && commit_sha - %td - = link_to commit_status.short_sha, namespace_project_commit_path(commit_status.project.namespace, commit_status.project, commit_status.sha), class: "monospace" - - %td - - if commit_status.ref - = link_to commit_status.ref, namespace_project_commits_path(commit_status.project.namespace, commit_status.project, commit_status.ref) - - else - .light none - - - if defined?(runner) && runner - %td - - if commit_status.try(:runner) - = runner_link(commit_status.runner) - - else - .light none - - - if defined?(stage) && stage - %td - = commit_status.stage - - %td - = commit_status.name - - .pull-right - - if commit_status.tags.any? - - commit_status.tags.each do |tag| - %span.label.label-primary - = tag - - if commit_status.try(:trigger_request) - %span.label.label-info triggered - - if commit_status.try(:allow_failure) - %span.label.label-danger allowed to fail - - %td.duration - - if commit_status.duration - #{duration_in_words(commit_status.finished_at, commit_status.started_at)} - - %td.timestamp - - if commit_status.finished_at - %span #{time_ago_with_tooltip(commit_status.finished_at)} - - - if defined?(coverage) && coverage - %td.coverage - - if commit_status.try(:coverage) - #{commit_status.coverage}% - - %td - .pull-right - - if can?(current_user, :read_commit_status, commit_status) && commit_status.artifacts_download_url - = link_to commit_status.artifacts_download_url, title: 'Download artifacts' do - %i.fa.fa-download - - if can?(current_user, :update_commit_status, commit_status) - - if commit_status.active? - - if commit_status.cancel_url - = link_to commit_status.cancel_url, method: :post, title: 'Cancel' do - %i.fa.fa-remove.cred - - elsif defined?(allow_retry) && allow_retry && commit_status.retry_url - = link_to commit_status.retry_url, method: :post, title: 'Retry' do - %i.fa.fa-repeat diff --git a/app/views/projects/commits/_commit_list.html.haml b/app/views/projects/commits/_commit_list.html.haml index ce60fbdf032..bac9e244d36 100644 --- a/app/views/projects/commits/_commit_list.html.haml +++ b/app/views/projects/commits/_commit_list.html.haml @@ -1,11 +1,14 @@ +- commits, hidden = limited_commits(@commits) +- commits = Commit.decorate(commits, @project) + %div.panel.panel-default .panel-heading Commits (#{@commits.count}) - - if @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE + - if hidden > 0 %ul.well-list - - Commit.decorate(@commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE), @project).each do |commit| + - commits.each do |commit| = render "projects/commits/inline_commit", commit: commit, project: @project %li.warning-row.unstyled - other #{@commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE} commits hidden to prevent performance issues. + #{number_with_delimiter(hidden)} additional commits have been omitted to prevent performance issues. - else - %ul.well-list= render Commit.decorate(@commits, @project), project: @project + %ul.well-list= render commits, project: @project diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml index 6c631228002..a7e3c2478c2 100644 --- a/app/views/projects/commits/_commits.html.haml +++ b/app/views/projects/commits/_commits.html.haml @@ -1,7 +1,9 @@ - unless defined?(project) - project = @project -- @commits.group_by { |c| c.committed_date.to_date }.sort.reverse.each do |day, commits| +- commits, hidden = limited_commits(@commits) + +- commits.group_by { |c| c.committed_date.to_date }.sort.reverse.each do |day, commits| .row.commits-row .col-md-2.hidden-xs.hidden-sm %h5.commits-row-date @@ -13,3 +15,7 @@ %ul.bordered-list = render commits, project: project %hr.lists-separator + +- if hidden > 0 + .alert.alert-warning + #{number_with_delimiter(hidden)} additional commits have been omitted to prevent performance issues. diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml index 498c5e05b32..7a5b0d993db 100644 --- a/app/views/projects/commits/_head.html.haml +++ b/app/views/projects/commits/_head.html.haml @@ -15,9 +15,9 @@ = nav_link(html_options: {class: branches_tab_class}) do = link_to namespace_project_branches_path(@project.namespace, @project) do Branches - %span.badge.js-totalbranch-count= @repository.branches.size + %span.badge.js-totalbranch-count= @repository.branch_count = nav_link(controller: [:tags, :releases]) do = link_to namespace_project_tags_path(@project.namespace, @project) do Tags - %span.badge.js-totaltags-count= @repository.tags.length + %span.badge.js-totaltags-count= @repository.tag_count diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml index 6086ad3661e..2e1a37aa06d 100644 --- a/app/views/projects/diffs/_diffs.html.haml +++ b/app/views/projects/diffs/_diffs.html.haml @@ -20,4 +20,4 @@ - next unless blob = render 'projects/diffs/file', i: index, project: project, - diff_file: diff_file, diff_commit: diff_commit, blob: blob + diff_file: diff_file, diff_commit: diff_commit, blob: blob, diff_refs: diff_refs diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml index 3ac058a3bf8..3898bb202c5 100644 --- a/app/views/projects/diffs/_file.html.haml +++ b/app/views/projects/diffs/_file.html.haml @@ -42,13 +42,17 @@ .diff-content.diff-wrap-lines -# Skipp all non non-supported blobs - return unless blob.respond_to?('text?') - - if blob_text_viewable?(blob) - - if diff_view == 'parallel' - = render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob, index: i - - else - = render "projects/diffs/text_file", diff_file: diff_file, index: i - - elsif blob.image? - - old_file = project.repository.prev_blob_for_diff(diff_commit, diff_file) - = render "projects/diffs/image", diff_file: diff_file, old_file: old_file, file: blob, index: i + - if diff_file.too_large? + .nothing-here-block + This diff could not be displayed because it is too large. - else - .nothing-here-block No preview for this file type + - if blob_text_viewable?(blob) + - if diff_view == 'parallel' + = render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob, index: i + - else + = render "projects/diffs/text_file", diff_file: diff_file, index: i + - elsif blob.image? + - old_file = project.repository.prev_blob_for_diff(diff_commit, diff_file) + = render "projects/diffs/image", diff_file: diff_file, old_file: old_file, file: blob, index: i, diff_refs: diff_refs + - else + .nothing-here-block No preview for this file type diff --git a/app/views/projects/diffs/_image.html.haml b/app/views/projects/diffs/_image.html.haml index 752e92e2e6b..8367112a9cb 100644 --- a/app/views/projects/diffs/_image.html.haml +++ b/app/views/projects/diffs/_image.html.haml @@ -1,6 +1,7 @@ - diff = diff_file.diff - file_raw_path = namespace_project_raw_path(@project.namespace, @project, tree_join(@commit.id, diff.new_path)) -- old_file_raw_path = namespace_project_raw_path(@project.namespace, @project, tree_join(@commit.parent_id, diff.old_path)) +- old_commit_id = diff_refs.first.id +- old_file_raw_path = namespace_project_raw_path(@project.namespace, @project, tree_join(old_commit_id, diff.old_path)) - if diff.renamed_file || diff.new_file || diff.deleted_file .image %span.wrap @@ -12,7 +13,7 @@ %div.two-up.view %span.wrap .frame.deleted - %a{href: namespace_project_blob_path(@project.namespace, @project, tree_join(@commit.parent_id, diff.old_path))} + %a{href: namespace_project_blob_path(@project.namespace, @project, tree_join(old_commit_id, diff.old_path))} %img{src: old_file_raw_path} %p.image-info.hide %span.meta-filesize= "#{number_to_human_size old_file.size}" diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml new file mode 100644 index 00000000000..9464c8dc996 --- /dev/null +++ b/app/views/projects/diffs/_line.html.haml @@ -0,0 +1,26 @@ +- type = line.type +%tr.line_holder{id: line_code, class: type} + - case type + - when 'match' + = render "projects/diffs/match_line", {line: line.text, + line_old: line.old_pos, line_new: line.new_pos, bottom: false, new_file: diff_file.new_file} + - when 'nonewline' + %td.old_line.diff-line-num + %td.new_line.diff-line-num + %td.line_content.match= line.text + - else + %td.old_line.diff-line-num{class: type} + - link_text = raw(type == "new" ? " " : line.old_pos) + - if defined?(plain) && plain + = link_text + - else + = link_to link_text, "##{line_code}", id: line_code + - if @comments_allowed && can?(current_user, :create_note, @project) + = link_to_new_diff_note(line_code) + %td.new_line.diff-line-num{class: type, data: {linenumber: line.new_pos}} + - link_text = raw(type == "old" ? " " : line.new_pos) + - if defined?(plain) && plain + = link_text + - else + = link_to link_text, "##{line_code}", id: line_code + %td.line_content{class: "noteable_line #{type} #{line_code}", data: { line_code: line_code }}= diff_line_content(line.text) diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml index 9a8208202e4..e7169d7b599 100644 --- a/app/views/projects/diffs/_text_file.html.haml +++ b/app/views/projects/diffs/_text_file.html.haml @@ -8,26 +8,9 @@ - last_line = 0 - raw_diff_lines = diff_file.diff_lines.to_a - diff_file.highlighted_diff_lines.each_with_index do |line, index| - - type = line.type - - last_line = line.new_pos - line_code = generate_line_code(diff_file.file_path, line) - - line_old = line.old_pos - %tr.line_holder{ id: line_code, class: "#{type}" } - - if type == "match" - = render "projects/diffs/match_line", {line: line.text, - line_old: line_old, line_new: line.new_pos, bottom: false, new_file: diff_file.new_file} - - elsif type == 'nonewline' - %td.old_line.diff-line-num - %td.new_line.diff-line-num - %td.line_content.match= line.text - - else - %td.old_line.diff-line-num{class: type} - = link_to raw(type == "new" ? " " : line_old), "##{line_code}", id: line_code - - if @comments_allowed && can?(current_user, :create_note, @project) - = link_to_new_diff_note(line_code) - %td.new_line.diff-line-num{class: type, data: {linenumber: line.new_pos}} - = link_to raw(type == "old" ? " " : line.new_pos), "##{line_code}", id: line_code - %td.line_content{class: "noteable_line #{type} #{line_code}", data: { line_code: line_code }}= diff_line_content(line.text) + - last_line = line.new_pos + = render "projects/diffs/line", {line: line, diff_file: diff_file, line_code: line_code} - if @reply_allowed - comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at) diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index f2e56081afe..6d872cd0b21 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -84,6 +84,8 @@ %br %span.descr Share code pastes with others out of git repository + = render 'builds_settings', f: f + %fieldset.features %legend Project avatar: @@ -110,69 +112,6 @@ %hr = link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" - %fieldset.features - %legend - Continuous Integration - .form-group - .col-sm-offset-2.col-sm-10 - %p Get recent application code using the following command: - .radio - = f.label :build_allow_git_fetch_false do - = f.radio_button :build_allow_git_fetch, 'false' - %strong git clone - %br - %span.descr Slower but makes sure you have a clean dir before every build - .radio - = f.label :build_allow_git_fetch_true do - = f.radio_button :build_allow_git_fetch, 'true' - %strong git fetch - %br - %span.descr Faster - - .form-group - = f.label :build_timeout_in_minutes, 'Timeout', class: 'control-label' - .col-sm-10 - = f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0' - %p.help-block per build in minutes - .form-group - = f.label :build_coverage_regex, "Test coverage parsing", class: 'control-label' - .col-sm-10 - .input-group - %span.input-group-addon / - = f.text_field :build_coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered' - %span.input-group-addon / - %p.help-block - We will use this regular expression to find test coverage output in build trace. - Leave blank if you want to disable this feature - .bs-callout.bs-callout-info - %p Below are examples of regex for existing tools: - %ul - %li - Simplecov (Ruby) - - %code \(\d+.\d+\%\) covered - %li - pytest-cov (Python) - - %code \d+\%\s*$ - %li - phpunit --coverage-text --colors=never (PHP) - - %code ^\s*Lines:\s*\d+.\d+\% - - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :public_builds do - = f.check_box :public_builds - %strong Public builds - .help-block Allow everyone to access builds for Public and Internal projects - - %fieldset.features - %legend - Advanced settings - .form-group - = f.label :runners_token, "CI token", class: 'control-label' - .col-sm-10 - = f.text_field :runners_token, class: "form-control", placeholder: 'xEeFCaDAB89' - %p.help-block The secure token used to checkout project. .form-actions = f.submit 'Save changes', class: "btn btn-save" diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml new file mode 100644 index 00000000000..c15386b4883 --- /dev/null +++ b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml @@ -0,0 +1,58 @@ +%tr.generic_commit_status + %td.status + - if can?(current_user, :read_commit_status, generic_commit_status) && generic_commit_status.target_url + = ci_status_with_icon(generic_commit_status.status, generic_commit_status.target_url) + - else + = ci_status_with_icon(generic_commit_status.status) + + %td.generic_commit_status-link + - if can?(current_user, :read_commit_status, generic_commit_status) && generic_commit_status.target_url + = link_to generic_commit_status.target_url do + %strong ##{generic_commit_status.id} + - else + %strong ##{generic_commit_status.id} + + - if defined?(commit_sha) && commit_sha + %td + = link_to generic_commit_status.short_sha, namespace_project_commit_path(generic_commit_status.project.namespace, generic_commit_status.project, generic_commit_status.sha), class: "monospace" + + %td + - if generic_commit_status.ref + = link_to generic_commit_status.ref, namespace_project_commits_path(generic_commit_status.project.namespace, generic_commit_status.project, generic_commit_status.ref) + - else + .light none + + - if defined?(runner) && runner + %td + - if generic_commit_status.try(:runner) + = runner_link(generic_commit_status.runner) + - else + .light none + + - if defined?(stage) && stage + %td + = generic_commit_status.stage + + %td + = generic_commit_status.name + + .pull-right + - if generic_commit_status.tags.any? + - generic_commit_status.tags.each do |tag| + %span.label.label-primary + = tag + + %td.duration + - if generic_commit_status.duration + #{duration_in_words(generic_commit_status.finished_at, generic_commit_status.started_at)} + + %td.timestamp + - if generic_commit_status.finished_at + %span #{time_ago_with_tooltip(generic_commit_status.finished_at)} + + - if defined?(coverage) && coverage + %td.coverage + - if generic_commit_status.try(:coverage) + #{generic_commit_status.coverage}% + + %td diff --git a/app/views/projects/go_import.html.haml b/app/views/projects/go_import.html.haml deleted file mode 100644 index 87ac75a350f..00000000000 --- a/app/views/projects/go_import.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -!!! 5 -%html - %head - - web_url = [Gitlab.config.gitlab.url, @namespace, @id].join('/') - %meta{name: "go-import", content: "#{web_url.split('://')[1]} git #{web_url}.git"} diff --git a/app/views/projects/group_links/index.html.haml b/app/views/projects/group_links/index.html.haml new file mode 100644 index 00000000000..13f5fc141fa --- /dev/null +++ b/app/views/projects/group_links/index.html.haml @@ -0,0 +1,41 @@ +- page_title "Groups" +%h3.page_title Share project with other groups +%p.light + Projects can be stored in only one group at once. However you can share a project with other groups here. +%hr +- if @group_links.present? + .enabled-groups.panel.panel-default + .panel-heading + Already shared with + %ul.well-list + - @group_links.each do |group_link| + - group = group_link.group + %li + .pull-right + = link_to namespace_project_group_link_path(@project.namespace, @project, group_link), method: :delete, class: 'btn btn-sm' do + %i.icon-remove + disable sharing + = link_to group do + %strong + %i.icon-folder-open + = group.name + %br + .light up to #{group_link.human_access} + + +.available-groups + %h4 + Can be shared with + %div + = form_tag namespace_project_group_links_path(@project.namespace, @project), method: :post, class: 'form-horizontal' do + .form-group + = label_tag :link_group_id, 'Group', class: 'control-label' + .col-sm-10 + = groups_select_tag(:link_group_id, skip_group: @project.group.try(:path)) + .form-group + = label_tag :link_group_access, 'Max access level', class: 'control-label' + .col-sm-10 + = select_tag :link_group_access, options_for_select(ProjectGroupLink.access_options, ProjectGroupLink.default_access), class: "form-control" + .form-actions + = submit_tag "Share", class: "btn btn-create" + diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml index a0511819c9f..67d016bd871 100644 --- a/app/views/projects/hooks/index.html.haml +++ b/app/views/projects/hooks/index.html.haml @@ -1,9 +1,9 @@ -- page_title "Web Hooks" +- page_title "Webhooks" %h3.page-title - Web hooks + Webhooks %p.light - #{link_to "Web hooks ", help_page_path("web_hooks", "web_hooks"), class: "vlink"} can be + #{link_to "Webhooks ", help_page_path("web_hooks", "web_hooks"), class: "vlink"} can be used for binding events when something is happening within the project. %hr.clearfix @@ -70,12 +70,12 @@ = f.check_box :enable_ssl_verification %strong Enable SSL verification .form-actions - = f.submit "Add Web Hook", class: "btn btn-create" + = f.submit "Add Webhook", class: "btn btn-create" -if @hooks.any? .panel.panel-default .panel-heading - Web hooks (#{@hooks.count}) + Webhooks (#{@hooks.count}) %ul.well-list - @hooks.each do |hook| %li diff --git a/app/views/projects/issues/_discussion.html.haml b/app/views/projects/issues/_discussion.html.haml index eb9c225df2f..b151393abab 100644 --- a/app/views/projects/issues/_discussion.html.haml +++ b/app/views/projects/issues/_discussion.html.haml @@ -1,7 +1,7 @@ - content_for :note_actions do - if can?(current_user, :update_issue, @issue) - = link_to 'Reopen issue', issue_path(@issue, issue: {state_event: :reopen}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-reopen btn-comment js-note-target-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue' - = link_to 'Close issue', issue_path(@issue, issue: {state_event: :close}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-close btn-comment js-note-target-close #{issue_button_visibility(@issue, true)}", title: 'Close issue' + = link_to 'Reopen issue', issue_path(@issue, issue: {state_event: :reopen}, status_only: true, format: 'json'), data: {no_turbolink: true, original_text: "Reopen issue", alternative_text: "Comment & reopen issue"}, class: "btn btn-nr btn-grouped btn-reopen btn-comment js-note-target-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue' + = link_to 'Close issue', issue_path(@issue, issue: {state_event: :close}, status_only: true, format: 'json'), data: {no_turbolink: true, original_text: "Close issue", alternative_text: "Comment & close issue"}, class: "btn btn-nr btn-grouped btn-close btn-comment js-note-target-close #{issue_button_visibility(@issue, true)}", title: 'Close issue' #notes = render 'projects/notes/notes_with_form' diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index a44f34c2a68..4aa92d0b39e 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -3,10 +3,11 @@ .issue-check = check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue" - .issue-title + .issue-title.title %span.issue-title-text - = link_to_gfm issue.title, issue_path(issue), class: "title" - %ul.controls.light + = confidential_icon(issue) + = link_to_gfm issue.title, issue_path(issue) + %ul.controls - if issue.closed? %li CLOSED diff --git a/app/views/projects/issues/_merge_requests.html.haml b/app/views/projects/issues/_merge_requests.html.haml index 640a1962ffc..d6b38b327ff 100644 --- a/app/views/projects/issues/_merge_requests.html.haml +++ b/app/views/projects/issues/_merge_requests.html.haml @@ -1,4 +1,4 @@ --if @merge_requests.any? +- if @merge_requests.any? %h2.merge-requests-title = pluralize(@merge_requests.count, 'Related Merge Request') %ul.unstyled-list @@ -11,7 +11,7 @@ - elsif has_any_ci = icon('blank fw') %span.merge-request-id - \!#{merge_request.iid} + = merge_request.to_reference %span.merge-request-info %strong = link_to_gfm merge_request.title, merge_request_path(merge_request), class: "row_title" diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml new file mode 100644 index 00000000000..e66e4669d48 --- /dev/null +++ b/app/views/projects/issues/_new_branch.html.haml @@ -0,0 +1,5 @@ +- if current_user && can?(current_user, :push_code, @project) && @issue.can_be_worked_on?(current_user) + .pull-right + = link_to namespace_project_branches_path(@project.namespace, @project, branch_name: @issue.to_branch_name, issue_iid: @issue.iid), method: :post, class: 'btn', title: @issue.to_branch_name do + = icon('code-fork') + New Branch diff --git a/app/views/projects/issues/_related_branches.html.haml b/app/views/projects/issues/_related_branches.html.haml new file mode 100644 index 00000000000..b10cd03515f --- /dev/null +++ b/app/views/projects/issues/_related_branches.html.haml @@ -0,0 +1,15 @@ +- if @related_branches.any? + %h2.related-branches-title + = pluralize(@related_branches.count, 'Related Branch') + %ul.unstyled-list + - @related_branches.each do |branch| + %li + - sha = @project.repository.find_branch(branch).target + - ci_commit = @project.ci_commit(sha) if sha + - if ci_commit + %span.related-branch-ci-status + = render_ci_status(ci_commit) + %span.related-branch-info + %strong + = link_to namespace_project_compare_path(@project.namespace, @project, from: @project.default_branch, to: branch), class: "label-branch" do + = branch diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 617b0437807..52df3de8a27 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -18,24 +18,24 @@ %span.hidden-sm.hidden-md.hidden-lg = icon('circle-o') - %a.btn.btn-default.pull-right.hidden-sm.hidden-md.hidden-lg.gutter-toggle{ href: "#" } + %a.btn.btn-default.pull-right.visible-xs-block.gutter-toggle.js-sidebar-toggle{ href: "#" } = icon('angle-double-left') .issue-meta + = confidential_icon(@issue) %strong.identifier Issue ##{@issue.iid} %span.creator - by + opened .editor-details .editor-details + = time_ago_with_tooltip(@issue.created_at) + by %strong = link_to_member(@project, @issue.author, size: 24, mobile_classes: "hidden-xs") - %span.hidden-xs - = '@' + @issue.author.username %strong = link_to_member(@project, @issue.author, size: 24, mobile_classes: "hidden-sm hidden-md hidden-lg", by_username: true, avatar: false) - = time_ago_with_tooltip(@issue.created_at) .pull-right.issue-btn-group - if can?(current_user, :create_issue, @project) @@ -63,15 +63,14 @@ = markdown(@issue.description, cache_key: [@issue, "description"]) %textarea.hidden.js-task-list-field = @issue.description - - if @issue.updated_at != @issue.created_at - %small - Edited - = time_ago_with_tooltip(@issue.updated_at, placement: 'bottom', html_class: 'issue_edited_ago') + = edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue_edited_ago') .merge-requests = render 'merge_requests' + = render 'related_branches' - .content-block + .content-block.content-block-small + = render 'new_branch' = render 'votes/votes_block', votable: @issue .row diff --git a/app/views/projects/labels/_label.html.haml b/app/views/projects/labels/_label.html.haml index f7ddd30c5a9..4927d239c1e 100644 --- a/app/views/projects/labels/_label.html.haml +++ b/app/views/projects/labels/_label.html.haml @@ -10,6 +10,16 @@ = link_to_label(label) do = pluralize label.open_issues_count, 'open issue' + - if current_user + .label-subscription{data: {url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label)}} + .subscription-status{data: {status: label_subscription_status(label)}} + %button.btn.btn-sm.btn-info.subscribe-button + %span= label_subscription_toggle_button_text(label) + - if can? current_user, :admin_label, @project = link_to 'Edit', edit_namespace_project_label_path(@project.namespace, @project, label), class: 'btn btn-sm' = link_to 'Delete', namespace_project_label_path(@project.namespace, @project, label), class: 'btn btn-sm btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?"} + +- if current_user + :javascript + new Subscription('##{dom_id(label)} .label-subscription'); diff --git a/app/views/projects/merge_requests/_discussion.html.haml b/app/views/projects/merge_requests/_discussion.html.haml index 1c7de94acfd..393998f15b9 100644 --- a/app/views/projects/merge_requests/_discussion.html.haml +++ b/app/views/projects/merge_requests/_discussion.html.haml @@ -1,8 +1,8 @@ - content_for :note_actions do - if can?(current_user, :update_merge_request, @merge_request) - if @merge_request.open? - = link_to 'Close', merge_request_path(@merge_request, merge_request: {state_event: :close }), method: :put, class: "btn btn-nr btn-comment btn-grouped btn-close close-mr-link js-note-target-close", title: "Close merge request" + = link_to 'Close merge request', merge_request_path(@merge_request, merge_request: {state_event: :close }), method: :put, class: "btn btn-nr btn-comment btn-grouped btn-close close-mr-link js-note-target-close", title: "Close merge request", data: {original_text: "Close merge request", alternative_text: "Comment & close merge request"} - if @merge_request.closed? - = link_to 'Reopen', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-nr btn-comment btn-grouped btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request" + = link_to 'Reopen merge request', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-nr btn-comment btn-grouped btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request", data: {original_text: "Reopen merge request", alternative_text: "Comment & reopen merge request"} #notes= render "projects/notes/notes_with_form" diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index 18cf3f14f0b..13d0cbdde1d 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -1,8 +1,8 @@ %li{ class: mr_css_classes(merge_request) } - .merge-request-title + .merge-request-title.title %span.merge-request-title-text - = link_to_gfm merge_request.title, merge_request_path(merge_request), class: "title" - %ul.controls.light + = link_to_gfm merge_request.title, merge_request_path(merge_request) + %ul.controls - if merge_request.merged? %li MERGED diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index b262892ac65..ee5b9fd95a8 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -68,7 +68,7 @@ .tab-content #notes.notes.tab-pane.voting_notes - .content-block.oneline-block + .content-block.content-block-small.oneline-block = render 'votes/votes_block', votable: @merge_request .row diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml index 602f787e6cf..a23bd8d18d0 100644 --- a/app/views/projects/merge_requests/show/_mr_box.html.haml +++ b/app/views/projects/merge_requests/show/_mr_box.html.haml @@ -11,7 +11,4 @@ %textarea.hidden.js-task-list-field = @merge_request.description - - if @merge_request.updated_at != @merge_request.created_at - %small - Edited - = time_ago_with_tooltip(@merge_request.updated_at, placement: 'bottom') + = edited_time_ago_with_tooltip(@merge_request, placement: 'bottom') diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml index d24c12251f3..eeb605e2dc5 100644 --- a/app/views/projects/merge_requests/show/_mr_title.html.haml +++ b/app/views/projects/merge_requests/show/_mr_title.html.haml @@ -4,22 +4,25 @@ = @merge_request.state_human_name %span.hidden-sm.hidden-md.hidden-lg = icon(@merge_request.state_icon_name) - %a.btn.btn-default.pull-right.hidden-sm.hidden-md.hidden-lg.gutter-toggle{ href: "#" } + %a.btn.btn-default.pull-right.visible-xs-block.gutter-toggle.js-sidebar-toggle{ href: "#" } = icon('angle-double-left') .issue-meta %strong.identifier - Merge Request ##{@merge_request.iid} + %span.hidden-sm.hidden-md.hidden-lg + MR + %span.hidden-xs + Merge Request + !#{@merge_request.iid} %span.creator - by + opened .editor-details + = time_ago_with_tooltip(@merge_request.created_at) + by %strong = link_to_member(@project, @merge_request.author, size: 24, mobile_classes: "hidden-xs") - %span.hidden-xs - = '@' + @merge_request.author.username %strong = link_to_member(@project, @merge_request.author, size: 24, mobile_classes: "hidden-sm hidden-md hidden-lg", by_username: true, avatar: false) - = time_ago_with_tooltip(@merge_request.created_at) .issue-btn-group.pull-right - if can?(current_user, :update_merge_request, @merge_request) diff --git a/app/views/projects/merge_requests/widget/open/_wip.html.haml b/app/views/projects/merge_requests/widget/open/_wip.html.haml index 0cf16542cc1..c296422a9cf 100644 --- a/app/views/projects/merge_requests/widget/open/_wip.html.haml +++ b/app/views/projects/merge_requests/widget/open/_wip.html.haml @@ -1,5 +1,11 @@ %h4 This merge request is currently a Work In Progress -%p - When this merge request is ready, remove the "WIP" prefix from the title to allow it to be merged. +- if can?(current_user, :update_merge_request, @merge_request) + %p + When this merge request is ready, + = link_to remove_wip_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), method: :post do + remove the + %code WIP: + prefix from the title + to allow it to be merged. diff --git a/app/views/projects/milestones/_issue.html.haml b/app/views/projects/milestones/_issue.html.haml deleted file mode 100644 index ca51b8c745d..00000000000 --- a/app/views/projects/milestones/_issue.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%li{ id: dom_id(issue, 'sortable'), class: 'issue-row', 'data-iid' => issue.iid, 'data-url' => issue_path(issue) } - %span - = link_to_gfm issue.title, [@project.namespace.becomes(Namespace), @project, issue], title: issue.title - .issue-detail - = link_to [@project.namespace.becomes(Namespace), @project, issue] do - %span.issue-number ##{issue.iid} - - issue.labels.each do |label| - = render_colored_label(label) - - if issue.assignee - = image_tag avatar_icon(issue.assignee, 16), class: "avatar s24", alt: '' diff --git a/app/views/projects/milestones/_issues.html.haml b/app/views/projects/milestones/_issues.html.haml deleted file mode 100644 index 6f8a341e478..00000000000 --- a/app/views/projects/milestones/_issues.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -.panel.panel-default - .panel-heading - = title - .pull-right= issues.size - %ul{ class: "well-list issues-sortable-list", id: "issues-list-#{id}", "data-state" => id } - - issues.sort_by(&:position).each do |issue| - = render 'issue', issue: issue diff --git a/app/views/projects/milestones/_merge_request.html.haml b/app/views/projects/milestones/_merge_request.html.haml deleted file mode 100644 index a1033607c5d..00000000000 --- a/app/views/projects/milestones/_merge_request.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -%li{ id: dom_id(merge_request, 'sortable'), class: 'mr-row', 'data-iid' => merge_request.iid, 'data-url' => merge_request_path(merge_request) } - %span.str-truncated - = link_to [@project.namespace.becomes(Namespace), @project, merge_request] do - %span.cgray ##{merge_request.iid} - = link_to_gfm merge_request.title, [@project.namespace.becomes(Namespace), @project, merge_request], title: merge_request.title - .pull-right.assignee-icon - - if merge_request.assignee - = image_tag avatar_icon(merge_request.assignee, 16), class: "avatar s16", alt: '' diff --git a/app/views/projects/milestones/_merge_requests.html.haml b/app/views/projects/milestones/_merge_requests.html.haml deleted file mode 100644 index 9a5a02af215..00000000000 --- a/app/views/projects/milestones/_merge_requests.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -.panel.panel-default - .panel-heading= title - %ul{ class: "well-list merge_requests-sortable-list", id: "merge_requests-list-#{id}", "data-state" => id } - - merge_requests.sort_by(&:position).each do |merge_request| - = render 'merge_request', merge_request: merge_request diff --git a/app/views/projects/milestones/_milestone.html.haml b/app/views/projects/milestones/_milestone.html.haml index 67d95ab0364..77b566db6b6 100644 --- a/app/views/projects/milestones/_milestone.html.haml +++ b/app/views/projects/milestones/_milestone.html.haml @@ -1,31 +1,5 @@ -%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone) } - .row - .col-sm-6 - %strong - = link_to_gfm truncate(milestone.title, length: 100), namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) - - .col-sm-6 - .pull-right.light #{milestone.percent_complete}% complete - .row - .col-sm-6 - = link_to namespace_project_issues_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title) do - = pluralize milestone.issues.count, 'Issue' - · - = link_to namespace_project_merge_requests_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title) do - = pluralize milestone.merge_requests.count, 'Merge Request' - .col-sm-6 - = milestone_progress_bar(milestone) - - .row - .col-sm-6 - = render 'shared/milestone_expired', milestone: milestone - .col-sm-6 - - if can?(current_user, :admin_milestone, milestone.project) and milestone.active? - = link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-xs" do - = icon('pencil-square-o') - Edit - \ - = link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close" - = link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-xs btn-remove" do - = icon('trash-o') - Delete += render 'shared/milestones/milestone', + milestone_path: namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), + issues_path: namespace_project_issues_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title), + merge_requests_path: namespace_project_merge_requests_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title), + milestone: milestone diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index 2cae1ac4e2c..be63875ab34 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -42,102 +42,9 @@ = preserve do = markdown @milestone.description -- if @milestone.issues.any? && @milestone.can_be_closed? +- if @milestone.complete?(current_user) && @milestone.active? .alert.alert-success.prepend-top-default %span All issues for this milestone are closed. You may close milestone now. -.context.prepend-top-default - .milestone-summary - %h4 Progress - %strong= @milestone.issues.count - issues: - %span.milestone-stat - %strong= @milestone.open_items_count - open and - %strong= @milestone.closed_items_count - closed - %span.milestone-stat - %strong== #{@milestone.percent_complete}% - complete - %span.milestone-stat - %span.remaining-days= milestone_remaining_days(@milestone) - %span.pull-right.tab-issues-buttons - - if can?(current_user, :create_issue, @project) - = link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { milestone_id: @milestone.id }), class: "btn btn-grouped", title: "New Issue" do - %i.fa.fa-plus - New Issue - - if can?(current_user, :read_issue, @project) - = link_to 'Browse Issues', namespace_project_issues_path(@milestone.project.namespace, @milestone.project, milestone_title: @milestone.title), class: "btn btn-grouped" - %span.pull-right.tab-merge-requests-buttons.hidden - - if can?(current_user, :read_merge_request, @project) - = link_to 'Browse Merge Requests', namespace_project_merge_requests_path(@milestone.project.namespace, @milestone.project, milestone_title: @milestone.title), class: "btn btn-grouped" - - = milestone_progress_bar(@milestone) - -%ul.nav-links.no-top.no-bottom - %li.active - = link_to '#tab-issues', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do - Issues - %span.badge= @issues.count - %li - = link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-show' => '.tab-merge-requests-buttons' do - Merge Requests - %span.badge= @merge_requests.count - %li - = link_to '#tab-participants', 'data-toggle' => 'tab' do - Participants - %span.badge= @users.count - %li - = link_to '#tab-labels', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do - Labels - %span.badge= @labels.count - -.tab-content.milestone-content - .tab-pane.active#tab-issues - .row.prepend-top-default - .col-md-4 - = render('issues', title: 'Unstarted Issues (open and unassigned)', issues: @issues.opened.unassigned, id: 'unassigned') - .col-md-4 - = render('issues', title: 'Ongoing Issues (open and assigned)', issues: @issues.opened.assigned, id: 'ongoing') - .col-md-4 - = render('issues', title: 'Completed Issues (closed)', issues: @issues.closed, id: 'closed') - - .tab-pane#tab-merge-requests - .row.prepend-top-default - .col-md-3 - = render('merge_requests', title: 'Work in progress (open and unassigned)', merge_requests: @merge_requests.opened.unassigned, id: 'unassigned') - .col-md-3 - = render('merge_requests', title: 'Waiting for merge (open and assigned)', merge_requests: @merge_requests.opened.assigned, id: 'ongoing') - .col-md-3 - = render('merge_requests', title: 'Rejected (closed)', merge_requests: @merge_requests.closed, id: 'closed') - .col-md-3 - .panel.panel-primary - .panel-heading Merged - %ul.well-list - - @merge_requests.merged.each do |merge_request| - = render 'merge_request', merge_request: merge_request - - .tab-pane#tab-participants - %ul.bordered-list - - @users.each do |user| - %li - = link_to user, title: user.name, class: "darken" do - = image_tag avatar_icon(user, 32), class: "avatar s32" - %strong= truncate(user.name, lenght: 40) - %br - %small.cgray= user.username - - .tab-pane#tab-labels - %ul.bordered-list.manage-labels-list - - @labels.each do |label| - %li - = render_colored_label(label) - - args = [@milestone.project.namespace, @milestone.project, milestone_title: @milestone.title, label_name: label.title] - - options = args.extract_options! - - %span.issues-count - = link_to namespace_project_issues_path(*args, options.merge(state: 'opened')) do - = pluralize label.open_issues_count, 'open issue' - %span.issues-count - = link_to namespace_project_issues_path(*args, options.merge(state: 'closed')) do - = pluralize label.closed_issues_count, 'closed issue' += render 'shared/milestones/summary', milestone: @milestone, project: @project += render 'shared/milestones/tabs', milestone: @milestone diff --git a/app/views/projects/notes/_edit_form.html.haml b/app/views/projects/notes/_edit_form.html.haml index b5f076088c7..2999befffc6 100644 --- a/app/views/projects/notes/_edit_form.html.haml +++ b/app/views/projects/notes/_edit_form.html.haml @@ -1,10 +1,10 @@ .note-edit-form - = form_for note, url: namespace_project_note_path(@project.namespace, @project, note), method: :put, remote: true, authenticity_token: true, class: 'js-quick-submit' do |f| + = form_for note, url: namespace_project_note_path(@project.namespace, @project, note), method: :put, remote: true, authenticity_token: true, html: { class: 'edit-note js-quick-submit' } do |f| = note_target_fields(note) = render layout: 'projects/md_preview', locals: { preview_class: 'md-preview' } do = render 'projects/zen', f: f, attr: :note, classes: 'note_text js-note-text js-task-list-field' = render 'projects/notes/hints' - .note-form-actions + .note-form-actions.clearfix = f.submit 'Save Comment', class: 'btn btn-nr btn-save btn-grouped js-comment-button' = link_to 'Cancel', '#', class: 'btn btn-nr btn-cancel note-edit-cancel' diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml index 09740d8ea12..f675f092da1 100644 --- a/app/views/projects/notes/_form.html.haml +++ b/app/views/projects/notes/_form.html.haml @@ -13,6 +13,7 @@ .error-alert .note-form-actions.clearfix - = f.submit 'Add Comment', class: "btn btn-nr btn-create comment-btn btn-grouped js-comment-button" + = f.submit 'Comment', class: "btn btn-nr btn-create comment-btn btn-grouped js-comment-button" = yield(:note_actions) - %a.btn.btn-nr.btn-cancel.js-close-discussion-note-form Cancel + %a.btn.btn-cancel.js-note-discard{role: "button", data: {cancel_text: "Cancel"}} + Discard draft diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index 52972576aff..2cf32e6093d 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -27,20 +27,13 @@ %span.note-last-update %a{name: dom_id(note), href: "##{dom_id(note)}", title: 'Link here'} = time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note_created_ago') - - if note.updated_at != note.created_at - %span.note-updated-at - · - = icon('edit', title: 'edited') - = time_ago_with_tooltip(note.updated_at, placement: 'bottom', html_class: 'note_edited_ago') - - if note.updated_by && note.updated_by != note.author - by #{link_to_member(note.project, note.updated_by, avatar: false, author_class: nil)} - .note-body{class: note_editable?(note) ? 'js-task-list-container' : ''} .note-text = preserve do = markdown(note.note, pipeline: :note, cache_key: [note, "note"]) - if note_editable?(note) = render 'projects/notes/edit_form', note: note + = edited_time_ago_with_tooltip(note, placement: 'bottom', html_class: 'note_edited_ago', include_author: true) - if note.attachment.url .note-attachment @@ -54,4 +47,3 @@ = link_to delete_attachment_namespace_project_note_path(note.project.namespace, note.project, note), title: 'Delete this attachment', method: :delete, remote: true, data: { confirm: 'Are you sure you want to remove the attachment?' }, class: 'danger js-note-attachment-delete' do = icon('trash-o', class: 'cred') - .clear diff --git a/app/views/projects/project_members/_shared_group_members.html.haml b/app/views/projects/project_members/_shared_group_members.html.haml new file mode 100644 index 00000000000..62888e41935 --- /dev/null +++ b/app/views/projects/project_members/_shared_group_members.html.haml @@ -0,0 +1,21 @@ +- @project_group_links.each do |group_links| + - shared_group = group_links.group + - shared_group_users_count = group_links.group.group_members.count + .panel.panel-default + .panel-heading + Shared with + %strong #{shared_group.name} + group, members with + %strong #{group_links.human_access} + role (#{shared_group_users_count}) + - if current_user.can?(:admin_group, shared_group) + .panel-head-actions + = link_to group_group_members_path(shared_group), class: 'btn btn-sm' do + %i.fa.fa-pencil-square-o + Edit group members + %ul.content-list + - shared_group.group_members.order('access_level DESC').limit(20).each do |member| + = render 'groups/group_members/group_member', member: member, show_controls: false, show_roles: false + - if shared_group_users_count > 20 + %li + and #{shared_group_users_count - 20} more. For full list visit #{link_to 'group members page', group_group_members_path(shared_group)} diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml index 0f8848a5cbe..ebcfc907ebb 100644 --- a/app/views/projects/project_members/index.html.haml +++ b/app/views/projects/project_members/index.html.haml @@ -18,3 +18,6 @@ - if @group = render "group_members", members: @group_members + + - if @project_group_links.any? && @project.allowed_to_share_with_group? + = render "shared_group_members" diff --git a/app/views/projects/repositories/_download_archive.html.haml b/app/views/projects/repositories/_download_archive.html.haml index b9486a9b492..24658319060 100644 --- a/app/views/projects/repositories/_download_archive.html.haml +++ b/app/views/projects/repositories/_download_archive.html.haml @@ -10,7 +10,7 @@ %span.caret %span.sr-only Select Archive Format - %ul.col-xs-10.dropdown-menu{ role: 'menu' } + %ul.col-xs-10.dropdown-menu.dropdown-menu-align-right{ role: 'menu' } %li = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'zip'), rel: 'nofollow' do %i.fa.fa-download diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml index ec478a5963d..4ef544136a8 100644 --- a/app/views/search/_filter.html.haml +++ b/app/views/search/_filter.html.haml @@ -6,14 +6,21 @@ - else Any %b.caret - %ul.dropdown-menu - %li - = link_to search_filter_path(group_id: nil) do - Any - - current_user.authorized_groups.sort_by(&:name).each do |group| - %li - = link_to search_filter_path(group_id: group.id, project_id: nil) do - = group.name + .dropdown-menu.dropdown-select.dropdown-menu-selectable + .dropdown-title + %span Filter results by group + %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} + = icon('times') + .dropdown-content + %ul + %li + = link_to search_filter_path(group_id: nil), class: ("is-active" if !params[:group_id].present?) do + Any + %li.divider + - current_user.authorized_groups.sort_by(&:name).each do |group| + %li + = link_to search_filter_path(group_id: group.id, project_id: nil), class: ("is-active" if params[:group_id] == group.id.to_s) do + = group.name .dropdown.inline.prepend-left-10.project-filter %button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'} @@ -23,11 +30,18 @@ - else Any %b.caret - %ul.dropdown-menu - %li - = link_to search_filter_path(project_id: nil) do - Any - - current_user.authorized_projects.sort_by(&:name_with_namespace).each do |project| - %li - = link_to search_filter_path(project_id: project.id, group_id: nil) do - = project.name_with_namespace + .dropdown-menu.dropdown-select.dropdown-menu-selectable + .dropdown-title + %span Filter results by project + %button.dropdown-title-button.dropdown-menu-close{aria: {label: "Close"}} + = icon('times') + .dropdown-content + %ul + %li + = link_to search_filter_path(project_id: nil), class: ("is-active" if !params[:project_id].present?) do + Any + %li.divider + - current_user.authorized_projects.sort_by(&:name_with_namespace).each do |project| + %li + = link_to search_filter_path(project_id: project.id, group_id: nil), class: ("is-active" if params[:project_id] == project.id.to_s) do + = project.name_with_namespace diff --git a/app/views/search/results/_issue.html.haml b/app/views/search/results/_issue.html.haml index 45d700781f3..710f5613c81 100644 --- a/app/views/search/results/_issue.html.haml +++ b/app/views/search/results/_issue.html.haml @@ -1,5 +1,6 @@ .search-result-row %h4 + = confidential_icon(issue) = link_to [issue.project.namespace.becomes(Namespace), issue.project, issue] do %span.term.str-truncated= issue.title .pull-right ##{issue.iid} diff --git a/app/views/search/results/_wiki_blob.html.haml b/app/views/search/results/_wiki_blob.html.haml index f5859481d46..235106c4f74 100644 --- a/app/views/search/results/_wiki_blob.html.haml +++ b/app/views/search/results/_wiki_blob.html.haml @@ -2,9 +2,9 @@ .blob-result .file-holder .file-title - = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_blob.filename) do + = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_blob.basename) do %i.fa.fa-file %strong - = wiki_blob.filename + = wiki_blob.basename .file-content.code.term = render 'shared/file_highlight', blob: wiki_blob, first_line_number: wiki_blob.startline diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml index faf7e49ed29..974751d9970 100644 --- a/app/views/shared/_clone_panel.html.haml +++ b/app/views/shared/_clone_panel.html.haml @@ -8,11 +8,9 @@ = icon('angle-down') %ul.dropdown-menu.dropdown-menu-right.clone-options-dropdown %li - %a#ssh-selector{href: @project.ssh_url_to_repo} - SSH + = ssh_clone_button(project) %li - %a#http-selector{href: @project.http_url_to_repo} - HTTPS + = http_clone_button(project) = text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true .input-group-btn diff --git a/app/views/shared/_label_row.html.haml b/app/views/shared/_label_row.html.haml index 8134b15d245..4b47b0291be 100644 --- a/app/views/shared/_label_row.html.haml +++ b/app/views/shared/_label_row.html.haml @@ -1,4 +1,4 @@ %span.label-row - = link_to_label(label) + = link_to_label(label, tooltip: false) %span.prepend-left-10 = markdown(label.description, pipeline: :single_line) diff --git a/app/views/shared/groups/_group.html.haml b/app/views/shared/groups/_group.html.haml index fb9a8db0889..f172350f5ff 100644 --- a/app/views/shared/groups/_group.html.haml +++ b/app/views/shared/groups/_group.html.haml @@ -10,7 +10,7 @@ %i.fa.fa-cogs = link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Leave this group' do - %i.fa.fa-sign-out + = icon('sign-out') .stats %span @@ -22,12 +22,13 @@ = number_with_delimiter(group.users.count) = image_tag group_icon(group), class: "avatar s40 hidden-xs" - = link_to group, class: 'group-name title' do - = group.name + .title + = link_to group, class: 'group-name' do + = group.name - - if group_member - as - %span #{group_member.human_access} + - if group_member + as + %span #{group_member.human_access} - if group.description.present? .description diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml index e55159d996b..ac20f7d1f7e 100644 --- a/app/views/shared/issuable/_filter.html.haml +++ b/app/views/shared/issuable/_filter.html.haml @@ -7,22 +7,22 @@ class: "check_all_issues left" .issues-other-filters .filter-item.inline - = users_select_tag(:author_id, selected: params[:author_id], - placeholder: 'Author', class: 'trigger-submit', any_user: "Any Author", first_user: true, current_user: true) + - if params[:author_id] + = hidden_field_tag(:author_id, params[:author_id]) + = dropdown_tag(user_dropdown_label(params[:author_id], "Author"), options: { toggle_class: "js-user-search js-filter-submit js-author-search", title: "Filter by author", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-author", + placeholder: "Search authors", data: { any_user: "Any Author", first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), selected: params[:author_id], field_name: "author_id", default_label: "Author" } }) .filter-item.inline - = users_select_tag(:assignee_id, selected: params[:assignee_id], - placeholder: 'Assignee', class: 'trigger-submit', any_user: "Any Assignee", null_user: true, first_user: true, current_user: true) + - if params[:assignee_id] + = hidden_field_tag(:assignee_id, params[:assignee_id]) + = dropdown_tag(user_dropdown_label(params[:assignee_id], "Assignee"), options: { toggle_class: "js-user-search js-filter-submit js-assignee-search", title: "Filter by assignee", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee", + placeholder: "Search assignee", data: { any_user: "Any Assignee", first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: (@project.id if @project), selected: params[:assignee_id], field_name: "assignee_id", default_label: "Assignee" } }) .filter-item.inline.milestone-filter - = select_tag('milestone_title', projects_milestones_options, - class: 'select2 trigger-submit', include_blank: true, - data: {placeholder: 'Milestone'}) + = render "shared/issuable/milestone_dropdown" .filter-item.inline.labels-filter - = select_tag('label_name', projects_labels_options, - class: 'select2 trigger-submit', include_blank: true, - data: {placeholder: 'Label'}) + = render "shared/issuable/label_dropdown" .pull-right = render 'shared/sort_dropdown' @@ -31,11 +31,18 @@ .issues_bulk_update.hide = form_tag bulk_update_namespace_project_issues_path(@project.namespace, @project), method: :post do .filter-item.inline - = select_tag('update[state_event]', options_for_select([['Open', 'reopen'], ['Closed', 'close']]), include_blank: true, data: { placeholder: "Status" }) + = dropdown_tag("Status", options: { toggle_class: "js-issue-status", title: "Change status", dropdown_class: "dropdown-menu-selectable", data: { field_name: "update[state_event]" } } ) do + %ul + %li + %a{href: "#", data: {id: "reopen"}} Open + %li + %a{href: "#", data: {id: "close"}} Closed .filter-item.inline - = users_select_tag('update[assignee_id]', placeholder: 'Assignee', null_user: true, first_user: true, current_user: true) + = dropdown_tag("Assignee", options: { toggle_class: "js-user-search", title: "Assign to", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable", + placeholder: "Search authors", data: { first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: @project.id, field_name: "update[assignee_id]" } }) .filter-item.inline - = select_tag('update[milestone_id]', bulk_update_milestone_options, include_blank: true, data: { placeholder: "Milestone" }) + = dropdown_tag("Milestone", options: { title: "Assign milestone", toggle_class: 'js-milestone-select', filter: true, dropdown_class: "dropdown-menu-selectable", + placeholder: "Search milestones", data: { show_no: true, field_name: "update[milestone_id]", project_id: @project.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :js), use_id: true } }) = hidden_field_tag 'update[issues_ids]', [] = hidden_field_tag :state_event, params[:state_event] .filter-item.inline @@ -47,6 +54,9 @@ :javascript new UsersSelect(); + new LabelsSelect(); + new MilestoneSelect(); + new IssueStatusSelect(); $('form.filter-form').on('submit', function (event) { event.preventDefault(); Turbolinks.visit(this.action + '&' + $(this).serialize()); diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index d5a4aad05d9..1740b128ee4 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -13,12 +13,21 @@ - if issuable.is_a?(MergeRequest) %p.help-block - - if issuable.work_in_progress? - Remove the <code>WIP</code> prefix from the title to allow this - <strong>Work In Progress</strong> merge request to be merged when it's ready. - - else - Start the title with <code>[WIP]</code> or <code>WIP:</code> to prevent a - <strong>Work In Progress</strong> merge request from being merged before it's ready. + .js-wip-explanation + %a.js-toggle-wip{href: ""} + Remove the + %code WIP: + prefix from the title + to allow this + %strong Work In Progress + merge request to be merged when it's ready. + .js-no-wip-explanation + %a.js-toggle-wip{href: ""} + Start the title with + %code WIP: + to prevent a + %strong Work In Progress + merge request from being merged before it's ready. .form-group.detail-page-description = f.label :description, 'Description', class: 'control-label' .col-sm-10 @@ -29,6 +38,15 @@ = render 'projects/notes/hints' .clearfix .error-alert + +- if issuable.is_a?(Issue) && !issuable.project.private? + .form-group + .col-sm-offset-2.col-sm-10 + .checkbox + = f.label :confidential do + = f.check_box :confidential + This issue is confidential and should only be visible to team members + - if can?(current_user, :"admin_#{issuable.to_ability_name}", issuable.project) %hr .form-group @@ -67,13 +85,26 @@ - if can? current_user, :admin_label, issuable.project = link_to 'Create new label', new_namespace_project_label_path(issuable.project.namespace, issuable.project), target: :blank +- if issuable.can_move?(current_user) + %hr + .form-group + = label_tag :move_to_project_id, 'Move', class: 'control-label' + .col-sm-10 + - projects = project_options(issuable, current_user, ability: :admin_issue) + = select_tag(:move_to_project_id, projects, include_blank: true, + class: 'select2', data: { placeholder: 'Select project' }) + + %span{ data: { toggle: 'tooltip', placement: 'auto top' }, style: 'cursor: default', + title: 'Moving an issue will copy the discussion to a different project and close it here. All participants will be notified of the new location.' } + = icon('question-circle') + - if issuable.is_a?(MergeRequest) %hr - - if @merge_request.new_record? - .form-group - = f.label :source_branch, class: 'control-label' - .col-sm-10 - = f.select(:source_branch, [@merge_request.source_branch], { }, { class: 'source_branch select2 span2', disabled: true }) + - if @merge_request.new_record? + .form-group + = f.label :source_branch, class: 'control-label' + .col-sm-10 + = f.select(:source_branch, [@merge_request.source_branch], { }, { class: 'source_branch select2 span2', disabled: true }) .form-group = f.label :target_branch, class: 'control-label' .col-sm-10 diff --git a/app/views/shared/issuable/_label_dropdown.html.haml b/app/views/shared/issuable/_label_dropdown.html.haml new file mode 100644 index 00000000000..87617315181 --- /dev/null +++ b/app/views/shared/issuable/_label_dropdown.html.haml @@ -0,0 +1,39 @@ +- if params[:label_name] + = hidden_field_tag(:label_name, params[:label_name]) +.dropdown + %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: @project.try(:id), labels: labels_filter_path, default_label: "Label"}} + %span.dropdown-toggle-text + = h(params[:label_name].presence || "Label") + = icon('chevron-down') + .dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable + .dropdown-page-one + = dropdown_title("Filter by label") + = dropdown_filter("Search labels") + = dropdown_content + - if @project + = dropdown_footer do + %ul.dropdown-footer-list + - if can? current_user, :admin_label, @project + %li + %a.dropdown-toggle-page{href: "#"} + Create new + %li + = link_to namespace_project_labels_path(@project.namespace, @project) do + - if can? current_user, :admin_label, @project + Manage labels + - else + View labels + - if can? current_user, :admin_label, @project and @project + .dropdown-page-two + = dropdown_title("Create new label", back: true) + = dropdown_content do + %input#new_label_color{type: "hidden"} + %input#new_label_name.dropdown-input-field{type: "text", placeholder: "Name new label"} + .dropdown-label-color-preview.js-dropdown-label-color-preview + .suggest-colors.suggest-colors-dropdown + - suggested_colors.each do |color| + = link_to '#', style: "background-color: #{color}", data: { color: color } do +   + %button.btn.btn-primary.js-new-label-btn{type: "button"} + Create + = dropdown_loading diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml new file mode 100644 index 00000000000..0434506c8d7 --- /dev/null +++ b/app/views/shared/issuable/_milestone_dropdown.html.haml @@ -0,0 +1,16 @@ +- if params[:milestone_title] + = hidden_field_tag(:milestone_title, params[:milestone_title]) += dropdown_tag(h(params[:milestone_title].presence || "Milestone"), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", + placeholder: "Search milestones", footer_content: @project.present?, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: @project.try(:id), milestones: milestones_filter_dropdown_path, default_label: "Milestone" } }) do + - if @project + %ul.dropdown-footer-list + - if can? current_user, :admin_milestone, @project + %li + = link_to new_namespace_project_milestone_path(@project.namespace, @project), title: "New Milestone" do + Create new + %li + = link_to namespace_project_milestones_path(@project.namespace, @project) do + - if can? current_user, :admin_milestone, @project + Manage milestones + - else + View milestones diff --git a/app/views/shared/issuable/_participants.html.haml b/app/views/shared/issuable/_participants.html.haml index f1d92ef48b2..3fb409ff727 100644 --- a/app/views/shared/issuable/_participants.html.haml +++ b/app/views/shared/issuable/_participants.html.haml @@ -1,3 +1,6 @@ +- participants_row = 7 +- participants_size = participants.size +- participants_extra = participants_size - participants_row .block.participants .sidebar-collapsed-icon = icon('users') @@ -5,6 +8,13 @@ = participants.count .title.hide-collapsed = pluralize participants.count, "participant" - - participants.each do |participant| - %span.hide-collapsed - = link_to_member(@project, participant, name: false, size: 24) + .hide-collapsed.participants-list + - participants.each do |participant| + .participants-author.js-participants-author + = link_to_member(@project, participant, name: false, size: 24) + - if participants_extra > 0 + %div.participants-more + %a.js-participants-more{href: "#", data: {original_text: "+ #{participants_size - 7} more", less_text: "- show less"}} + + #{participants_extra} more +:javascript + Issue.prototype.PARTICIPANTS_ROW_COUNT = #{participants_row}; diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 36f06377886..2b95b19facc 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -1,13 +1,12 @@ %aside.right-sidebar{ class: sidebar_gutter_collapsed_class } .issuable-sidebar - .block + .block.issuable-sidebar-header %span.issuable-count.hide-collapsed.pull-left = issuable.iid of = issuables_count(issuable) - %span.pull-right - %a.gutter-toggle{href: '#'} - = sidebar_gutter_toggle_icon + %a.gutter-toggle.pull-right.js-sidebar-toggle{href: '#'} + = sidebar_gutter_toggle_icon .issuable-nav.hide-collapsed.pull-right.btn-group{role: 'group', "aria-label" => '...'} - if prev_issuable = prev_issuable_for(issuable) = link_to 'Prev', [@project.namespace.becomes(Namespace), @project, prev_issuable], class: 'btn btn-default prev-btn' @@ -22,20 +21,20 @@ = form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f| .block.assignee - .sidebar-collapsed-icon + .sidebar-collapsed-icon.sidebar-collapsed-user{data: {toggle: "tooltip", placement: "left", container: "body"}, title: (issuable.assignee.to_reference if issuable.assignee)} - if issuable.assignee - = link_to_member_avatar(issuable.assignee, size: 24) + = link_to_member(@project, issuable.assignee, size: 24) - else = icon('user') .title.hide-collapsed - %label - Assignee + Assignee - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) - .pull-right - = link_to 'Edit', '#', class: 'edit-link' - .value.hide-collapsed + = link_to 'Edit', '#', class: 'edit-link pull-right' + .value.bold.hide-collapsed - if issuable.assignee - %strong= link_to_member(@project, issuable.assignee, size: 24) + = link_to_member(@project, issuable.assignee, size: 32) do + %span.username + = issuable.assignee.to_reference - if issuable.instance_of?(MergeRequest) && !issuable.can_be_merged_by?(issuable.assignee) %a.pull-right.cannot-be-merged{href: '#', data: {toggle: 'tooltip'}, title: 'Not allowed to merge'} = icon('exclamation-triangle') @@ -54,18 +53,13 @@ - else No .title.hide-collapsed - %label - Milestone + Milestone - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) - .pull-right - = link_to 'Edit', '#', class: 'edit-link' - .value.hide-collapsed + = link_to 'Edit', '#', class: 'edit-link pull-right' + .value.bold.hide-collapsed - if issuable.milestone - %span.back-to-milestone - = link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do - %strong - = icon('clock-o') - = issuable.milestone.title + = link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do + = issuable.milestone.title - else .light None .selectbox.hide-collapsed @@ -80,11 +74,10 @@ %span = issuable.labels.count .title.hide-collapsed - %label Labels + Labels - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) - .pull-right - = link_to 'Edit', '#', class: 'edit-link' - .value.issuable-show-labels.hide-collapsed + = link_to 'Edit', '#', class: 'edit-link pull-right' + .value.issuable-show-labels.hide-collapsed{class: ("has-labels" if issuable.labels.any?)} - if issuable.labels.any? - issuable.labels.each do |label| = link_to_label(label, type: issuable.to_ability_name) @@ -95,14 +88,13 @@ { selected: issuable.label_ids }, multiple: true, class: 'select2 js-select2', data: { placeholder: "Select labels" } = render "shared/issuable/participants", participants: issuable.participants(current_user) - %hr - if current_user - subscribed = issuable.subscribed?(current_user) - .block.light + .block.light.subscription{data: {url: toggle_subscription_path(issuable)}} .sidebar-collapsed-icon = icon('rss') .title.hide-collapsed - %label.light Notifications + Notifications - subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed' %button.btn.btn-block.btn-gray.subscribe-button.hide-collapsed{:type => 'button'} %span= subscribed ? 'Unsubscribe' : 'Subscribe' @@ -124,5 +116,5 @@ = clipboard_button(clipboard_text: project_ref) :javascript - new Subscription("#{toggle_subscription_path(issuable)}"); + new Subscription('.subscription'); new IssuableContext(); diff --git a/app/views/shared/milestones/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml new file mode 100644 index 00000000000..85888096722 --- /dev/null +++ b/app/views/shared/milestones/_issuable.html.haml @@ -0,0 +1,27 @@ +-# @project is present when viewing Project's milestone +- project = @project || issuable.project +- assignee = issuable.assignee +- issuable_type = issuable.class.table_name +- base_url_args = [project.namespace.becomes(Namespace), project, issuable_type] + +%li{ id: dom_id(issuable, 'sortable'), class: "issuable-row", 'data-iid' => issuable.iid, 'data-url' => polymorphic_path(issuable) } + %span + - if show_project_name + %strong #{project.name} · + - elsif show_full_project_name + %strong #{project.name_with_namespace} · + - if issuable.is_a?(Issue) + = confidential_icon(issuable) + = link_to_gfm issuable.title, [project.namespace.becomes(Namespace), project, issuable], title: issuable.title + %div{class: 'issuable-detail'} + = link_to [project.namespace.becomes(Namespace), project, issuable] do + %span{ class: 'issuable-number' }>= issuable.to_reference + + - issuable.labels.each do |label| + = link_to polymorphic_path(base_url_args, { milestone_title: @milestone.title, label_name: label.title, state: 'all' }) do + - render_colored_label(label) + + - if assignee + = link_to polymorphic_path(base_url_args, { milestone_title: @milestone.title, assignee_id: issuable.assignee_id, state: 'all' }), + class: 'has_tooltip', data: { 'original-title' => "Assigned to #{sanitize(assignee.name)}", container: 'body' } do + - image_tag(avatar_icon(issuable.assignee, 16), class: "avatar s16", alt: '') diff --git a/app/views/shared/milestones/_issuables.html.haml b/app/views/shared/milestones/_issuables.html.haml new file mode 100644 index 00000000000..8619939dde7 --- /dev/null +++ b/app/views/shared/milestones/_issuables.html.haml @@ -0,0 +1,16 @@ +- show_counter = local_assigns.fetch(:show_counter, false) +- primary = local_assigns.fetch(:primary, false) +- panel_class = primary ? 'panel-primary' : 'panel-default' + +.panel{ class: panel_class } + .panel-heading + = title + - if show_counter + .pull-right= issuables.size + + - class_prefix = dom_class(issuables).pluralize + %ul{ class: "well-list #{class_prefix}-sortable-list", id: "#{class_prefix}-list-#{id}", "data-state" => id } + = render partial: 'shared/milestones/issuable', + collection: issuables.sort_by(&:position), + as: :issuable, + locals: { show_project_name: show_project_name, show_full_project_name: show_full_project_name } diff --git a/app/views/shared/milestones/_issues_tab.html.haml b/app/views/shared/milestones/_issues_tab.html.haml new file mode 100644 index 00000000000..a8db7f8a556 --- /dev/null +++ b/app/views/shared/milestones/_issues_tab.html.haml @@ -0,0 +1,10 @@ +- args = { show_project_name: local_assigns.fetch(:show_project_name, false), + show_full_project_name: local_assigns.fetch(:show_full_project_name, false) } + +.row.prepend-top-default + .col-md-4 + = render 'shared/milestones/issuables', args.merge(title: 'Unstarted Issues (open and unassigned)', issuables: issues.opened.unassigned, id: 'unassigned', show_counter: true) + .col-md-4 + = render 'shared/milestones/issuables', args.merge(title: 'Ongoing Issues (open and assigned)', issuables: issues.opened.assigned, id: 'ongoing', show_counter: true) + .col-md-4 + = render 'shared/milestones/issuables', args.merge(title: 'Completed Issues (closed)', issuables: issues.closed, id: 'closed', show_counter: true) diff --git a/app/views/shared/milestones/_labels_tab.html.haml b/app/views/shared/milestones/_labels_tab.html.haml new file mode 100644 index 00000000000..868b2357003 --- /dev/null +++ b/app/views/shared/milestones/_labels_tab.html.haml @@ -0,0 +1,18 @@ +%ul.bordered-list.manage-labels-list + - labels.each do |label| + - options = { milestone_title: @milestone.title, label_name: label.title } + + %li + %span.label-row + = link_to milestones_label_path(options) do + - render_colored_label(label, tooltip: false) + %span.prepend-left-10 + = markdown(label.description, pipeline: :single_line) + + .pull-right + %strong.issues-count + = link_to milestones_label_path(options.merge(state: 'opened')) do + - pluralize milestone_issues_by_label_count(@milestone, label, state: :opened), 'open issue' + %strong.issues-count + = link_to milestones_label_path(options.merge(state: 'closed')) do + - pluralize milestone_issues_by_label_count(@milestone, label, state: :closed), 'closed issue' diff --git a/app/views/shared/milestones/_merge_requests_tab.haml b/app/views/shared/milestones/_merge_requests_tab.haml new file mode 100644 index 00000000000..c29d8ee6737 --- /dev/null +++ b/app/views/shared/milestones/_merge_requests_tab.haml @@ -0,0 +1,12 @@ +- args = { show_project_name: local_assigns.fetch(:show_project_name, false), + show_full_project_name: local_assigns.fetch(:show_full_project_name, false) } + +.row.prepend-top-default + .col-md-3 + = render 'shared/milestones/issuables', args.merge(title: 'Work in progress (open and unassigned)', issuables: merge_requests.opened.unassigned, id: 'unassigned') + .col-md-3 + = render 'shared/milestones/issuables', args.merge(title: 'Waiting for merge (open and assigned)', issuables: merge_requests.opened.assigned, id: 'ongoing') + .col-md-3 + = render 'shared/milestones/issuables', args.merge(title: 'Rejected (closed)', issuables: merge_requests.closed, id: 'closed') + .col-md-3 + = render 'shared/milestones/issuables', args.merge(title: 'Merged', issuables: merge_requests.merged, id: 'merged', primary: true) diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml new file mode 100644 index 00000000000..6b25745c554 --- /dev/null +++ b/app/views/shared/milestones/_milestone.html.haml @@ -0,0 +1,45 @@ +- dashboard = local_assigns[:dashboard] +- custom_dom_id = dom_id(@project ? milestone : milestone.milestones.first) + +%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: custom_dom_id } + .row + .col-sm-6 + %strong= link_to_gfm truncate(milestone.title, length: 100), milestone_path + .col-sm-6 + .pull-right.light #{milestone.percent_complete(current_user)}% complete + .row + .col-sm-6 + = link_to pluralize(milestone.issues_visible_to_user(current_user).size, 'Issue'), issues_path + · + = link_to pluralize(milestone.merge_requests.size, 'Merge Request'), merge_requests_path + .col-sm-6= milestone_progress_bar(milestone) + - if milestone.is_a?(GlobalMilestone) + .row + .col-sm-6 + .expiration= render('shared/milestone_expired', milestone: milestone) + .projects + - milestone.milestones.each do |milestone| + = link_to milestone_path(milestone) do + %span.label.label-gray + = dashboard ? milestone.project.name_with_namespace : milestone.project.name + - if @group + .col-sm-6 + - if can?(current_user, :admin_milestones, @group) + - if milestone.closed? + = link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-xs btn-grouped btn-reopen" + - else + = link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-xs btn-close" + + - if @project + .row + .col-sm-6= render('shared/milestone_expired', milestone: milestone) + .col-sm-6 + - if can?(current_user, :admin_milestone, milestone.project) and milestone.active? + = link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-xs" do + = icon('pencil-square-o') + Edit + \ + = link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close" + = link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-xs btn-remove" do + = icon('trash-o') + Delete diff --git a/app/views/shared/milestones/_participants_tab.html.haml b/app/views/shared/milestones/_participants_tab.html.haml new file mode 100644 index 00000000000..67ae85ac276 --- /dev/null +++ b/app/views/shared/milestones/_participants_tab.html.haml @@ -0,0 +1,8 @@ +%ul.bordered-list + - users.each do |user| + %li + = link_to user, title: user.name, class: "darken" do + = image_tag avatar_icon(user, 32), class: "avatar s32" + %strong= truncate(user.name, lenght: 40) + %br + %small.cgray= user.username diff --git a/app/views/shared/milestones/_summary.html.haml b/app/views/shared/milestones/_summary.html.haml new file mode 100644 index 00000000000..385c6596606 --- /dev/null +++ b/app/views/shared/milestones/_summary.html.haml @@ -0,0 +1,28 @@ +- project = local_assigns[:project] + +.context.prepend-top-default + .milestone-summary + %h4 Progress + %strong= milestone.issues_visible_to_user(current_user).size + issues: + %span.milestone-stat + %strong= milestone.issues_visible_to_user(current_user).opened.size + open and + %strong= milestone.issues_visible_to_user(current_user).closed.size + closed + %span.milestone-stat + %strong== #{milestone.percent_complete(current_user)}% + complete + + %span.milestone-stat + %span.remaining-days= milestone_remaining_days(milestone) + %span.pull-right.tab-issues-buttons + - if project && can?(current_user, :create_issue, project) + = link_to new_namespace_project_issue_path(project.namespace, project, issue: { milestone_id: milestone.id }), class: "btn btn-grouped", title: "New Issue" do + %i.fa.fa-plus + New Issue + = link_to 'Browse Issues', milestones_browse_issuables_path(milestone, type: :issues), class: "btn btn-grouped" + %span.pull-right.tab-merge-requests-buttons.hidden + = link_to 'Browse Merge Requests', milestones_browse_issuables_path(milestone, type: :merge_requests), class: "btn btn-grouped" + + = milestone_progress_bar(milestone) diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml new file mode 100644 index 00000000000..2b6ce2d7e7a --- /dev/null +++ b/app/views/shared/milestones/_tabs.html.haml @@ -0,0 +1,30 @@ +%ul.nav-links.no-top.no-bottom + %li.active + = link_to '#tab-issues', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do + Issues + %span.badge= milestone.issues_visible_to_user(current_user).size + %li + = link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-show' => '.tab-merge-requests-buttons' do + Merge Requests + %span.badge= milestone.merge_requests.size + %li + = link_to '#tab-participants', 'data-toggle' => 'tab' do + Participants + %span.badge= milestone.participants.count + %li + = link_to '#tab-labels', 'data-toggle' => 'tab' do + Labels + %span.badge= milestone.labels.count + +- show_project_name = local_assigns.fetch(:show_project_name, false) +- show_full_project_name = local_assigns.fetch(:show_full_project_name, false) + +.tab-content.milestone-content + .tab-pane.active#tab-issues + = render 'shared/milestones/issues_tab', issues: milestone.issues_visible_to_user(current_user), show_project_name: show_project_name, show_full_project_name: show_full_project_name + .tab-pane#tab-merge-requests + = render 'shared/milestones/merge_requests_tab', merge_requests: milestone.merge_requests, show_project_name: show_project_name, show_full_project_name: show_full_project_name + .tab-pane#tab-participants + = render 'shared/milestones/participants_tab', users: milestone.participants + .tab-pane#tab-labels + = render 'shared/milestones/labels_tab', labels: milestone.labels diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml new file mode 100644 index 00000000000..cab8743a077 --- /dev/null +++ b/app/views/shared/milestones/_top.html.haml @@ -0,0 +1,58 @@ +- page_title milestone.title, "Milestones" + +- group = local_assigns[:group] + +.detail-page-header + .status-box{ class: "status-box-#{milestone.closed? ? 'closed' : 'open'}" } + - if milestone.closed? + Closed + - elsif milestone.expired? + Expired + - else + Open + %span.identifier + Milestone #{milestone.title} + - if milestone.expires_at + %span.creator + · + = milestone.expires_at + - if group + .pull-right + - if can?(current_user, :admin_milestones, group) + - if milestone.active? + = link_to 'Close Milestone', group_milestone_path(group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-grouped btn-close" + - else + = link_to 'Reopen Milestone', group_milestone_path(group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-grouped btn-reopen" + +.detail-page-description.gray-content-block.second-block + %h2.title + = markdown escape_once(milestone.title), pipeline: :single_line + +- if milestone.complete?(current_user) && milestone.active? + .alert.alert-success.prepend-top-default + - close_msg = group ? 'You may close the milestone now.' : 'Navigate to the project to close the milestone.' + %span All issues for this milestone are closed. #{close_msg} + +.table-holder + %table.table + %thead + %tr + %th Project + %th Open issues + %th State + %th Due date + - milestone.milestones.each do |ms| + %tr + %td + - project_name = group ? ms.project.name : ms.project.name_with_namespace + = link_to project_name, namespace_project_milestone_path(ms.project.namespace, ms.project, ms) + %td + = ms.issues_visible_to_user(current_user).opened.count + %td + - if ms.closed? + Closed + - else + Open + %td + = ms.expires_at + diff --git a/app/views/shared/projects/_dropdown.html.haml b/app/views/shared/projects/_dropdown.html.haml new file mode 100644 index 00000000000..e7e04621ff4 --- /dev/null +++ b/app/views/shared/projects/_dropdown.html.haml @@ -0,0 +1,22 @@ +- @sort ||= sort_value_recently_updated +- archived = params[:archived] +.dropdown.inline + %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} + %span.light + = projects_sort_options_hash[@sort] + %b.caret + %ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-selectable + %li.dropdown-header + Sort by + - projects_sort_options_hash.each do |value, title| + %li + = link_to filter_projects_path(sort: value, archived: archived), class: ("is-active" if @sort == value) do + = title + + %li.divider + %li + = link_to filter_projects_path(sort: @sort, archived: nil), class: ("is-active" unless params[:archived].present?) do + Hide archived projects + %li + = link_to filter_projects_path(sort: @sort, archived: true), class: ("is-active" if params[:archived].present?) do + Show archived projects diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index 99e48e86e38..872d2bdf46d 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -7,27 +7,15 @@ - show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true && project.commit - css_class += " no-description" if project.description.blank? && !show_last_commit_as_description - ci_commit = project.ci_commit(project.commit.sha) if ci && !project.empty_repo? && project.commit -- cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.2'] +- cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.3'] - cache_key.push(ci_commit.status) if ci_commit %li.project-row{ class: css_class } = cache(cache_key) do - = link_to project_path(project), class: dom_class(project) do - - if avatar - .dash-project-avatar - - if use_creator_avatar - = image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:'' - - else - = project_icon(project, alt: '', class: 'avatar project-avatar s40') - %span.project-full-name.title - %span.namespace-name - - if project.namespace && !skip_namespace - = project.namespace.human_name - \/ - %span.project-name.filter-title - = project.name - .controls + - if project.main_language + %span + = project.main_language - if ci_commit %span = render_ci_status(ci_commit) @@ -42,6 +30,23 @@ %span.visibility-icon.has_tooltip{data: { container: 'body', placement: 'left' }, title: "#{visibility_level_label(project.visibility_level)} - #{project_visibility_level_description(project.visibility_level)}"} = visibility_level_icon(project.visibility_level, fw: false) + + .title + = link_to project_path(project), class: dom_class(project) do + - if avatar + .dash-project-avatar + - if use_creator_avatar + = image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:'' + - else + = project_icon(project, alt: '', class: 'avatar project-avatar s40') + %span.project-full-name + %span.namespace-name + - if project.namespace && !skip_namespace + = project.namespace.human_name + \/ + %span.project-name.filter-title + = project.name + - if show_last_commit_as_description .description = link_to_gfm project.commit.title, namespace_project_commit_path(project.namespace, project, project.commit), diff --git a/app/views/shared/snippets/_blob.html.haml b/app/views/shared/snippets/_blob.html.haml index e0e41fc4bea..773ce8ac240 100644 --- a/app/views/shared/snippets/_blob.html.haml +++ b/app/views/shared/snippets/_blob.html.haml @@ -1,5 +1,7 @@ - unless @snippet.content.empty? - if markup?(@snippet.file_name) + %textarea.markdown-snippet-copy.blob-content{data: {blob_id: @snippet.id}} + = @snippet.data .file-content.wiki = render_markup(@snippet.file_name, @snippet.data) - else diff --git a/app/views/shared/snippets/_snippet.html.haml b/app/views/shared/snippets/_snippet.html.haml index a316a085107..c96dfefe17f 100644 --- a/app/views/shared/snippets/_snippet.html.haml +++ b/app/views/shared/snippets/_snippet.html.haml @@ -1,8 +1,8 @@ %li.snippet-row = image_tag avatar_icon(snippet.author_email), class: "avatar s40 hidden-xs", alt: '' - .snippet-title - = link_to reliable_snippet_path(snippet), class: 'title' do + .title + = link_to reliable_snippet_path(snippet) do = truncate(snippet.title, length: 60) - if snippet.private? %span.label.label-gray diff --git a/app/views/votes/_votes_block.html.haml b/app/views/votes/_votes_block.html.haml index 176fd29cb57..20d2d5f317b 100644 --- a/app/views/votes/_votes_block.html.haml +++ b/app/views/votes/_votes_block.html.haml @@ -1,14 +1,17 @@ .awards.votes-block - awards_sort(votable.notes.awards.grouped_awards).each do |emoji, notes| - .award{class: (note_active_class(notes, current_user)), title: emoji_author_list(notes, current_user)} + %button.btn.award-control.js-emoji-btn.has_tooltip{class: (note_active_class(notes, current_user)), title: emoji_author_list(notes, current_user), data: {placement: "top"}} = emoji_icon(emoji) - .counter + %span.award-control-text.js-counter = notes.count - if current_user - .awards-controls - %a.add-award{"href" => "#"} - = icon('smile-o') + %div.award-menu-holder.js-award-holder + %a.btn.award-control.js-add-award{"href" => "#"} + = icon('smile-o', {class: "award-control-icon"}) + = icon('spinner spin', {class: "award-control-icon award-control-icon-loading"}) + %span.award-control-text + Add - if current_user :javascript @@ -23,17 +26,3 @@ noteable_id, aliases ); - - $(".awards").on("click", ".emoji-menu-content li", function(e) { - var emoji = $(this).find(".emoji-icon").data("emoji"); - awards_handler.addAward(emoji); - }); - - $(".awards").on("click", ".award", function(e) { - var emoji = $(this).find(".icon").data("emoji"); - awards_handler.addAward(emoji); - }); - - $(".award").tooltip(); - - $(".emoji-menu-content").niceScroll({cursorwidth: "7px", autohidemode: false}); |