diff options
author | tiagonbotelho <tiagonbotelho@hotmail.com> | 2016-07-18 14:59:12 +0100 |
---|---|---|
committer | tiagonbotelho <tiagonbotelho@hotmail.com> | 2016-07-18 14:59:12 +0100 |
commit | 50f3d0d4f1392b3e45abe623506965016889cf8b (patch) | |
tree | 5e0dff94916042d4a3a33ffb4f42f21bd0d10535 /app | |
parent | c6097f24d32610d4c12ae0e9d16b72dc53cda9da (diff) | |
parent | 017ae313dc84682e260e960f93fb4a55af0df523 (diff) | |
download | gitlab-ce-50f3d0d4f1392b3e45abe623506965016889cf8b.tar.gz |
Merge branch 'master' into rename-repo-files
Diffstat (limited to 'app')
111 files changed, 751 insertions, 519 deletions
diff --git a/app/assets/javascripts/api.js.coffee b/app/assets/javascripts/api.js.coffee index cf46f15a156..89b0ac697ed 100644 --- a/app/assets/javascripts/api.js.coffee +++ b/app/assets/javascripts/api.js.coffee @@ -3,7 +3,7 @@ groupPath: "/api/:version/groups/:id.json" namespacesPath: "/api/:version/namespaces.json" groupProjectsPath: "/api/:version/groups/:id/projects.json" - projectsPath: "/api/:version/projects.json" + projectsPath: "/api/:version/projects.json?simple=true" labelsPath: "/api/:version/projects/:id/labels" licensePath: "/api/:version/licenses/:key" gitignorePath: "/api/:version/gitignores/:key" diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index c98763d6271..eceff6d91d5 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -53,7 +53,6 @@ #= require_directory ./u2f #= require_directory . #= require fuzzaldrin-plus -#= require u2f window.slugify = (text) -> text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase() diff --git a/app/assets/javascripts/compare_autocomplete.js.coffee b/app/assets/javascripts/compare_autocomplete.js.coffee new file mode 100644 index 00000000000..7ad9fd97637 --- /dev/null +++ b/app/assets/javascripts/compare_autocomplete.js.coffee @@ -0,0 +1,41 @@ +class @CompareAutocomplete + constructor: -> + @initDropdown() + + initDropdown: -> + $('.js-compare-dropdown').each -> + $dropdown = $(@) + selected = $dropdown.data('selected') + + $dropdown.glDropdown( + data: (term, callback) -> + $.ajax( + url: $dropdown.data('refs-url') + data: + ref: $dropdown.data('ref') + ).done (refs) -> + callback(refs) + selectable: true + filterable: true + filterByText: true + fieldName: $dropdown.attr('name') + filterInput: 'input[type="text"]' + renderRow: (ref) -> + if ref.header? + $('<li />') + .addClass('dropdown-header') + .text(ref.header) + else + link = $('<a />') + .attr('href', '#') + .addClass(if ref is selected then 'is-active' else '') + .text(ref) + .attr('data-ref', escape(ref)) + + $('<li />') + .append(link) + id: (obj, $el) -> + $el.attr('data-ref') + toggleLabel: (obj, $el) -> + $el.text().trim() + ) diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index 74fd77cf7ab..afaa6407b05 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -137,6 +137,8 @@ class Dispatcher new Project() new ProjectAvatar() switch path[1] + when 'compare' + new CompareAutocomplete() when 'edit' shortcut_handler = new ShortcutsNavigation() new ProjectNew() diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 1c65e833d47..1b0d0db8954 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -456,6 +456,8 @@ class GitLabDropdown rowClicked: (el) -> fieldName = @options.fieldName + isInput = $(@el).is('input') + if @renderedData groupName = el.data('group') if groupName @@ -466,10 +468,19 @@ class GitLabDropdown selectedObject = @renderedData[selectedIndex] value = if @options.id then @options.id(selectedObject, el) else selectedObject.id - field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']") + + if isInput + field = $(@el) + else + field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']") + if el.hasClass(ACTIVE_CLASS) el.removeClass(ACTIVE_CLASS) - field.remove() + + if isInput + field.val('') + else + field.remove() # Toggle the dropdown label if @options.toggleLabel @@ -490,7 +501,9 @@ class GitLabDropdown else if not @options.multiSelect or el.hasClass('dropdown-clear-active') @dropdown.find(".#{ACTIVE_CLASS}").removeClass ACTIVE_CLASS - @dropdown.parent().find("input[name='#{fieldName}']").remove() + + unless isInput + @dropdown.parent().find("input[name='#{fieldName}']").remove() if !value? field.remove() @@ -505,7 +518,9 @@ class GitLabDropdown if !field.length and fieldName @addInput(fieldName, value) else - field.val value + field + .val value + .trigger 'change' return selectedObject diff --git a/app/assets/javascripts/issuable.js.coffee b/app/assets/javascripts/issuable.js.coffee index c71d4ecf505..7f795f8096b 100644 --- a/app/assets/javascripts/issuable.js.coffee +++ b/app/assets/javascripts/issuable.js.coffee @@ -32,13 +32,11 @@ issuable_created = false $search = $('#issue_search') $form = $('.js-filter-form') $input = $("input[name='#{$search.attr('name')}']", $form) - if $input.length is 0 $form.append "<input type='hidden' name='#{$search.attr('name')}' value='#{_.escape($search.val())}'/>" else $input.val $search.val() - - Issuable.filterResults $form + Issuable.filterResults $form if $search.val() isnt '' , 500) initLabelFilterRemove: -> diff --git a/app/assets/javascripts/projects_list.js.coffee b/app/assets/javascripts/projects_list.js.coffee index e4c4bf3b273..a7d78d9e461 100644 --- a/app/assets/javascripts/projects_list.js.coffee +++ b/app/assets/javascripts/projects_list.js.coffee @@ -5,13 +5,12 @@ this.initPagination() initSearch: -> - @timer = null - $(".projects-list-filter").on('keyup', -> - clearTimeout(@timer) - @timer = setTimeout(ProjectsList.filterResults, 500) - ) + projectsListFilter = $('.projects-list-filter') + debounceFilter = _.debounce ProjectsList.filterResults, 500 + projectsListFilter.on 'keyup', (e) -> + debounceFilter() if projectsListFilter.val() isnt '' - filterResults: => + filterResults: -> $('.projects-list-holder').fadeTo(250, 0.5) form = null diff --git a/app/assets/javascripts/shortcuts.js.coffee b/app/assets/javascripts/shortcuts.js.coffee index 3319a67a79d..8c8689bacee 100644 --- a/app/assets/javascripts/shortcuts.js.coffee +++ b/app/assets/javascripts/shortcuts.js.coffee @@ -2,9 +2,10 @@ class @Shortcuts constructor: (skipResetBindings) -> @enabledHelp = [] Mousetrap.reset() if not skipResetBindings - Mousetrap.bind('?', @onToggleHelp) - Mousetrap.bind('s', Shortcuts.focusSearch) - Mousetrap.bind(['ctrl+shift+p', 'command+shift+p'], @toggleMarkdownPreview) + Mousetrap.bind '?', @onToggleHelp + Mousetrap.bind 's', Shortcuts.focusSearch + Mousetrap.bind 'f', (e) => @focusFilter e + Mousetrap.bind ['ctrl+shift+p', 'command+shift+p'], @toggleMarkdownPreview Mousetrap.bind('t', -> Turbolinks.visit(findFileURL)) if findFileURL? onToggleHelp: (e) => @@ -32,10 +33,16 @@ class @Shortcuts $('.js-more-help-button').remove() ) + focusFilter: (e) -> + @filterInput ?= $('input[type=search]', '.nav-controls') + @filterInput.focus() + e.preventDefault() + @focusSearch: (e) -> $('#search').focus() e.preventDefault() + $(document).on 'click.more_help', '.js-more-help-button', (e) -> $(@).remove() $('.hidden-shortcut').show() diff --git a/app/assets/javascripts/u2f/authenticate.js.coffee b/app/assets/javascripts/u2f/authenticate.js.coffee index 6deb902c8de..918c0a560fd 100644 --- a/app/assets/javascripts/u2f/authenticate.js.coffee +++ b/app/assets/javascripts/u2f/authenticate.js.coffee @@ -6,8 +6,20 @@ class @U2FAuthenticate constructor: (@container, u2fParams) -> @appId = u2fParams.app_id - @challenges = u2fParams.challenges - @signRequests = u2fParams.sign_requests + @challenge = u2fParams.challenge + + # The U2F Javascript API v1.1 requires a single challenge, with + # _no challenges per-request_. The U2F Javascript API v1.0 requires a + # challenge per-request, which is done by copying the single challenge + # into every request. + # + # In either case, we don't need the per-request challenges that the server + # has generated, so we can remove them. + # + # Note: The server library fixes this behaviour in (unreleased) version 1.0.0. + # This can be removed once we upgrade. + # https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4 + @signRequests = u2fParams.sign_requests.map (request) -> _(request).omit('challenge') start: () => if U2FUtil.isU2FSupported() @@ -16,7 +28,7 @@ class @U2FAuthenticate @renderNotSupported() authenticate: () => - u2f.sign(@appId, @challenges, @signRequests, (response) => + u2f.sign(@appId, @challenge, @signRequests, (response) => if response.errorCode error = new U2FError(response.errorCode) @renderError(error); diff --git a/app/assets/javascripts/u2f/util.js.coffee b/app/assets/javascripts/u2f/util.js.coffee new file mode 100644 index 00000000000..5ef324f609d --- /dev/null +++ b/app/assets/javascripts/u2f/util.js.coffee @@ -0,0 +1,3 @@ +class @U2FUtil + @isU2FSupported: -> + window.u2f diff --git a/app/assets/javascripts/u2f/util.js.coffee.erb b/app/assets/javascripts/u2f/util.js.coffee.erb deleted file mode 100644 index d59341c38b9..00000000000 --- a/app/assets/javascripts/u2f/util.js.coffee.erb +++ /dev/null @@ -1,15 +0,0 @@ -# Helper class for U2F (universal 2nd factor) device registration and authentication. - -class @U2FUtil - @isU2FSupported: -> - if @testMode - true - else - gon.u2f.browser_supports_u2f - - @enableTestMode: -> - @testMode = true - -<% if Rails.env.test? %> -U2FUtil.enableTestMode(); -<% end %> diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee index 4e032ab1ff1..344be811e0d 100644 --- a/app/assets/javascripts/users_select.js.coffee +++ b/app/assets/javascripts/users_select.js.coffee @@ -56,6 +56,11 @@ class @UsersSelect username: '' avatar: '' $value.html(assigneeTemplate(user)) + + $collapsedSidebar + .attr('title', user.name) + .tooltip('fixTitle') + $collapsedSidebar.html(collapsedAssigneeTemplate(user)) @@ -63,7 +68,6 @@ class @UsersSelect '<% if( avatar ) { %> <a class="author_link" href="/u/<%- username %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> - <span class="author">Toni Boehm</span> </a> <% } else { %> <i class="fa fa-user"></i> diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss index bb8d71fbae8..8b6ddf8ba18 100644 --- a/app/assets/stylesheets/framework/avatar.scss +++ b/app/assets/stylesheets/framework/avatar.scss @@ -20,6 +20,7 @@ } &.s16 { width: 16px; height: 16px; margin-right: 6px; } + &.s20 { width: 20px; height: 20px; margin-right: 7px; } &.s24 { width: 24px; height: 24px; margin-right: 8px; } &.s26 { width: 26px; height: 26px; margin-right: 8px; } &.s32 { width: 32px; height: 32px; margin-right: 10px; } diff --git a/app/assets/stylesheets/framework/blank.scss b/app/assets/stylesheets/framework/blank.scss index d28cda6d62d..540718197e0 100644 --- a/app/assets/stylesheets/framework/blank.scss +++ b/app/assets/stylesheets/framework/blank.scss @@ -20,9 +20,12 @@ .blank-state-icon { padding-bottom: 20px; + color: $gray-darkest; + font-size: 56px; - path { - fill: $gray-darkest; + path, + polygon { + fill: currentColor; } } @@ -37,6 +40,10 @@ margin-top: 0; margin-bottom: $gl-padding; font-size: 15px; + + > strong { + font-weight: 600; + } } .blank-state-welcome-title { diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index 24b1ebab4b0..ad94e457cfd 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -16,8 +16,14 @@ font-weight: normal; font-size: 16px; line-height: 36px; + &.diff-collapsed { + padding: 5px; cursor: pointer; + + &:hover { + background-color: $row-hover; + } } } diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index f8aecd0558d..c1e5305644b 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -270,21 +270,6 @@ table { } } -.dashboard-intro-icon { - float: left; - text-align: center; - font-size: 32px; - color: #aaa; - width: 60px; -} - -.dashboard-intro-text { - display: inline-block; - margin-left: -60px; - padding-left: 60px; - width: 100%; -} - .btn-sign-in { text-shadow: none; diff --git a/app/assets/stylesheets/framework/gitlab-theme.scss b/app/assets/stylesheets/framework/gitlab-theme.scss index d1ff63bd099..3673b81f183 100644 --- a/app/assets/stylesheets/framework/gitlab-theme.scss +++ b/app/assets/stylesheets/framework/gitlab-theme.scss @@ -11,7 +11,6 @@ .toggle-nav-collapse, .pin-nav-btn { color: $color-light; - background: $color; &:hover { color: $white-light; diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index 1a2220f3b40..d52e8f00172 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -17,7 +17,7 @@ height: 100%; overflow: hidden; transition: width $sidebar-transition-duration; - @include box-shadow(2px 0 16px 0 #bbb); + @include box-shadow(2px 0 16px 0 $black-transparent); } } @@ -55,10 +55,6 @@ overflow-y: auto; overflow-x: hidden; - @media (min-width: $sidebar-breakpoint) { - bottom: 50px; - } - &.navbar-collapse { padding: 0 !important; } @@ -76,7 +72,7 @@ } a { - padding: 7px 15px 7px 12px; + padding: 7px $gl-sidebar-padding; font-size: $gl-font-size; line-height: 24px; display: block; @@ -108,7 +104,7 @@ } } -.toggle-nav-collapse { +.sidebar-action-buttons { width: $sidebar_width; position: absolute; top: 0; @@ -117,12 +113,37 @@ padding: 5px 0; font-size: 18px; line-height: 30px; + + .toggle-nav-collapse { + left: 0; + } + + .pin-nav-btn { + right: 0; + display: none; + + @media (min-width: $sidebar-breakpoint) { + display: block; + } + + .fa { + transition: transform .15s; + } + + &.is-active { + .fa { + transform: rotate(90deg); + } + } + } } .nav-header-btn { - padding: 10px 5px; + padding: 10px $gl-sidebar-padding; color: inherit; transition-duration: .3s; + position: absolute; + top: 0; &:hover, &:focus { @@ -131,30 +152,6 @@ } } -.pin-nav-btn { - display: none; - position: absolute; - left: 0; - bottom: 0; - height: 50px; - width: $sidebar_width; - line-height: 30px; - - @media (min-width: $sidebar-breakpoint) { - display: block; - } - - .fa { - transition: transform .15s; - } - - &.is-active { - .fa { - transform: rotate(90deg); - } - } -} - .page-sidebar-collapsed { padding-left: 0; diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 4337fab5d87..f0e7002e4cd 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -17,6 +17,7 @@ $focus-border-color: #3aabf0; $table-border-color: #f0f0f0; $background-color: #fafafa; $dark-background-color: #f7f7f7; +$table-text-gray: #8f8f8f; /* * Text @@ -63,6 +64,7 @@ $gl-btn-padding: 10px; $gl-input-padding: 10px; $gl-vert-padding: 6px; $gl-padding-top: 10px; +$gl-sidebar-padding: 22px; /* * Misc diff --git a/app/assets/stylesheets/pages/admin.scss b/app/assets/stylesheets/pages/admin.scss index 1d34a7f79ae..5607239d92d 100644 --- a/app/assets/stylesheets/pages/admin.scss +++ b/app/assets/stylesheets/pages/admin.scss @@ -88,13 +88,7 @@ .user-name { display: inline-block; - font-weight: bold; - } - - .controls { - > .btn, > .dropdown { - margin-left: 5px; - } + font-weight: 600; } .dropdown { diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index e8f1935d239..99a2cd306cf 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -83,14 +83,6 @@ } } -table.builds { - .build-link { - a { - color: $gl-dark-link-color; - } - } -} - .build-trace { background: $ci-output-bg; color: $ci-text-color; diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss index 701b9388454..2a3acc3eb4c 100644 --- a/app/assets/stylesheets/pages/groups.scss +++ b/app/assets/stylesheets/pages/groups.scss @@ -38,33 +38,6 @@ margin-right: 15px; } } - - &.group-admin { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - - .group-avatar, .group-details, .group-controls { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - } - - .group-details { - flex: 1 1 auto; - flex-direction: column; - min-width: 0; - } - - .group-controls { - align-items: center; - - a { - margin-left: 5px; - } - } - } - } .ldap-group-links { diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss index 47bfd144930..3b1e38fc07d 100644 --- a/app/assets/stylesheets/pages/labels.scss +++ b/app/assets/stylesheets/pages/labels.scss @@ -162,9 +162,15 @@ } .filtered-labels { + font-size: 0; + padding: 12px 16px; + .label-row { + margin-top: 4px; + margin-bottom: 4px; + &:not(:last-child) { - margin-right: 5px; + margin-right: 8px; } } diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index d9756b66af0..15c6c9f231a 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -73,11 +73,14 @@ color: #888; } - &.ci-pending, - &.ci-running { + &.ci-pending { color: $gl-warning; } + &.ci-running { + color: $blue-normal; + } + &.ci-failed, &.ci-error { color: $gl-danger; diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 6128868b670..a0334207c68 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -1,15 +1,12 @@ .pipelines { .stage { - max-width: 100px; + max-width: 80px; + width: 80px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } - .duration, .finished_at { - margin: 4px 0; - } - .commit-title { margin: 0; } @@ -22,3 +19,156 @@ margin: 4px; } } + +.content-list { + + &.pipelines, + &.builds-content-list { + width: 100%; + overflow: auto; + } +} + +.table.builds { + min-width: 1100px; + + tr { + th { + padding: 16px; + border: none; + } + } + + tbody { + border-top-width: 1px; + } + + .commit-link { + + a:hover { + text-decoration: none; + } + } + + .branch-commit { + + .branch-name { + margin-left: 8px; + font-weight: bold; + max-width: 180px; + overflow: hidden; + display: inline-block; + white-space: nowrap; + vertical-align: top; + text-overflow: ellipsis; + } + + svg { + margin: 0 6px; + height: 14px; + width: auto; + vertical-align: middle; + } + + .commit-id { + color: $gl-link-color; + margin-right: 8px; + } + + .commit-title { + margin-top: 4px; + max-width: 320px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + .avatar { + margin-left: 0; + } + + .label { + margin-right: 4px; + } + + .label-container { + font-size: 0; + + .label { + margin-top: 5px; + } + } + } + + .duration, + .finished-at { + color: $table-text-gray; + margin: 4px 0; + + .fa { + font-size: 12px; + } + + svg { + height: 12px; + width: auto; + vertical-align: middle; + } + + .fa, + svg { + margin-right: 5px; + } + } + + .pipeline-actions { + + .btn { + margin: 0; + color: $table-text-gray; + } + + .cancel-retry-btns { + vertical-align: middle; + + .btn:not(:first-child) { + margin-left: 8px; + } + } + + .dropdown-toggle, + .dropdown-menu { + color: $table-text-gray; + + .fa { + color: $table-text-gray; + margin-right: 6px; + font-size: 14px; + } + } + + .btn-remove { + color: $white-light; + } + + .btn-group { + &.open { + .btn-default { + background-color: $white-normal; + border-color: $border-white-normal; + } + } + } + } + + .build-link { + + a { + color: $gl-dark-link-color; + } + } + + .btn-group.open .dropdown-toggle { + box-shadow: none; + } +} diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 5be911dc562..ea9f7cf0540 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -482,6 +482,10 @@ pre.light-well { a:hover { text-decoration: none; } + + > span { + margin-left: 10px; + } } } @@ -639,3 +643,9 @@ pre.light-well { width: 300px; } } + +.compare-form-group { + .dropdown-menu { + width: 300px; + } +} diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index 9e9b18fdbb8..c9d436d72ba 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -185,7 +185,7 @@ padding-right: $gl-padding + 15px; } - .btn-search { + .btn-search, .btn-new { width: 100%; margin-top: 5px; diff --git a/app/assets/stylesheets/pages/status.scss b/app/assets/stylesheets/pages/status.scss index 2370d35924e..c6b053150be 100644 --- a/app/assets/stylesheets/pages/status.scss +++ b/app/assets/stylesheets/pages/status.scss @@ -32,11 +32,15 @@ border-color: $gl-gray; } - &.ci-pending, - &.ci-running { + &.ci-pending { color: $gl-warning; border-color: $gl-warning; } + + &.ci-running { + color: $blue-normal; + border-color: $blue-normal; + } } .ci-status-icon-success { @@ -45,10 +49,12 @@ .ci-status-icon-failed { color: $gl-danger; } - .ci-status-icon-running, .ci-status-icon-pending { color: $gl-warning; } + .ci-status-icon-running { + color: $blue-normal; + } .ci-status-icon-canceled, .ci-status-icon-disabled, .ci-status-icon-not-found, diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss index 5b61270daa8..42a20e9775f 100644 --- a/app/assets/stylesheets/pages/tree.scss +++ b/app/assets/stylesheets/pages/tree.scss @@ -23,12 +23,11 @@ } &:hover { - cursor: pointer; - td { background-color: $row-hover; border-top: 1px solid $row-hover-border; border-bottom: 1px solid $row-hover-border; + cursor: pointer; } } diff --git a/app/controllers/admin/builds_controller.rb b/app/controllers/admin/builds_controller.rb index 0db91eaaf2e..88f3c0e2fd4 100644 --- a/app/controllers/admin/builds_controller.rb +++ b/app/controllers/admin/builds_controller.rb @@ -5,8 +5,10 @@ class Admin::BuildsController < Admin::ApplicationController @builds = @all_builds.order('created_at DESC') @builds = case @scope + when 'pending' + @builds.pending.reverse_order when 'running' - @builds.running_or_pending.reverse_order + @builds.running.reverse_order when 'finished' @builds.finished else diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9cc31620d9f..a1004d9bcea 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -344,10 +344,6 @@ class ApplicationController < ActionController::Base session[:skip_tfa] && session[:skip_tfa] > Time.current end - def browser_supports_u2f? - browser.chrome? && browser.version.to_i >= 41 && !browser.device.mobile? - end - def redirect_to_home_page_url? # If user is not signed-in and tries to access root_path - redirect him to landing page # Don't redirect to the default URL to prevent endless redirections diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb index 998b8adc411..ba07cea569c 100644 --- a/app/controllers/concerns/authenticates_with_two_factor.rb +++ b/app/controllers/concerns/authenticates_with_two_factor.rb @@ -57,7 +57,7 @@ module AuthenticatesWithTwoFactor # Authenticate using the response from a U2F (universal 2nd factor) device def authenticate_with_two_factor_via_u2f(user) - if U2fRegistration.authenticate(user, u2f_app_id, user_params[:device_response], session[:challenges]) + if U2fRegistration.authenticate(user, u2f_app_id, user_params[:device_response], session[:challenge]) # Remove any lingering user data from login session.delete(:otp_user_id) session.delete(:challenges) @@ -77,11 +77,9 @@ module AuthenticatesWithTwoFactor if key_handles.present? sign_requests = u2f.authentication_requests(key_handles) - challenges = sign_requests.map(&:challenge) - session[:challenges] = challenges - gon.push(u2f: { challenges: challenges, app_id: u2f_app_id, - sign_requests: sign_requests, - browser_supports_u2f: browser_supports_u2f? }) + session[:challenge] ||= u2f.challenge + gon.push(u2f: { challenge: session[:challenge], app_id: u2f_app_id, + sign_requests: sign_requests }) end end end diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb index 3a2db3e6eeb..19a76a5b5d8 100644 --- a/app/controllers/dashboard/todos_controller.rb +++ b/app/controllers/dashboard/todos_controller.rb @@ -1,6 +1,4 @@ class Dashboard::TodosController < Dashboard::ApplicationController - include TodosHelper - before_action :find_todos, only: [:index, :destroy_all] def index @@ -13,7 +11,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController respond_to do |format| format.html { redirect_to dashboard_todos_path, notice: 'Todo was successfully marked as done.' } format.js { head :ok } - format.json { render json: { count: todos_pending_count, done_count: todos_done_count } } + format.json { render json: todos_counts } end end @@ -23,7 +21,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController respond_to do |format| format.html { redirect_to dashboard_todos_path, notice: 'All todos were marked as done.' } format.js { head :ok } - format.json { render json: { count: todos_pending_count, done_count: todos_done_count } } + format.json { render json: todos_counts } end end @@ -36,4 +34,11 @@ class Dashboard::TodosController < Dashboard::ApplicationController def find_todos @todos ||= TodosFinder.new(current_user, params).execute end + + def todos_counts + { + count: TodosFinder.new(current_user, state: :pending).execute.count, + done_count: TodosFinder.new(current_user, state: :done).execute.count + } + end end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index f35d631df0c..f54c79c2e37 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -107,7 +107,11 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController # Only allow properly saved users to login. if @user.persisted? && @user.valid? log_audit_event(@user, with: oauth['provider']) - sign_in_and_redirect(@user) + if @user.two_factor_enabled? + prompt_for_two_factor(@user) + else + sign_in_and_redirect(@user) + end else error_message = @user.errors.full_messages.to_sentence diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb index 6a358fdcc05..e37e9e136db 100644 --- a/app/controllers/profiles/two_factor_auths_controller.rb +++ b/app/controllers/profiles/two_factor_auths_controller.rb @@ -100,7 +100,6 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController gon.push(u2f: { challenges: session[:challenges], app_id: u2f_app_id, register_requests: registration_requests, - sign_requests: sign_requests, - browser_supports_u2f: browser_supports_u2f? }) + sign_requests: sign_requests }) end end diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb index ef3051d7519..d7513d75f01 100644 --- a/app/controllers/projects/builds_controller.rb +++ b/app/controllers/projects/builds_controller.rb @@ -10,8 +10,10 @@ class Projects::BuildsController < Projects::ApplicationController @builds = @all_builds.order('created_at DESC') @builds = case @scope + when 'pending' + @builds.pending.reverse_order when 'running' - @builds.running_or_pending.reverse_order + @builds.running.reverse_order when 'finished' @builds.finished else diff --git a/app/controllers/projects/todos_controller.rb b/app/controllers/projects/todos_controller.rb index 23868d986e9..5685d0f4e7c 100644 --- a/app/controllers/projects/todos_controller.rb +++ b/app/controllers/projects/todos_controller.rb @@ -5,7 +5,7 @@ class Projects::TodosController < Projects::ApplicationController todo = TodoService.new.mark_todo(issuable, current_user) render json: { - count: current_user.todos_pending_count, + count: TodosFinder.new(current_user, state: :pending).execute.count, delete_path: dashboard_todo_path(todo) } end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 1803aa8eab4..4e5bcff9cf8 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -5,7 +5,7 @@ class ProjectsController < Projects::ApplicationController before_action :project, except: [:new, :create] before_action :repository, except: [:new, :create] before_action :assign_ref_vars, only: [:show], if: :repo_exists? - before_action :tree, only: [:show], if: :project_view_files? + before_action :tree, only: [:show], if: [:repo_exists?, :project_view_files?] # Authorize before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping, :download_export, :export, :remove_export, :generate_new_export] diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb index 7806d9e4cc5..ff866c2faa5 100644 --- a/app/finders/todos_finder.rb +++ b/app/finders/todos_finder.rb @@ -8,7 +8,7 @@ # action_id: integer # author_id: integer # project_id; integer -# state: 'pending' or 'done' +# state: 'pending' (default) or 'done' # type: 'Issue' or 'MergeRequest' # @@ -37,7 +37,7 @@ class TodosFinder private def action_id? - action_id.present? && [Todo::ASSIGNED, Todo::MENTIONED, Todo::BUILD_FAILED, Todo::MARKED].include?(action_id.to_i) + action_id.present? && Todo::ACTION_NAMES.has_key?(action_id.to_i) end def action_id diff --git a/app/helpers/appearances_helper.rb b/app/helpers/appearances_helper.rb index 950f323e383..e12a1052988 100644 --- a/app/helpers/appearances_helper.rb +++ b/app/helpers/appearances_helper.rb @@ -31,7 +31,7 @@ module AppearancesHelper end end - def navbar_icon(icon_name, size: 16) + def custom_icon(icon_name, size: 16) render "shared/icons/#{icon_name}.svg", size: size end end diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 428a42266d0..abe115d8c68 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -1,10 +1,7 @@ module BlobHelper - def highlighter(blob_name, blob_content, repository: nil, nowrap: false) - Gitlab::Highlight.new(blob_name, blob_content, nowrap: nowrap, repository: repository) - end - - def highlight(blob_name, blob_content, repository: nil, nowrap: false, plain: false) - Gitlab::Highlight.highlight(blob_name, blob_content, nowrap: nowrap, plain: plain, repository: repository) + def highlight(blob_name, blob_content, repository: nil, plain: false) + highlighted = Gitlab::Highlight.highlight(blob_name, blob_content, plain: plain, repository: repository) + raw %(<pre class="code highlight"><code>#{highlighted}</code></pre>) end def no_highlight_files diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 8e4ae1e6aec..e6c99c9959e 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -29,8 +29,10 @@ module CiStatusHelper 'check' when 'failed' 'close' - when 'running', 'pending' + when 'pending' 'clock-o' + when 'running' + 'spinner' else 'circle' end diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 294b7e92b8d..47d174361db 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -61,7 +61,7 @@ module IssuablesHelper output = content_tag :strong, "#{text} #{issuable.to_reference}", class: "identifier" output << " opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe output << content_tag(:strong) do - author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "hidden-xs") + author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "hidden-xs", tooltip: true) author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "hidden-sm hidden-md hidden-lg") end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 3bbbb26cff2..a733dff1579 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -19,7 +19,7 @@ module ProjectsHelper end def link_to_member(project, author, opts = {}, &block) - default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" } + default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name", tooltip: false } opts = default_opts.merge(opts) return "(deleted)" unless author @@ -33,7 +33,8 @@ module ProjectsHelper if opts[:by_username] author_html << content_tag(:span, sanitize("@#{author.username}"), class: opts[:author_class]) if opts[:name] else - author_html << content_tag(:span, sanitize(author.name), class: opts[:author_class]) if opts[:name] + tooltip_data = { placement: 'top' } + author_html << content_tag(:span, sanitize(author.name), class: [opts[:author_class], ('has-tooltip' if opts[:tooltip])], title: (author.to_reference if opts[:tooltip]), data: (tooltip_data if opts[:tooltip])) if opts[:name] end author_html << capture(&block) if block @@ -60,7 +61,7 @@ module ProjectsHelper project_link = link_to simple_sanitize(project.name), project_path(project), { class: "project-item-select-holder" } if current_user - project_link << icon("chevron-down", class: "dropdown-toggle-caret js-projects-dropdown-toggle", data: { target: ".js-dropdown-menu-projects", toggle: "dropdown" }) + project_link << icon("chevron-down", class: "dropdown-toggle-caret js-projects-dropdown-toggle", aria: { label: "Toggle switch project dropdown" }, data: { target: ".js-dropdown-menu-projects", toggle: "dropdown" }) end full_title = "#{namespace_link} / #{project_link}".html_safe diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index b165b569372..fcb2703e837 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -45,7 +45,7 @@ module SearchHelper [ { category: "Help", label: "API Help", url: help_page_path("api/README") }, { category: "Help", label: "Markdown Help", url: help_page_path("markdown/markdown") }, - { category: "Help", label: "Permissions Help", url: help_page_path("permissions/permissions") }, + { category: "Help", label: "Permissions Help", url: help_page_path("user/permissions") }, { category: "Help", label: "Public Access Help", url: help_page_path("public_access/public_access") }, { category: "Help", label: "Rake Tasks Help", url: help_page_path("raketasks/README") }, { category: "Help", label: "SSH Keys Help", url: help_page_path("ssh/README") }, diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index a832a6c8df7..e3a208f826a 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -1,10 +1,10 @@ module TodosHelper def todos_pending_count - TodosFinder.new(current_user, state: :pending).execute.count + @todos_pending_count ||= TodosFinder.new(current_user, state: :pending).execute.count end def todos_done_count - TodosFinder.new(current_user, state: :done).execute.count + @todos_done_count ||= TodosFinder.new(current_user, state: :done).execute.count end def todo_action_name(todo) @@ -13,6 +13,7 @@ module TodosHelper when Todo::MENTIONED then 'mentioned you on' when Todo::BUILD_FAILED then 'The build failed for your' when Todo::MARKED then 'added a todo for' + when Todo::APPROVAL_REQUIRED then 'set you as an approver for' end end diff --git a/app/helpers/u2f_helper.rb b/app/helpers/u2f_helper.rb new file mode 100644 index 00000000000..143b4ca6b51 --- /dev/null +++ b/app/helpers/u2f_helper.rb @@ -0,0 +1,5 @@ +module U2fHelper + def inject_u2f_api? + browser.chrome? && browser.version.to_i >= 41 && !browser.device.mobile? + end +end diff --git a/app/models/ability.rb b/app/models/ability.rb index eeb0ceba081..6fd18f2ee24 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -204,7 +204,8 @@ class Ability :download_code, :fork_project, :read_commit_status, - :read_pipeline + :read_pipeline, + :read_container_image ] end diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index e189dbac285..ffac3a22efc 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -5,6 +5,7 @@ module Ci belongs_to :erased_by, class_name: 'User' serialize :options + serialize :yaml_variables validates :coverage, numericality: true, allow_blank: true validates_presence_of :ref @@ -52,7 +53,10 @@ module Ci new_build.stage = build.stage new_build.stage_idx = build.stage_idx new_build.trigger_request = build.trigger_request + new_build.yaml_variables = build.yaml_variables + new_build.when = build.when new_build.user = user + new_build.environment = build.environment new_build.save MergeRequests::AddTodoWhenBuildFailsService.new(build.project, nil).close(new_build) new_build @@ -117,7 +121,12 @@ module Ci end def variables - predefined_variables + yaml_variables + project_variables + trigger_variables + variables = [] + variables += predefined_variables + variables += yaml_variables if yaml_variables + variables += project_variables + variables += trigger_variables + variables end def merge_request @@ -394,30 +403,6 @@ module Ci self.update(erased_by: user, erased_at: Time.now, artifacts_expire_at: nil) end - def yaml_variables - global_yaml_variables + job_yaml_variables - end - - def global_yaml_variables - if pipeline.config_processor - pipeline.config_processor.global_variables.map do |key, value| - { key: key, value: value, public: true } - end - else - [] - end - end - - def job_yaml_variables - if pipeline.config_processor - pipeline.config_processor.job_variables(name).map do |key, value| - { key: key, value: value, public: true } - end - else - [] - end - end - def project_variables project.variables.map do |variable| { key: variable.key, value: variable.value, public: false } diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index fa4071e2482..b468434866b 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -6,6 +6,8 @@ module Ci self.table_name = 'ci_commits' belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id + belongs_to :user + has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id has_many :builds, class_name: 'Ci::Build', foreign_key: :commit_id has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest', foreign_key: :commit_id @@ -215,6 +217,8 @@ module Ci end def keep_around_commits + return unless project + project.repository.keep_around(self.sha) project.repository.keep_around(self.before_sha) end diff --git a/app/models/concerns/awardable.rb b/app/models/concerns/awardable.rb index 06beff177b1..800a16ab246 100644 --- a/app/models/concerns/awardable.rb +++ b/app/models/concerns/awardable.rb @@ -65,8 +65,7 @@ module Awardable def create_award_emoji(name, current_user) return unless emoji_awardable? - - award_emoji.create(name: name, user: current_user) + award_emoji.create(name: normalize_name(name), user: current_user) end def remove_award_emoji(name, current_user) @@ -80,4 +79,10 @@ module Awardable create_award_emoji(emoji_name, current_user) end end + + private + + def normalize_name(name) + Gitlab::AwardEmoji.normalize_emoji_name(name) + end end diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb index 8cac47246db..ec9e0f1b1d0 100644 --- a/app/models/concerns/mentionable.rb +++ b/app/models/concerns/mentionable.rb @@ -14,14 +14,14 @@ module Mentionable attr = attr.to_s mentionable_attrs << [attr, options] end + end + included do # Accessor for attributes marked mentionable. - def mentionable_attrs - @mentionable_attrs ||= [] + cattr_accessor :mentionable_attrs, instance_accessor: false do + [] end - end - included do if self < Participable participant -> (user, ext) { all_references(user, extractor: ext) } end diff --git a/app/models/concerns/participable.rb b/app/models/concerns/participable.rb index 9822844357d..70740c76e43 100644 --- a/app/models/concerns/participable.rb +++ b/app/models/concerns/participable.rb @@ -41,9 +41,12 @@ module Participable def participant(attr) participant_attrs << attr end + end - def participant_attrs - @participant_attrs ||= [] + included do + # Accessor for participant attributes. + cattr_accessor :participant_attrs, instance_accessor: false do + [] end end diff --git a/app/models/label.rb b/app/models/label.rb index dc5586f5756..35e678001dc 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -52,14 +52,17 @@ class Label < ActiveRecord::Base # This pattern supports cross-project references. # def self.reference_pattern + # NOTE: The id pattern only matches when all characters on the expression + # are digits, so it will match ~2 but not ~2fa because that's probably a + # label name and we want it to be matched as such. @reference_pattern ||= %r{ (#{Project.reference_pattern})? #{Regexp.escape(reference_prefix)} (?: - (?<label_id>\d+) | # Integer-based label ID, or + (?<label_id>\d+(?!\S\w)\b) | # Integer-based label ID, or (?<label_name> - [A-Za-z0-9_\-\?&]+ | # String-based single-word label title, or - "[^,]+" # String-based multi-word label surrounded in quotes + [A-Za-z0-9_\-\?\.&]+ | # String-based single-word label title, or + ".+?" # String-based multi-word label surrounded in quotes ) ) }x diff --git a/app/models/legacy_diff_note.rb b/app/models/legacy_diff_note.rb index 790dfd4d480..04a651d50ab 100644 --- a/app/models/legacy_diff_note.rb +++ b/app/models/legacy_diff_note.rb @@ -38,7 +38,7 @@ class LegacyDiffNote < Note end def diff_line - @diff_line ||= diff_file.line_for_line_code(self.line_code) + @diff_line ||= diff_file.line_for_line_code(self.line_code) if diff_file end def for_line?(line) @@ -55,7 +55,7 @@ class LegacyDiffNote < Note def active? return @active if defined?(@active) return true if for_commit? - return true unless self.diff + return true unless diff_line return false unless noteable noteable_diff = find_noteable_diff diff --git a/app/models/note.rb b/app/models/note.rb index 8dca2ef09a8..0ce10c77de9 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -229,8 +229,7 @@ class Note < ActiveRecord::Base end def award_emoji_name - original_name = note.match(Banzai::Filter::EmojiFilter.emoji_pattern)[1] - Gitlab::AwardEmoji.normalize_emoji_name(original_name) + note.match(Banzai::Filter::EmojiFilter.emoji_pattern)[1] end private diff --git a/app/models/project.rb b/app/models/project.rb index a66b750cd48..1cdf22f6a51 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -464,8 +464,8 @@ class Project < ActiveRecord::Base return super(value) unless Gitlab::UrlSanitizer.valid?(value) import_url = Gitlab::UrlSanitizer.new(value) - create_or_update_import_data(credentials: import_url.credentials) super(import_url.sanitized_url) + create_or_update_import_data(credentials: import_url.credentials) end def import_url @@ -477,7 +477,13 @@ class Project < ActiveRecord::Base end end + def valid_import_url? + valid? || errors.messages[:import_url].nil? + end + def create_or_update_import_data(data: nil, credentials: nil) + return unless import_url.present? && valid_import_url? + project_import_data = import_data || build_import_data if data project_import_data.data ||= {} @@ -1032,8 +1038,8 @@ class Project < ActiveRecord::Base pipelines.order(id: :desc).find_by(sha: sha, ref: ref) end - def ensure_pipeline(sha, ref) - pipeline(sha, ref) || pipelines.create(sha: sha, ref: ref) + def ensure_pipeline(sha, ref, current_user = nil) + pipeline(sha, ref) || pipelines.create(sha: sha, ref: ref, user: current_user) end def enable_ci diff --git a/app/models/todo.rb b/app/models/todo.rb index ac3fdbc7f3b..8d7a5965aa1 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -1,14 +1,16 @@ class Todo < ActiveRecord::Base - ASSIGNED = 1 - MENTIONED = 2 - BUILD_FAILED = 3 - MARKED = 4 + ASSIGNED = 1 + MENTIONED = 2 + BUILD_FAILED = 3 + MARKED = 4 + APPROVAL_REQUIRED = 5 # This is an EE-only feature ACTION_NAMES = { ASSIGNED => :assigned, MENTIONED => :mentioned, BUILD_FAILED => :build_failed, - MARKED => :marked + MARKED => :marked, + APPROVAL_REQUIRED => :approval_required } belongs_to :author, class_name: "User" diff --git a/app/models/user.rb b/app/models/user.rb index 79c670cb35a..3d0a033785c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -85,9 +85,10 @@ class User < ActiveRecord::Base has_one :abuse_report, dependent: :destroy has_many :spam_logs, dependent: :destroy has_many :builds, dependent: :nullify, class_name: 'Ci::Build' + has_many :pipelines, dependent: :nullify, class_name: 'Ci::Pipeline' has_many :todos, dependent: :destroy has_many :notification_settings, dependent: :destroy - has_many :award_emoji, as: :awardable, dependent: :destroy + has_many :award_emoji, dependent: :destroy # # Validations diff --git a/app/services/ci/create_builds_service.rb b/app/services/ci/create_builds_service.rb index 2dcb052d274..3b21f0acb96 100644 --- a/app/services/ci/create_builds_service.rb +++ b/app/services/ci/create_builds_service.rb @@ -36,7 +36,9 @@ module Ci :allow_failure, :stage, :stage_idx, - :environment) + :environment, + :when, + :yaml_variables) build_attrs.merge!(pipeline: @pipeline, ref: @pipeline.ref, diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index b1ee6874190..be91bf0db85 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -2,6 +2,7 @@ module Ci class CreatePipelineService < BaseService def execute pipeline = project.pipelines.new(params) + pipeline.user = current_user unless ref_names.include?(params[:ref]) pipeline.errors.add(:base, 'Reference not found') diff --git a/app/services/create_commit_builds_service.rb b/app/services/create_commit_builds_service.rb index f947e8f452e..0b66b854dea 100644 --- a/app/services/create_commit_builds_service.rb +++ b/app/services/create_commit_builds_service.rb @@ -14,7 +14,13 @@ class CreateCommitBuildsService return false end - @pipeline = Ci::Pipeline.new(project: project, sha: sha, ref: ref, before_sha: before_sha, tag: tag) + @pipeline = Ci::Pipeline.new( + project: project, + sha: sha, + ref: ref, + before_sha: before_sha, + tag: tag, + user: user) ## # Skip creating pipeline if no gitlab-ci.yml is found diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb index 02fca5c0ea3..18971bd0be3 100644 --- a/app/services/notes/create_service.rb +++ b/app/services/notes/create_service.rb @@ -8,7 +8,6 @@ module Notes if note.award_emoji? noteable = note.noteable todo_service.new_award_emoji(noteable, current_user) - return noteable.create_award_emoji(note.award_emoji_name, current_user) end diff --git a/app/services/projects/housekeeping_service.rb b/app/services/projects/housekeeping_service.rb index c9ad710b7bf..29b3981f49f 100644 --- a/app/services/projects/housekeeping_service.rb +++ b/app/services/projects/housekeeping_service.rb @@ -22,11 +22,7 @@ module Projects def execute raise LeaseTaken unless try_obtain_lease - GitGarbageCollectWorker.perform_async(@project.id) - ensure - Gitlab::Metrics.measure(:reset_pushes_since_gc) do - update_pushes_since_gc(0) - end + execute_gitlab_shell_gc end def needed? @@ -34,19 +30,27 @@ module Projects end def increment! - Gitlab::Metrics.measure(:increment_pushes_since_gc) do - update_pushes_since_gc(@project.pushes_since_gc + 1) + if Gitlab::ExclusiveLease.new("project_housekeeping:increment!:#{@project.id}", timeout: 60).try_obtain + Gitlab::Metrics.measure(:increment_pushes_since_gc) do + update_pushes_since_gc(@project.pushes_since_gc + 1) + end end end private - def update_pushes_since_gc(new_value) - if Gitlab::ExclusiveLease.new("project_housekeeping:update_pushes_since_gc:#{project.id}", timeout: 60).try_obtain - @project.update_column(:pushes_since_gc, new_value) + def execute_gitlab_shell_gc + GitGarbageCollectWorker.perform_async(@project.id) + ensure + Gitlab::Metrics.measure(:reset_pushes_since_gc) do + update_pushes_since_gc(0) end end + def update_pushes_since_gc(new_value) + @project.update_column(:pushes_since_gc, new_value) + end + def try_obtain_lease Gitlab::Metrics.measure(:obtain_housekeeping_lease) do lease = ::Gitlab::ExclusiveLease.new("project_housekeeping:#{@project.id}", timeout: LEASE_TIMEOUT) diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index 6afc048576d..998789d64d2 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -10,7 +10,7 @@ module Projects def save_all if [version_saver, project_tree_saver, uploads_saver, repo_saver, wiki_repo_saver].all?(&:save) - Gitlab::ImportExport::Saver.save(shared: @shared) + Gitlab::ImportExport::Saver.save(project: project, shared: @shared) notify_success else cleanup_and_notify diff --git a/app/services/projects/import_service.rb b/app/services/projects/import_service.rb index 163ebf26c84..cdad0426b02 100644 --- a/app/services/projects/import_service.rb +++ b/app/services/projects/import_service.rb @@ -43,7 +43,7 @@ module Projects def import_repository begin gitlab_shell.import_repository(project.repository_storage_path, project.path_with_namespace, project.import_url) - rescue Gitlab::Shell::Error => e + rescue => e raise Error, "Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}" end end diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb index 6bb0a72d30e..6b48d68cccb 100644 --- a/app/services/todo_service.rb +++ b/app/services/todo_service.rb @@ -194,7 +194,7 @@ class TodoService end def create_assignment_todo(issuable, author) - if issuable.assignee && issuable.assignee != author + if issuable.assignee attributes = attributes_for_todo(issuable.project, issuable, author, Todo::ASSIGNED) create_todos(issuable.assignee, attributes) end @@ -239,7 +239,6 @@ class TodoService def filter_mentioned_users(project, target, author) mentioned_users = target.mentioned_users(author) mentioned_users = reject_users_without_access(mentioned_users, project, target) - mentioned_users.delete(author) mentioned_users.uniq end diff --git a/app/views/admin/builds/_build.html.haml b/app/views/admin/builds/_build.html.haml index 967151bc33b..ce818c30c30 100644 --- a/app/views/admin/builds/_build.html.haml +++ b/app/views/admin/builds/_build.html.haml @@ -1,30 +1,40 @@ - project = build.project -%tr.build +%tr.build.commit %td.status = ci_status_with_icon(build.status) - %td.build-link - - 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} + %td + .branch-commit + - if can?(current_user, :read_build, build.project) + = link_to namespace_project_build_url(build.project.namespace, build.project, build) do + %span.build-link ##{build.id} + - else + %span.build-link ##{build.id} - - if build.stuck? - %i.fa.fa-warning.text-warning + - if build.stuck? + %i.fa.fa-warning.text-warning - %td - - if project - = link_to project.name_with_namespace, admin_namespace_project_path(project.namespace, project) + - if build.ref + = link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref), class: "monospace branch-name" + - else + .light none + = custom_icon("icon_commit") - %td - = link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "monospace" + = link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "monospace commit-id" + + .label-container + - 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 - - if build.ref - = link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref) - - else - .light none + - if project + = link_to project.name_with_namespace, admin_namespace_project_path(project.namespace, project) %td - if build.try(:runner) @@ -36,22 +46,15 @@ #{build.stage} / #{build.name} %td - - 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)} + %p.duration + = custom_icon("icon_timer") + = duration_in_numbers(build.finished_at, build.started_at) - %td.timestamp - if build.finished_at - %span #{time_ago_with_tooltip(build.finished_at)} + %p.finished-at + = icon("calendar") + %span #{time_ago_with_tooltip(build.finished_at)} - if defined?(coverage) && coverage %td.coverage diff --git a/app/views/admin/builds/index.html.haml b/app/views/admin/builds/index.html.haml index 1e60205f91a..3d77634d8fa 100644 --- a/app/views/admin/builds/index.html.haml +++ b/app/views/admin/builds/index.html.haml @@ -10,15 +10,20 @@ All %span.badge.js-totalbuilds-count= @all_builds.count(:id) + %li{class: ('active' if @scope == 'pending')} + = link_to admin_builds_path(scope: :pending) do + Pending + %span.badge= number_with_delimiter(@all_builds.pending.count(:id)) + %li{class: ('active' if @scope == 'running')} = link_to admin_builds_path(scope: :running) do Running - %span.badge.js-running-count= number_with_delimiter(@all_builds.running_or_pending.count(:id)) + %span.badge= number_with_delimiter(@all_builds.running.count(:id)) %li{class: ('active' if @scope == 'finished')} = link_to admin_builds_path(scope: :finished) do Finished - %span.badge.js-running-count= number_with_delimiter(@all_builds.finished.count(:id)) + %span.badge= number_with_delimiter(@all_builds.finished.count(:id)) .nav-controls - if @all_builds.running_or_pending.any? @@ -27,7 +32,7 @@ .row-content-block.second-block #{(@scope || 'all').capitalize} builds - %ul.content-list + %ul.content-list.builds-content-list - if @builds.blank? %li .nothing-here-block No builds to show @@ -37,15 +42,11 @@ %thead %tr %th Status - %th Build ID - %th Project %th Commit - %th Ref + %th Project %th Runner %th Name - %th Tags - %th Duration - %th Finished at + %th %th - @builds.each do |build| diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml index 59fd6c3fea0..77a11e49e20 100644 --- a/app/views/admin/groups/_group.html.haml +++ b/app/views/admin/groups/_group.html.haml @@ -1,20 +1,26 @@ -- css_class = '' unless local_assigns[:css_class] +- css_class = 'no-description' if group.description.blank? -%li.group-row.group-admin{ class: css_class } - .group-avatar - = image_tag group_icon(group), class: 'avatar hidden-xs' - .group-details - .title - = link_to [:admin, group], class: 'group-name' do - = group.name - .group-stats - %span>= pluralize(number_with_delimiter(group.projects.count), 'project') - , - %span= pluralize(number_with_delimiter(group.users.count), 'member') - - - if group.description.present? - .description - = markdown(group.description, pipeline: :description) - .group-controls.hidden-xs +%li.group-row{ class: css_class } + .controls = link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: 'btn' = link_to 'Delete', [:admin, group], data: { confirm: "Are you sure you want to remove #{group.name}?" }, method: :delete, class: 'btn btn-remove' + .stats + %span + = icon('bookmark') + = number_with_delimiter(group.projects.count) + + %span + = icon('users') + = number_with_delimiter(group.users.count) + + %span.visibility-icon.has-tooltip{data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group)} + = visibility_level_icon(group.visibility_level, fw: false) + + = image_tag group_icon(group), class: "avatar s40 hidden-xs" + .title + = link_to [:admin, group], class: 'group-name' do + = group.name + + - if group.description.present? + .description + = markdown(group.description, pipeline: :description) diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 40c8169ad9d..bb374694400 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -79,7 +79,7 @@ .panel-body.form-holder %p.light Read more about project permissions - %strong= link_to "here", help_page_path("permissions/permissions"), class: "vlink" + %strong= link_to "here", help_page_path("user/permissions"), class: "vlink" = form_tag members_update_admin_group_path(@group), id: "new_project_member", class: "bulk_import", method: :put do %div diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index 7fbce25b2c4..1e755785d90 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -66,7 +66,7 @@ %ul.projects-list.content-list - @projects.each_with_index do |project| %li.project-row - .controls.pull-right + .controls - if project.archived %span.label.label-warning archived %span.label.label-gray diff --git a/app/views/admin/users/_user.html.haml b/app/views/admin/users/_user.html.haml index d3519f616f6..4bf1c9cde3c 100644 --- a/app/views/admin/users/_user.html.haml +++ b/app/views/admin/users/_user.html.haml @@ -14,7 +14,7 @@ %span It's you! .user-email = mail_to user.email, user.email - .controls.pull-right + .controls = link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: 'btn' - unless user == current_user .dropdown.inline diff --git a/app/views/dashboard/projects/_zero_authorized_projects.html.haml b/app/views/dashboard/projects/_zero_authorized_projects.html.haml index d54c7cad7be..fdea834ff45 100644 --- a/app/views/dashboard/projects/_zero_authorized_projects.html.haml +++ b/app/views/dashboard/projects/_zero_authorized_projects.html.haml @@ -1,53 +1,46 @@ - publicish_project_count = ProjectsFinder.new.execute(current_user).count -%h3.page-title Welcome to GitLab! -%p.light Self hosted Git management application. -%hr -%div - .dashboard-intro-icon - %i.fa.fa-bookmark-o - .dashboard-intro-text - %p.slead - You don't have access to any projects right now. - %br - - if current_user.can_create_project? - You can create up to - %strong= pluralize(number_with_delimiter(current_user.projects_limit), "project") + "." - - else - If you are added to a project, it will be displayed here. - +.blank-state.blank-state-welcome + %h2.blank-state-welcome-title + Welcome to GitLab + %p.blank-state-text + Code, test, and deploy together +.blank-state + .blank-state-icon + = custom_icon("project", size: 50) + %h3.blank-state-title + You don't have access to any projects right now + %p.blank-state-text - if current_user.can_create_project? - .link_holder - = link_to new_project_path, class: "btn btn-new" do - = icon('plus') - New Project + You can create up to + %strong= number_with_delimiter(current_user.projects_limit) + = succeed "." do + = "project".pluralize(current_user.projects_limit) + - else + If you are added to a project, it will be displayed here. + - if current_user.can_create_project? + = link_to new_project_path, class: "btn btn-new" do + New project - if current_user.can_create_group? - %hr - %div - .dashboard-intro-icon - %i.fa.fa-users - .dashboard-intro-text - %p.slead - You can create a group for several dependent projects. - %br - Groups are the best way to manage projects and members. - .link_holder - = link_to new_group_path, class: "btn btn-new" do - %i.fa.fa-plus - New Group + .blank-state + .blank-state-icon + = custom_icon("group", size: 50) + %h3.blank-state-title + You can create a group for several dependent projects. + %p.blank-state-text + Groups are the best way to manage projects and members. + = link_to new_group_path, class: "btn btn-new" do + New group -if publicish_project_count > 0 - %hr - %div - .dashboard-intro-icon - %i.fa.fa-globe - .dashboard-intro-text - %p.slead - There are - %strong= number_with_delimiter(publicish_project_count) - public projects on this server. - %br - Public projects are an easy way to allow everyone to have read-only access. - .link_holder - = link_to trending_explore_projects_path, class: "btn btn-new" do - Browse public projects + .blank-state + .blank-state-icon + = icon("globe") + %h3.blank-state-title + There are + = number_with_delimiter(publicish_project_count) + public projects on this server. + %p.blank-state-text + Public projects are an easy way to allow everyone to have read-only access. + = link_to trending_explore_projects_path, class: "btn btn-new" do + Browse projects diff --git a/app/views/dashboard/projects/index.html.haml b/app/views/dashboard/projects/index.html.haml index 4565e752c1f..4f36a4a1c73 100644 --- a/app/views/dashboard/projects/index.html.haml +++ b/app/views/dashboard/projects/index.html.haml @@ -5,7 +5,8 @@ - page_title "Projects" - header_title "Projects", dashboard_projects_path -= render 'dashboard/projects_head' +- if @projects.any? || params[:filter_projects] + = render 'dashboard/projects_head' - if @last_push = render "events/event_last_push", event: @last_push diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml index fc42e5dcc66..4e340b6ec16 100644 --- a/app/views/dashboard/todos/index.html.haml +++ b/app/views/dashboard/todos/index.html.haml @@ -9,14 +9,14 @@ %span To do %span.badge - = todos_pending_count + = number_with_delimiter(todos_pending_count) - 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 %span.badge - = todos_done_count + = number_with_delimiter(todos_done_count) .nav-controls - if @todos.any?(&:pending?) diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml index a373f61bd3c..4debd3d608f 100644 --- a/app/views/devise/sessions/two_factor.html.haml +++ b/app/views/devise/sessions/two_factor.html.haml @@ -1,3 +1,7 @@ +- if inject_u2f_api? + - content_for :page_specific_javascripts do + = page_specific_javascript_tag('u2f.js') + %div .login-box .login-heading diff --git a/app/views/errors/access_denied.html.haml b/app/views/errors/access_denied.html.haml index 2febeef99d3..c034bbe430e 100644 --- a/app/views/errors/access_denied.html.haml +++ b/app/views/errors/access_denied.html.haml @@ -3,4 +3,4 @@ %h3 Access Denied %hr %p You are not allowed to access this page. -%p Read more about project permissions #{link_to "here", help_page_path("permissions/permissions"), class: "vlink"} +%p Read more about project permissions #{link_to "here", help_page_path("user/permissions"), class: "vlink"} diff --git a/app/views/groups/group_members/_new_group_member.html.haml b/app/views/groups/group_members/_new_group_member.html.haml index 13ded2bc455..9bb9f962177 100644 --- a/app/views/groups/group_members/_new_group_member.html.haml +++ b/app/views/groups/group_members/_new_group_member.html.haml @@ -12,7 +12,7 @@ = select_tag :access_level, options_for_select(GroupMember.access_level_roles, @group_member.access_level), class: "project-access-select select2" .help-block Read more about role permissions - %strong= link_to "here", help_page_path("permissions/permissions"), class: "vlink" + %strong= link_to "here", help_page_path("user/permissions"), class: "vlink" .form-actions = f.submit 'Add users to group', class: "btn btn-create" diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index a83eb7e88bb..eddeae98bc4 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -6,8 +6,7 @@ .cover-block.groups-cover-block %div{ class: container_class } - = link_to group_icon(@group), target: '_blank' do - = image_tag group_icon(@group), class: "avatar group-avatar s70" + = image_tag group_icon(@group), class: "avatar group-avatar s70" .group-info .cover-title %h1 diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml index 8cc0b59edeb..ce4536ebdc6 100644 --- a/app/views/help/_shortcuts.html.haml +++ b/app/views/help/_shortcuts.html.haml @@ -20,6 +20,10 @@ %td Focus Search %tr %td.shortcut + .key f + %td Focus Filter + %tr + %td.shortcut .key ? %td Show/hide this dialog %tr diff --git a/app/views/layouts/_collapse_button.html.haml b/app/views/layouts/_collapse_button.html.haml deleted file mode 100644 index 8c140a5943e..00000000000 --- a/app/views/layouts/_collapse_button.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -= link_to '#', class: 'nav-header-btn text-center toggle-nav-collapse', title: "Open/Close" do - %span.sr-only Toggle navigation - = icon('bars') diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index 8596bbfdef6..a1a71c2fb33 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -1,6 +1,13 @@ .page-with-sidebar{ class: "#{page_sidebar_class} #{page_gutter_class}" } .sidebar-wrapper.nicescroll{ class: nav_sidebar_class } - = render partial: 'layouts/collapse_button' + .sidebar-action-buttons + = link_to '#', class: 'nav-header-btn toggle-nav-collapse', title: "Open/Close" do + %span.sr-only Toggle navigation + = icon('bars') + = link_to '#', class: "nav-header-btn pin-nav-btn has-tooltip #{'is-active' if pinned_nav?} js-nav-pin", title: pinned_nav? ? "Unpin navigation" : "Pin Navigation", data: {placement: 'right', container: 'body'} do + %span.sr-only Toggle navigation pinning + = icon('fw thumb-tack') + - if defined?(sidebar) && sidebar = render "layouts/nav/#{sidebar}" - elsif current_user @@ -8,9 +15,6 @@ - else = render 'layouts/nav/explore' - = link_to '#', class: "nav-header-btn text-center pin-nav-btn has-tooltip #{'is-active' if pinned_nav?} js-nav-pin", title: pinned_nav? ? "Unpin navigation" : "Pin Navigation", data: {placement: 'right', container: 'body'} do - %span.sr-only Toggle navigation pinning - = icon('thumb-tack') - if defined?(nav) && nav .layout-nav .container-fluid diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index 245b9c3b4d4..f7580f00159 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -44,7 +44,7 @@ name: "#{j(@project.name)}" }; - - if @group and @group.path + - if @group && @group.persisted? && @group.path :javascript gl.groupOptions = gl.groupOptions || {}; gl.groupOptions["#{j(@group.path)}"] = { diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 11cee421a99..94c53882623 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -1,7 +1,7 @@ %header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class } %div{ class: fluid_layout ? "container-fluid" : "container-fluid" } .header-content - %button.side-nav-toggle{type: 'button'} + %button.side-nav-toggle{ type: 'button', "aria-label" => "Toggle global navigation" } %span.sr-only Toggle navigation = icon('bars') %button.navbar-toggle{type: 'button'} @@ -13,25 +13,25 @@ %li.hidden-sm.hidden-xs = render 'layouts/search' unless current_controller?(:search) %li.visible-sm.visible-xs - = link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = link_to search_path, title: 'Search', aria: { label: "Search" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = icon('search') - if current_user - if session[:impersonator_id] %li.impersonation - = link_to admin_impersonation_path, method: :delete, title: 'Stop Impersonation', data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do + = link_to admin_impersonation_path, method: :delete, title: "Stop Impersonation", aria: { label: 'Stop Impersonation' }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do = icon('user-secret fw') - if current_user.is_admin? %li - = link_to admin_root_path, title: 'Admin Area', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = link_to admin_root_path, title: 'Admin Area', aria: { label: "Admin Area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = icon('wrench fw') %li - = link_to dashboard_todos_path, title: 'Todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = icon('bell fw') %span.badge.todos-pending-count{ class: ("hidden" if todos_pending_count == 0) } = todos_pending_count - if current_user.can_create_project? %li - = link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = link_to new_project_path, title: 'New project', aria: { label: "New project" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = icon('plus fw') - if Gitlab::Sherlock.enabled? %li @@ -45,12 +45,12 @@ .dropdown-menu-nav.dropdown-menu-align-right %ul %li - = link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username } + = link_to "Profile", current_user, class: 'profile-link', aria: { label: "Profile" }, data: { user: current_user.username } %li - = link_to "Profile Settings", profile_path + = link_to "Profile Settings", profile_path, aria: { label: "Profile Settings" } %li.divider %li - = link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link", title: 'Sign out' + = link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link", aria: { label: "Sign out" } - else %li %div diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml index 52e41b1a857..21668698814 100644 --- a/app/views/layouts/nav/_dashboard.html.haml +++ b/app/views/layouts/nav/_dashboard.html.haml @@ -1,64 +1,44 @@ %ul.nav.nav-sidebar = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: {class: "#{project_tab_class} home"}) do = link_to dashboard_projects_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do - .icon-container - = navbar_icon('project') %span Projects = nav_link(controller: :todos) do = link_to dashboard_todos_path, title: 'Todos' do - .icon-container - = icon('bell fw') %span Todos %span.count= number_with_delimiter(todos_pending_count) = nav_link(path: 'dashboard#activity') do = link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: 'Activity' do - .icon-container - = navbar_icon('activity') %span Activity = nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do = link_to dashboard_groups_path, title: 'Groups' do - .icon-container - = navbar_icon('group') %span Groups = nav_link(controller: 'dashboard/milestones') do = link_to dashboard_milestones_path, title: 'Milestones' do - .icon-container - = navbar_icon('milestones') %span Milestones = nav_link(path: 'dashboard#issues') do = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'dashboard-shortcuts-issues' do - .icon-container - = navbar_icon('issues') %span Issues %span.count= number_with_delimiter(current_user.assigned_issues.opened.count) = nav_link(path: 'dashboard#merge_requests') do = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'dashboard-shortcuts-merge_requests' do - .icon-container - = navbar_icon('mr') %span Merge Requests %span.count= number_with_delimiter(current_user.assigned_merge_requests.opened.count) = nav_link(controller: :snippets) do = link_to dashboard_snippets_path, title: 'Snippets' do - .icon-container - = icon('clipboard fw') %span Snippets = nav_link(controller: :help) do = link_to help_path, title: 'Help' do - .icon-container - = icon('question-circle fw') %span Help = nav_link(html_options: {class: profile_tab_class}) do = link_to profile_path, title: 'Profile Settings', data: {placement: 'bottom'} do - .icon-container - = icon('user fw') %span Profile Settings diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index 96fe62c39c3..6d514f669db 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -18,9 +18,9 @@ %span Applications = nav_link(controller: :personal_access_tokens) do - = link_to profile_personal_access_tokens_path, title: 'Personal Access Tokens' do + = link_to profile_personal_access_tokens_path, title: 'Access Tokens' do %span - Personal Access Tokens + Access Tokens = nav_link(controller: :emails) do = link_to profile_emails_path, title: 'Emails' do %span diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml index 35c4b862bb7..ea7e3d199fd 100644 --- a/app/views/notify/note_merge_request_email.html.haml +++ b/app/views/notify/note_merge_request_email.html.haml @@ -1,4 +1,4 @@ -- if @note.diff_note? +- if @note.diff_note? && @note.diff_file %p.details New comment on diff for = link_to @note.diff_file.file_path, @target_url diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml index 8780da1dec4..366f1fed35b 100644 --- a/app/views/profiles/two_factor_auths/show.html.haml +++ b/app/views/profiles/two_factor_auths/show.html.haml @@ -2,6 +2,10 @@ - header_title "Two-Factor Authentication", profile_two_factor_auth_path = render 'profiles/head' +- if inject_u2f_api? + - content_for :page_specific_javascripts do + = page_specific_javascript_tag('u2f.js') + .row.prepend-top-default .col-lg-3 %h4.prepend-top-0 diff --git a/app/views/projects/builds/index.html.haml b/app/views/projects/builds/index.html.haml index 381b3754cd5..2af625f69cd 100644 --- a/app/views/projects/builds/index.html.haml +++ b/app/views/projects/builds/index.html.haml @@ -11,17 +11,22 @@ %span.badge.js-totalbuilds-count = number_with_delimiter(@all_builds.count(:id)) + %li{class: ('active' if @scope == 'pending')} + = link_to project_builds_path(@project, scope: :pending) do + Pending + %span.badge + = number_with_delimiter(@all_builds.pending.count(:id)) %li{class: ('active' if @scope == 'running')} = link_to project_builds_path(@project, scope: :running) do Running - %span.badge.js-running-count - = number_with_delimiter(@all_builds.running_or_pending.count(:id)) + %span.badge + = number_with_delimiter(@all_builds.running.count(:id)) %li{class: ('active' if @scope == 'finished')} = link_to project_builds_path(@project, scope: :finished) do Finished - %span.badge.js-running-count + %span.badge = number_with_delimiter(@all_builds.finished.count(:id)) .nav-controls @@ -36,7 +41,7 @@ = link_to ci_lint_path, class: 'btn btn-default' do %span CI Lint - %ul.content-list + %ul.content-list.builds-content-list - if @builds.blank? %li .nothing-here-block No builds to show @@ -46,14 +51,10 @@ %thead %tr %th Status - %th Build ID %th Commit - %th Ref %th Stage %th Name - %th Tags - %th Duration - %th Finished at + %th - if @project.build_coverage_enabled? %th Coverage %th diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml index 5bd6e3f0ebc..e1b42b2cfa5 100644 --- a/app/views/projects/ci/builds/_build.html.haml +++ b/app/views/projects/ci/builds/_build.html.haml @@ -1,32 +1,45 @@ -%tr.build +%tr.build.commit %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} + %td + .branch-commit + - if can?(current_user, :read_build, build) + = link_to namespace_project_build_url(build.project.namespace, build.project, build) do + %span ##{build.id} + - else + %span ##{build.id} - - if build.stuck? - = icon('warning', class: 'text-warning has-tooltip', title: 'Build is stuck. Check runners.') - - if defined?(retried) && retried - = icon('warning', class: 'text-warning has-tooltip', title: 'Build was retried.') + - if build.stuck? + = icon('warning', class: 'text-warning has-tooltip', title: 'Build is stuck. Check runners.') + - if defined?(retried) && retried + = icon('warning', class: 'text-warning has-tooltip', title: 'Build was retried.') - - 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" + - if defined?(ref) && ref + - if build.ref + = link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref), class: "monospace branch-name" + - else + .light none + = custom_icon("icon_commit") + + - if defined?(commit_sha) && commit_sha + = link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "commit-id monospace" + + .label-container + - 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 + - if defined?(retried) && retried + %span.label.label-warning retried - - if defined?(ref) && ref - %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 @@ -43,25 +56,14 @@ = build.name %td - .label-container - - 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 - - if defined?(retried) && retried - %span.label.label-warning retried - - %td.duration - if build.duration - #{duration_in_words(build.finished_at, build.started_at)} - - %td.timestamp + %p.duration + = custom_icon("icon_timer") + = duration_in_numbers(build.finished_at, build.started_at) - if build.finished_at - %span #{time_ago_with_tooltip(build.finished_at)} + %p.finished-at + = icon("calendar") + %span #{time_ago_with_tooltip(build.finished_at)} - if defined?(coverage) && coverage %td.coverage @@ -79,4 +81,4 @@ = icon('remove', class: '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', class: 'btn btn-build' do - = icon('refresh') + = icon('repeat') diff --git a/app/views/projects/ci/pipelines/_pipeline.html.haml b/app/views/projects/ci/pipelines/_pipeline.html.haml index af8dd5cd02c..0557d384e33 100644 --- a/app/views/projects/ci/pipelines/_pipeline.html.haml +++ b/app/views/projects/ci/pipelines/_pipeline.html.haml @@ -1,17 +1,18 @@ - status = pipeline.status %tr.commit %td.commit-link - = link_to namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: "ci-status ci-#{status}" do - = ci_icon_for_status(status) - %strong ##{pipeline.id} + = link_to namespace_project_pipeline_path(@project.namespace, @project, pipeline.id) do + = ci_status_with_icon(status) + %td - %div.branch-commit + .branch-commit + = link_to namespace_project_pipeline_path(@project.namespace, @project, pipeline.id) do + %span ##{pipeline.id} - if pipeline.ref - = link_to pipeline.ref, namespace_project_commits_path(@project.namespace, @project, pipeline.ref), class: "monospace" - · + = link_to pipeline.ref, namespace_project_commits_path(@project.namespace, @project, pipeline.ref), class: "monospace branch-name" + = custom_icon("icon_commit") = link_to pipeline.short_sha, namespace_project_commit_path(@project.namespace, @project, pipeline.sha), class: "commit-id monospace" - - if pipeline.tag? %span.label.label-primary tag - elsif pipeline.latest? @@ -25,12 +26,13 @@ %p.commit-title - if commit = pipeline.commit + = commit_author_avatar(commit, size: 20) = link_to_gfm truncate(commit.title, length: 60), namespace_project_commit_path(@project.namespace, @project, commit.id), class: "commit-row-message" - else Cant find HEAD commit for this branch - - stages_status = pipeline.statuses.stages_status + - stages_status = pipeline.statuses.latest.stages_status - stages.each do |stage| %td - status = stages_status[stage] @@ -45,27 +47,34 @@ %td - if pipeline.started_at && pipeline.finished_at %p.duration + = custom_icon("icon_timer") = duration_in_numbers(pipeline.finished_at, pipeline.started_at) + - if pipeline.finished_at + %p.finished-at + = icon("calendar") + #{time_ago_with_tooltip(pipeline.finished_at)} - %td + %td.pipeline-actions .controls.hidden-xs.pull-right - artifacts = pipeline.builds.latest.select { |b| b.artifacts? } - if artifacts.present? - .dropdown.inline.build-artifacts - %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} - = icon('download') - %b.caret - %ul.dropdown-menu.dropdown-menu-align-right - - artifacts.each do |build| - %li - = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, build), rel: 'nofollow' do - = icon("download") - %span Download '#{build.name}' artifacts + .inline + .btn-group + %a.dropdown-toggle.btn.btn-default.build-artifacts{type: 'button', 'data-toggle' => 'dropdown'} + = icon("download") + %b.caret + %ul.dropdown-menu.dropdown-menu-align-right + - artifacts.each do |build| + %li + = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, build), rel: 'nofollow' do + = icon("download") + %span Download '#{build.name}' artifacts - if can?(current_user, :update_pipeline, @project) - - if pipeline.retryable? - = link_to retry_namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: 'btn has-tooltip', title: "Retry", method: :post do - = icon("repeat") - - if pipeline.cancelable? - = link_to cancel_namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: 'btn btn-remove has-tooltip', title: "Cancel", method: :post do - = icon("remove") + .cancel-retry-btns.inline + - if pipeline.retryable? + = link_to retry_namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: 'btn has-tooltip', title: "Retry", method: :post do + = icon("repeat") + - if pipeline.cancelable? + = link_to cancel_namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: 'btn btn-remove has-tooltip', title: "Cancel", method: :post do + = icon("remove") diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 0411137b7c6..41fd5459429 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -42,9 +42,7 @@ %th Status %th Build ID %th Name - %th Tags - %th Duration - %th Finished at + %th - if pipeline.project.build_coverage_enabled? %th Coverage %th diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml index dd590a4b8ec..af09b3418ea 100644 --- a/app/views/projects/compare/_form.html.haml +++ b/app/views/projects/compare/_form.html.haml @@ -2,15 +2,17 @@ .clearfix - if params[:to] && params[:from] = link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has-tooltip', title: 'Switch base of comparison'} - .form-group + .form-group.dropdown.compare-form-group.js-compare-from-dropdown .input-group.inline-input-group %span.input-group-addon from - = text_field_tag :from, params[:from], class: "form-control", required: true + = text_field_tag :from, params[:from], class: "form-control js-compare-dropdown", required: true, data: { refs_url: refs_namespace_project_path(@project.namespace, @project), toggle: "dropdown", target: ".js-compare-from-dropdown", selected: params[:from].presence } + = render "ref_dropdown" = "..." - .form-group + .form-group.dropdown.compare-form-group.js-compare-to-dropdown .input-group.inline-input-group %span.input-group-addon to - = text_field_tag :to, params[:to], class: "form-control", required: true + = text_field_tag :to, params[:to], class: "form-control js-compare-dropdown", required: true, data: { refs_url: refs_namespace_project_path(@project.namespace, @project), toggle: "dropdown", target: ".js-compare-to-dropdown", selected: params[:to].presence } + = render "ref_dropdown" = button_tag "Compare", class: "btn btn-create commits-compare-btn" - if @merge_request.present? @@ -19,11 +21,3 @@ = link_to create_mr_path, class: 'prepend-left-10 btn' do = icon("plus") Create Merge Request - -:javascript - var availableTags = #{@project.repository.ref_names.to_json}; - - $("#from, #to").autocomplete({ - source: availableTags, - minLength: 1 - }); diff --git a/app/views/projects/compare/_ref_dropdown.html.haml b/app/views/projects/compare/_ref_dropdown.html.haml new file mode 100644 index 00000000000..c604c6d0135 --- /dev/null +++ b/app/views/projects/compare/_ref_dropdown.html.haml @@ -0,0 +1,4 @@ +.dropdown-menu.dropdown-menu-selectable + = dropdown_title "Select branch/tag" + = dropdown_content + = dropdown_loading 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 index 5bc5c71283e..542827b2f15 100644 --- a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml +++ b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml @@ -50,10 +50,12 @@ %td.duration - if generic_commit_status.duration + = icon("clock-o") #{duration_in_words(generic_commit_status.finished_at, generic_commit_status.started_at)} %td.timestamp - if generic_commit_status.finished_at + = icon("calendar") %span #{time_ago_with_tooltip(generic_commit_status.finished_at)} - if defined?(coverage) && coverage diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml index 312bd86ed04..7612fe3719a 100644 --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -32,7 +32,7 @@ Code, test, and deploy together .blank-state .blank-state-icon - = navbar_icon("issues", size: 50) + = custom_icon("issues", size: 50) %h3.blank-state-title You don't have any issues right now. %p.blank-state-text diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 9b00bdedc27..c72d0140bb9 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -154,4 +154,9 @@ $('.import_gitlab_project').attr('disabled',true); $('.import_gitlab_project').attr('title', 'Project path required.'); } - }) + }); + + $('.import_git').click(function( event ) { + $projectImportUrl = $('#project_import_url') + $projectImportUrl.attr('disabled', !$projectImportUrl.attr('disabled')) + });
\ No newline at end of file diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml index 7c225e2b282..5f466bdbac2 100644 --- a/app/views/projects/pipelines/index.html.haml +++ b/app/views/projects/pipelines/index.html.haml @@ -28,7 +28,7 @@ .nav-controls - if can? current_user, :create_pipeline, @project = link_to new_namespace_project_pipeline_path(@project.namespace, @project), class: 'btn btn-create' do - New pipeline + Run pipeline - unless @repository.gitlab_ci_yml = link_to 'Get started with Pipelines', help_page_path('ci/quick_start/README'), class: 'btn btn-info' @@ -45,13 +45,13 @@ .table-holder %table.table.builds %tbody - %th ID + %th Status %th Commit - stages.each do |stage| %th.stage %span.has-tooltip{ title: "#{stage.titleize}" } = stage.titleize - %th Duration + %th %th = render @pipelines, commit_sha: true, stage: true, allow_retry: true, stages: stages diff --git a/app/views/projects/project_members/_new_project_member.html.haml b/app/views/projects/project_members/_new_project_member.html.haml index ea3d82d858e..978c4dfc5ec 100644 --- a/app/views/projects/project_members/_new_project_member.html.haml +++ b/app/views/projects/project_members/_new_project_member.html.haml @@ -12,7 +12,7 @@ = select_tag :access_level, options_for_select(ProjectMember.access_level_roles, @project_member.access_level), class: "project-access-select select2" .help-block Read more about role permissions - %strong= link_to "here", help_page_path("permissions/permissions"), class: "vlink" + %strong= link_to "here", help_page_path("user/permissions"), class: "vlink" .form-actions = f.submit 'Add users to project', class: "btn btn-create" diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml index 3fab95751e0..883d3e3af1e 100644 --- a/app/views/projects/protected_branches/index.html.haml +++ b/app/views/projects/protected_branches/index.html.haml @@ -8,10 +8,10 @@ %p.prepend-top-20 Protected branches are designed to: %ul - %li prevent pushes from everybody except #{link_to "masters", help_page_path("permissions/permissions"), class: "vlink"} + %li prevent pushes from everybody except #{link_to "masters", help_page_path("user/permissions"), class: "vlink"} %li prevent anyone from force pushing to the branch %li prevent anyone from deleting the branch - %p.append-bottom-0 Read more about #{link_to "project permissions", help_page_path("permissions/permissions"), class: "underlined-link"} + %p.append-bottom-0 Read more about #{link_to "project permissions", help_page_path("user/permissions"), class: "underlined-link"} .col-lg-9 %h5.prepend-top-0 Protect a branch diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml index 6c994ae486b..1646bcf4b8a 100644 --- a/app/views/projects/snippets/index.html.haml +++ b/app/views/projects/snippets/index.html.haml @@ -1,6 +1,6 @@ - page_title "Snippets" -.row-content-block.top-block +.sub-header-block .pull-right - if can?(current_user, :create_project_snippet, @project) = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: "btn btn-new", title: "New Snippet" do diff --git a/app/views/shared/_import_form.html.haml b/app/views/shared/_import_form.html.haml index 627814bcfae..65a3a6bddab 100644 --- a/app/views/shared/_import_form.html.haml +++ b/app/views/shared/_import_form.html.haml @@ -2,7 +2,7 @@ = f.label :import_url, class: 'control-label' do %span Git repository URL .col-sm-10 - = f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git' + = f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git', disabled: true .well.prepend-top-20 %ul diff --git a/app/views/shared/icons/_group.svg b/app/views/shared/icons/_group.svg.erb index 75cae0d16c8..53635016900 100644 --- a/app/views/shared/icons/_group.svg +++ b/app/views/shared/icons/_group.svg.erb @@ -1,9 +1,4 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - <!-- Generator: Sketch 3.7.2 (28276) - http://www.bohemiancoding.com/sketch --> - <title>Group</title> - <desc>Created with Sketch.</desc> - <defs></defs> +<svg width="<%= size %>" height="<%= size %>" viewBox="0 0 16 16"> <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <g id="Group" fill="#303030"> <path d="M15.6667,10.0105 L10.3337,10.0105 C10.1497,10.0105 9.9997,10.1775 9.9997,10.3845 L9.9997,15.6145 C9.9997,15.8215 10.1497,15.9885 10.3337,15.9885 L15.6667,15.9885 C15.8507,15.9885 15.9997,15.8215 15.9997,15.6145 L15.9997,10.3845 C15.9997,10.1775 15.8507,10.0105 15.6667,10.0105 L15.6667,10.0105 L15.6667,10.0105 Z M11.9997,14.0105 L13.9997,14.0105 L13.9997,12.0105 L11.9997,12.0105 L11.9997,14.0105 L11.9997,14.0105 Z" id="Fill-11"></path> @@ -15,4 +10,4 @@ <path d="M11.6667,6.21724894e-15 L4.3337,6.21724894e-15 C4.1497,6.21724894e-15 3.9997,0.167 3.9997,0.374 L3.9997,6.604 C3.9997,6.811 4.1497,6.978 4.3337,6.978 L11.6667,6.978 C11.8507,6.978 11.9997,6.811 11.9997,6.604 L11.9997,0.374 C11.9997,0.167 11.8507,6.21724894e-15 11.6667,6.21724894e-15 L11.6667,6.21724894e-15 L11.6667,6.21724894e-15 Z M5.9997,5 L9.9997,5 L9.9997,2 L5.9997,2 L5.9997,5 L5.9997,5 Z" id="Fill-14"></path> </g> </g> -</svg>
\ No newline at end of file +</svg> diff --git a/app/views/shared/icons/_icon_commit.svg b/app/views/shared/icons/_icon_commit.svg new file mode 100644 index 00000000000..0e96035b7b7 --- /dev/null +++ b/app/views/shared/icons/_icon_commit.svg @@ -0,0 +1,3 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"> + <path fill="#8F8F8F" fill-rule="evenodd" d="M28.7769836,18 C27.8675252,13.9920226 24.2831748,11 20,11 C15.7168252,11 12.1324748,13.9920226 11.2230164,18 L4.0085302,18 C2.90195036,18 2,18.8954305 2,20 C2,21.1122704 2.8992496,22 4.0085302,22 L11.2230164,22 C12.1324748,26.0079774 15.7168252,29 20,29 C24.2831748,29 27.8675252,26.0079774 28.7769836,22 L35.9914698,22 C37.0980496,22 38,21.1045695 38,20 C38,18.8877296 37.1007504,18 35.9914698,18 L28.7769836,18 L28.7769836,18 Z M20,25 C22.7614237,25 25,22.7614237 25,20 C25,17.2385763 22.7614237,15 20,15 C17.2385763,15 15,17.2385763 15,20 C15,22.7614237 17.2385763,25 20,25 L20,25 Z"/> +</svg> diff --git a/app/views/shared/icons/_icon_timer.svg b/app/views/shared/icons/_icon_timer.svg new file mode 100644 index 00000000000..0b1e5804427 --- /dev/null +++ b/app/views/shared/icons/_icon_timer.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><g fill="#8F8F8F" fill-rule="evenodd"><path d="M29.513 10.134A15.922 15.922 0 0 0 23 7.28V6h2.993C26.55 6 27 5.552 27 5V2a1 1 0 0 0-1.007-1H14.007C13.45 1 13 1.448 13 2v3a1 1 0 0 0 1.007 1H17v1.28C9.597 8.686 4 15.19 4 23c0 8.837 7.163 16 16 16s16-7.163 16-16c0-3.461-1.099-6.665-2.967-9.283l1.327-1.58a2.498 2.498 0 0 0-.303-3.53 2.499 2.499 0 0 0-3.528.315l-1.016 1.212zM20 34c6.075 0 11-4.925 11-11s-4.925-11-11-11S9 16.925 9 23s4.925 11 11 11z"/><path d="M19 21h-4.002c-.552 0-.998.452-.998 1.01v1.98c0 .567.447 1.01.998 1.01h7.004c.274 0 .521-.111.701-.291a.979.979 0 0 0 .297-.704v-8.01c0-.54-.452-.995-1.01-.995h-1.98a.997.997 0 0 0-1.01.995V21z"/></g></svg>
\ No newline at end of file diff --git a/app/views/shared/icons/_project.svg b/app/views/shared/icons/_project.svg deleted file mode 100644 index 1e8b43f8c6b..00000000000 --- a/app/views/shared/icons/_project.svg +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - <!-- Generator: Sketch 3.8.3 (29802) - http://www.bohemiancoding.com/sketch --> - <title>Page 1</title> - <desc>Created with Sketch.</desc> - <defs></defs> - <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> - <path d="M6,6 L12,6 L12,5 L6,5 L6,6 Z M6,8 L12,8 L12,7 L6,7 L6,8 Z M6,10 L12,10 L12,9 L6,9 L6,10 Z M6,12 L12,12 L12,11 L6,11 L6,12 Z M4,6 L5,6 L5,5 L4,5 L4,6 Z M4,8 L5,8 L5,7 L4,7 L4,8 Z M4,10 L5,10 L5,9 L4,9 L4,10 Z M4,12 L5,12 L5,11 L4,11 L4,12 Z M13,3 L10,3 L10,4 L6,4 L6,3 L3,3 L3,13 L13,13 L13,3 Z M2,14 L14,14 L14,2 L2,2 L2,14 Z M1,0 C0.448,0 0,0.448 0,1 L0,15 C0,15.552 0.448,16 1,16 L15,16 C15.552,16 16,15.552 16,15 L16,1 C16,0.448 15.552,0 15,0 L1,0 Z" fill="#7F7E7E"></path> - </g> -</svg>
\ No newline at end of file diff --git a/app/views/shared/icons/_project.svg.erb b/app/views/shared/icons/_project.svg.erb new file mode 100644 index 00000000000..2f60bb7245e --- /dev/null +++ b/app/views/shared/icons/_project.svg.erb @@ -0,0 +1,3 @@ +<svg width="<%= size %>" height="<%= size %>" viewBox="0 0 16 16"> + <path d="M6,6 L12,6 L12,5 L6,5 L6,6 Z M6,8 L12,8 L12,7 L6,7 L6,8 Z M6,10 L12,10 L12,9 L6,9 L6,10 Z M6,12 L12,12 L12,11 L6,11 L6,12 Z M4,6 L5,6 L5,5 L4,5 L4,6 Z M4,8 L5,8 L5,7 L4,7 L4,8 Z M4,10 L5,10 L5,9 L4,9 L4,10 Z M4,12 L5,12 L5,11 L4,11 L4,12 Z M13,3 L10,3 L10,4 L6,4 L6,3 L3,3 L3,13 L13,13 L13,3 Z M2,14 L14,14 L14,2 L2,2 L2,14 Z M1,0 C0.448,0 0,0.448 0,1 L0,15 C0,15.552 0.448,16 1,16 L15,16 C15.552,16 16,15.552 16,15 L16,1 C16,0.448 15.552,0 15,0 L1,0 Z" fill="#7F7E7E" fill-rule="evenodd"></path> +</svg> diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index adfab1af53e..e020a7d4d00 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -19,7 +19,7 @@ = form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, format: :json, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f| .block.assignee - .sidebar-collapsed-icon.sidebar-collapsed-user{data: {toggle: "tooltip", placement: "left", container: "body"}, title: (issuable.assignee.to_reference if issuable.assignee)} + .sidebar-collapsed-icon.sidebar-collapsed-user{data: {toggle: "tooltip", placement: "left", container: "body"}, title: (issuable.assignee.name if issuable.assignee)} - if issuable.assignee = link_to_member(@project, issuable.assignee, size: 24) - else diff --git a/app/workers/git_garbage_collect_worker.rb b/app/workers/git_garbage_collect_worker.rb index 2fa3c838f55..a6cefd4d601 100644 --- a/app/workers/git_garbage_collect_worker.rb +++ b/app/workers/git_garbage_collect_worker.rb @@ -8,7 +8,9 @@ class GitGarbageCollectWorker project = Project.find(project_id) gitlab_shell.gc(project.repository_storage_path, project.path_with_namespace) - # Expire the branch cache in case garbage collection caused a ref lookup to fail + # Refresh the branch cache in case garbage collection caused a ref lookup to fail project.repository.after_create_branch + project.repository.branch_names + project.repository.has_visible_content? end end diff --git a/app/workers/project_export_worker.rb b/app/workers/project_export_worker.rb index 39f6037e077..615311e63f5 100644 --- a/app/workers/project_export_worker.rb +++ b/app/workers/project_export_worker.rb @@ -1,7 +1,7 @@ class ProjectExportWorker include Sidekiq::Worker - sidekiq_options queue: :gitlab_shell, retry: true + sidekiq_options queue: :gitlab_shell, retry: 3 def perform(current_user_id, project_id) current_user = User.find(current_user_id) |