diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d5ac8eb17d2312bc5cadc8eee6f581524c257f87..45fcd5ce44bc9734719668c3aa542bfbade21189 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -131,56 +131,56 @@ spinach 7 10: *spinach-knapsack spinach 8 10: *spinach-knapsack spinach 9 10: *spinach-knapsack -# Execute all testing suites against Ruby 2.2 - -.ruby-22: &ruby-22 - image: "ruby:2.2" +# Execute all testing suites against Ruby 2.3 +.ruby-23: &ruby-23 + image: "ruby:2.3" only: - master cache: - key: "ruby22" + key: "ruby-23" paths: - - vendor + - vendor/apt + - vendor/ruby -.rspec-knapsack-ruby22: &rspec-knapsack-ruby22 +.rspec-knapsack-ruby23: &rspec-knapsack-ruby23 <<: *rspec-knapsack - <<: *ruby-22 + <<: *ruby-23 -.spinach-knapsack-ruby22: &spinach-knapsack-ruby22 +.spinach-knapsack-ruby23: &spinach-knapsack-ruby23 <<: *spinach-knapsack - <<: *ruby-22 + <<: *ruby-23 -rspec 0 20 ruby22: *rspec-knapsack-ruby22 -rspec 1 20 ruby22: *rspec-knapsack-ruby22 -rspec 2 20 ruby22: *rspec-knapsack-ruby22 -rspec 3 20 ruby22: *rspec-knapsack-ruby22 -rspec 4 20 ruby22: *rspec-knapsack-ruby22 -rspec 5 20 ruby22: *rspec-knapsack-ruby22 -rspec 6 20 ruby22: *rspec-knapsack-ruby22 -rspec 7 20 ruby22: *rspec-knapsack-ruby22 -rspec 8 20 ruby22: *rspec-knapsack-ruby22 -rspec 9 20 ruby22: *rspec-knapsack-ruby22 -rspec 10 20 ruby22: *rspec-knapsack-ruby22 -rspec 11 20 ruby22: *rspec-knapsack-ruby22 -rspec 12 20 ruby22: *rspec-knapsack-ruby22 -rspec 13 20 ruby22: *rspec-knapsack-ruby22 -rspec 14 20 ruby22: *rspec-knapsack-ruby22 -rspec 15 20 ruby22: *rspec-knapsack-ruby22 -rspec 16 20 ruby22: *rspec-knapsack-ruby22 -rspec 17 20 ruby22: *rspec-knapsack-ruby22 -rspec 18 20 ruby22: *rspec-knapsack-ruby22 -rspec 19 20 ruby22: *rspec-knapsack-ruby22 - -spinach 0 10 ruby22: *spinach-knapsack-ruby22 -spinach 1 10 ruby22: *spinach-knapsack-ruby22 -spinach 2 10 ruby22: *spinach-knapsack-ruby22 -spinach 3 10 ruby22: *spinach-knapsack-ruby22 -spinach 4 10 ruby22: *spinach-knapsack-ruby22 -spinach 5 10 ruby22: *spinach-knapsack-ruby22 -spinach 6 10 ruby22: *spinach-knapsack-ruby22 -spinach 7 10 ruby22: *spinach-knapsack-ruby22 -spinach 8 10 ruby22: *spinach-knapsack-ruby22 -spinach 9 10 ruby22: *spinach-knapsack-ruby22 +rspec 0 20 ruby23: *rspec-knapsack-ruby23 +rspec 1 20 ruby23: *rspec-knapsack-ruby23 +rspec 2 20 ruby23: *rspec-knapsack-ruby23 +rspec 3 20 ruby23: *rspec-knapsack-ruby23 +rspec 4 20 ruby23: *rspec-knapsack-ruby23 +rspec 5 20 ruby23: *rspec-knapsack-ruby23 +rspec 6 20 ruby23: *rspec-knapsack-ruby23 +rspec 7 20 ruby23: *rspec-knapsack-ruby23 +rspec 8 20 ruby23: *rspec-knapsack-ruby23 +rspec 9 20 ruby23: *rspec-knapsack-ruby23 +rspec 10 20 ruby23: *rspec-knapsack-ruby23 +rspec 11 20 ruby23: *rspec-knapsack-ruby23 +rspec 12 20 ruby23: *rspec-knapsack-ruby23 +rspec 13 20 ruby23: *rspec-knapsack-ruby23 +rspec 14 20 ruby23: *rspec-knapsack-ruby23 +rspec 15 20 ruby23: *rspec-knapsack-ruby23 +rspec 16 20 ruby23: *rspec-knapsack-ruby23 +rspec 17 20 ruby23: *rspec-knapsack-ruby23 +rspec 18 20 ruby23: *rspec-knapsack-ruby23 +rspec 19 20 ruby23: *rspec-knapsack-ruby23 + +spinach 0 10 ruby23: *spinach-knapsack-ruby23 +spinach 1 10 ruby23: *spinach-knapsack-ruby23 +spinach 2 10 ruby23: *spinach-knapsack-ruby23 +spinach 3 10 ruby23: *spinach-knapsack-ruby23 +spinach 4 10 ruby23: *spinach-knapsack-ruby23 +spinach 5 10 ruby23: *spinach-knapsack-ruby23 +spinach 6 10 ruby23: *spinach-knapsack-ruby23 +spinach 7 10 ruby23: *spinach-knapsack-ruby23 +spinach 8 10 ruby23: *spinach-knapsack-ruby23 +spinach 9 10 ruby23: *spinach-knapsack-ruby23 # Other generic tests diff --git a/CHANGELOG b/CHANGELOG index 367f845e147dd5eb69b4df2a4824ee5cfcf8214b..189b66e1b62483c0a733c7a9993f7d2e54b40be3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,64 @@ Please view this file on the master branch, on stable branches it's out of date. +v 8.10.0 (unreleased) + - Replace Haml with Hamlit to make view rendering faster. !3666 + - Wrap code blocks on Activies and Todos page. !4783 (winniehell) + - Add Sidekiq queue duration to transaction metrics. + - Fix MR-auto-close text added to description. !4836 + - Fix pagination when sorting by columns with lots of ties (like priority) + - Exclude email check from the standard health check + - Implement Subresource Integrity for CSS and JavaScript assets. This prevents malicious assets from loading in the case of a CDN compromise. + - Fix changing issue state columns in milestone view + - Fix user creation with stronger minimum password requirements !4054 (nathan-pmt) + - Add API endpoint for a group issues !4520 (mahcsig) + +v 8.9.1 + - Refactor labels documentation. !3347 + - Eager load award emoji on notes. !4628 + - Fix some CI wording in documentation. !4660 + - Document `GIT_STRATEGY` and `GIT_DEPTH`. !4720 + - Add documentation for the export & import features. !4732 + - Add some docs for Docker Registry configuration. !4738 + - Ensure we don't send the "access request declined" email to access requesters on project deletion. !4744 + - Display group/project access requesters separately in the admin area. !4798 + - Add documentation and examples for configuring cloud storage for registry images. !4812 + - Clarifies documentation about artifact expiry. !4831 + - Fix the Network graph links. !4832 + - Fix MR-auto-close text added to description. !4836 + - Add documentation for award emoji now that comments can be awarded with emojis. !4839 + - Fix typo in export failure email. !4847 + - Fix header vertical centering. !4170 + - Fix subsequent SAML sign ins. !4718 + - Set button label when picking an option from status dropdown. !4771 + - Prevent invalid URLs from raising exceptions in WikiLink Filter. !4775 + - Handle external issues in IssueReferenceFilter. !4789 + - Support for rendering/redacting multiple documents. !4828 + - Update Todos documentation and screenshots to include new functionality. !4840 + - Hide nav arrows by default. !4843 + - Added bottom padding to label color suggestion link. !4845 + - Use jQuery objects in ref dropdown. !4850 + - Fix GitLab project import issues related to notes and builds. !4855 + - Restrict header logo to 36px so it doesn't overflow. !4861 + - Fix unwanted label unassignment. !4863 + - Fix mobile Safari bug where horizontal nav arrows would flicker on scroll. !4869 + - Restore old behavior around diff notes to outdated discussions. !4870 + - Fix merge requests project settings help link anchor. !4873 + - Fix 404 when accessing pipelines as guest user on public projects. !4881 + - Remove width restriction for logo on sign-in page. !4888 + - Bump gitlab_git to 10.2.3 to fix false truncated warnings with ISO-8559 files. !4884 + - Apply selected value as label. !4886 + - Fix temp file being deleted after the request while importing a GitLab project. !4894 + - Fix pagination when sorting by columns with lots of ties (like priority) + - Implement Subresource Integrity for CSS and JavaScript assets. This prevents malicious assets from loading in the case of a CDN compromise. + - Fix user creation with stronger minimum password requirements !4054 (nathan-pmt) + - Add API endpoint for a group issues !4520 (mahcsig) + - Fix a wrong MR status when merge_when_build_succeeds & project.only_allow_merge_if_build_succeeds are true. !4912 + - Add SMTP as default delivery method to match gitlab-org/omnibus-gitlab!826. !4915 + +v 8.9.0 + - Fix builds API response not including commit data + - Fix error when CI job variables key specified but not defined + - Fix pipeline status when there are no builds in pipeline v 8.10.0 (unreleased) v 8.9.0 @@ -7,15 +66,22 @@ v 8.9.0 - Add more information into RSS feed for issues (Alexander Matyushentsev) - Bulk assign/unassign labels to issues. - Ability to prioritize labels !4009 / !3205 (Thijs Wouters) + - Show Star and Fork buttons on mobile. + - Performance improvements on RelativeLinkFilter - Fix endless redirections when accessing user OAuth applications when they are disabled - Allow enabling wiki page events from Webhook management UI - Bump rouge to 1.11.0 - Fix issue with arrow keys not working in search autocomplete dropdown - Fix an issue where note polling stopped working if a window was in the background during a refresh. + - Pre-processing Markdown now only happens when needed - Make EmailsOnPushWorker use Sidekiq mailers queue + - Redesign all Devise emails. !4297 + - Don't show 'Leave Project' to group members - Fix wiki page events' webhook to point to the wiki repository + - Add a border around images to differentiate them from the background. - Don't show tags for revert and cherry-pick operations + - Show image ID on registry page - Fix issue todo not remove when leave project !4150 (Long Nguyen) - Allow customisable text on the 'nearly there' page after a user signs up - Bump recaptcha gem to 3.0.0 to remove deprecated stoken support @@ -24,15 +90,18 @@ v 8.9.0 - Added descriptions to notification settings dropdown - Improve note validation to prevent errors when creating invalid note via API - Reduce number of fog gem dependencies + - Add number of merge requests for a given milestone to the milestones view. - Implement a fair usage of shared runners - Remove project notification settings associated with deleted projects - Fix 404 page when viewing TODOs that contain milestones or labels in different projects - Add a metric for the number of new Redis connections created by a transaction - Fix Error 500 when viewing a blob with binary characters after the 1024-byte mark - Redesign navigation for project pages + - Fix images in sign-up confirmation email - Added shortcut 'y' for copying a files content hash URL #14470 - Fix groups API to list only user's accessible projects - Fix horizontal scrollbar for long commit message. + - GitLab Performance Monitoring now tracks the total method execution time and call count per method - Add Environments and Deployments - Redesign account and email confirmation emails - Don't fail builds for projects that are deleted @@ -40,11 +109,16 @@ v 8.9.0 - `git clone https://host/namespace/project` now works, in addition to using the `.git` suffix - Bump nokogiri to 1.6.8 - Use gitlab-shell v3.0.0 + - Fixed alignment of download dropdown in merge requests - Upgrade to jQuery 2 + - Adds selected branch name to the dropdown toggle + - Add API endpoint for Sidekiq Metrics !4653 + - Refactoring Award Emoji with API support for Issues and MergeRequests - Use Knapsack to evenly distribute tests across multiple nodes - Add `sha` parameter to MR merge API, to ensure only reviewed changes are merged - Don't allow MRs to be merged when commits were added since the last review / page load - Add DB index on users.state + - Limit email on push diff size to 30 files / 150 KB - Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database - Changed the Slack build message to use the singular duration if necessary (Aran Koning) - Fix race condition on merge when build succeeds @@ -52,21 +126,31 @@ v 8.9.0 - Add option to project to only allow merge requests to be merged if the build succeeds (Rui Santos) - Added navigation shortcuts to the project pipelines, milestones, builds and forks page. !4393 - Fix issues filter when ordering by milestone + - Disable SAML account unlink feature - Added artifacts:when to .gitlab-ci.yml - this requires GitLab Runner 1.3 - Bamboo Service: Fix missing credentials & URL handling when base URL contains a path (Benjamin Schmid) - TeamCity Service: Fix URL handling when base URL contains a path - Todos will display target state if issuable target is 'Closed' or 'Merged' + - Validate only and except regexp - Fix bug when sorting issues by milestone due date and filtering by two or more labels + - POST to API /projects/:id/runners/:runner_id would give 409 if the runner was already enabled for this project - Add support for using Yubikeys (U2F) for two-factor authentication - Link to blank group icon doesn't throw a 404 anymore - Remove 'main language' feature - Toggle whitespace button now available for compare branches diffs #17881 - Pipelines can be canceled only when there are running builds + - Allow authentication using personal access tokens - Use downcased path to container repository as this is expected path by Docker + - Allow to use CI token to fetch LFS objects + - Custom notification settings - Projects pending deletion will render a 404 page - Measure queue duration between gitlab-workhorse and Rails + - Added Gfm autocomplete for labels + - Added edit note 'up' shortcut documentation to the help panel and docs screenshot #18114 - Make Omniauth providers specs to not modify global configuration + - Remove unused JiraIssue class and replace references with ExternalIssue. !4659 (Ilan Shamir) - Make authentication service for Container Registry to be compatible with < Docker 1.11 + - Make it possible to lock a runner from being enabled for other projects - Add Application Setting to configure Container Registry token expire delay (default 5min) - Cache assigned issue and merge request counts in sidebar nav - Use Knapsack only in CI environment @@ -84,7 +168,9 @@ v 8.9.0 - An indicator is now displayed at the top of the comment field for confidential issues. - Show categorised search queries in the search autocomplete - RepositoryCheck::SingleRepositoryWorker public and private methods are now instrumented + - Dropdown for `.gitlab-ci.yml` templates - Improve issuables APIs performance when accessing notes !4471 + - Add sorting dropdown to tags page !4423 - External links now open in a new tab - Prevent default actions of disabled buttons and links - Markdown editor now correctly resets the input value on edit cancellation !4175 @@ -92,6 +178,7 @@ v 8.9.0 - Improved UX of date pickers on issue & milestone forms - Cache on the database if a project has an active external issue tracker. - Put project Labels and Milestones pages links under Issues and Merge Requests tabs as subnav + - GitLab project import and export functionality - All classes in the Banzai::ReferenceParser namespace are now instrumented - Remove deprecated issues_tracker and issues_tracker_id from project model - Allow users to create confidential issues in private projects @@ -109,6 +196,18 @@ v 8.9.0 - Include user relationships when retrieving award_emoji - Various associations are now eager loaded when parsing issue references to reduce the number of queries executed - Set inverse_of for Project/Service association to reduce the number of queries + - Update tanuki logo highlight/loading colors + - Remove explicit Gitlab::Metrics.action assignments, are already automatic. + - Use Git cached counters for branches and tags on project page + - Cache participable participants in an instance variable. + - Filter parameters for request_uri value on instrumented transactions. + - Remove duplicated keys add UNIQUE index to keys fingerprint column + - ExtractsPath get ref_names from repository cache, if not there access git. + - Cache user todo counts from TodoService + - Ensure Todos counters doesn't count Todos for projects pending delete + - Add left/right arrows horizontal navigation + - Add tooltip to pin/unpin navbar + - Add new sub nav style to Wiki and Graphs sub navigation v 8.8.5 - Import GitHub repositories respecting the API rate limit !4166 @@ -120,6 +219,8 @@ v 8.8.5 - Prevent unauthorized access for projects build traces - Forbid scripting for wiki files - Only show notes through JSON on confidential issues that the user has access to + - Banzai::Filter::UploadLinkFilter use XPath instead CSS expressions + - Banzai::Filter::ExternalLinkFilter use XPath instead CSS expressions v 8.8.4 - Fix LDAP-based login for users with 2FA enabled. !4493 diff --git a/Gemfile b/Gemfile index 588c9b789e872b7ff1f30d457f6bb1ebce07e1eb..3aa5f8a6ee4a75a61fef56c27a4a396baeb40a03 100644 --- a/Gemfile +++ b/Gemfile @@ -52,11 +52,11 @@ gem 'u2f', '~> 0.2.1' gem 'validates_hostname', '~> 1.0.0' # Browser detection -gem "browser", '~> 2.0.3' +gem "browser", '~> 2.2' # Extracting information from a git repository # Provide access to Gitlab::Git library -gem "gitlab_git", '~> 10.0' +gem "gitlab_git", '~> 10.2' # LDAP Auth # GitLab fork with several improvements to original library. For full list of changes @@ -81,7 +81,7 @@ gem 'rack-cors', '~> 0.4.0', require: 'rack/cors' gem "kaminari", "~> 0.17.0" # HAML -gem "haml-rails", '~> 0.9.0' +gem 'hamlit', '~> 2.5' # Files attachments gem "carrierwave", '~> 0.10.0' @@ -231,7 +231,7 @@ gem 'jquery-turbolinks', '~> 2.1.0' gem 'addressable', '~> 2.3.8' gem 'bootstrap-sass', '~> 3.3.0' -gem 'font-awesome-rails', '~> 4.2' +gem 'font-awesome-rails', '~> 4.6.1' gem 'gitlab_emoji', '~> 0.3.0' gem 'gon', '~> 6.0.1' gem 'jquery-atwho-rails', '~> 1.3.2' @@ -245,7 +245,7 @@ gem 'base32', '~> 0.3.0' gem "gitlab-license", "~> 0.0.4" # Sentry integration -gem 'sentry-raven', '~> 0.15' +gem 'sentry-raven', '~> 1.1.0' gem 'premailer-rails', '~> 1.9.0' @@ -341,7 +341,7 @@ gem "newrelic_rpm", '~> 3.14' gem 'octokit', '~> 4.3.0' -gem "mail_room", "~> 0.7" +gem "mail_room", "~> 0.8" gem 'email_reply_parser', '~> 0.5.8' diff --git a/Gemfile.lock b/Gemfile.lock index 51663637d6b27abf3fee50c8a2b3997e7378eb20..fa1d9850cbd313826a778eb74127a86356c64342 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -98,7 +98,7 @@ GEM autoprefixer-rails (>= 5.2.1) sass (>= 3.3.4) brakeman (3.3.2) - browser (2.0.3) + browser (2.2.0) builder (3.2.2) bullet (5.0.0) activesupport (>= 3.0.0) @@ -259,7 +259,7 @@ GEM fog-xml (0.1.2) fog-core nokogiri (~> 1.5, >= 1.5.11) - font-awesome-rails (4.5.0.1) + font-awesome-rails (4.6.1.0) railties (>= 3.2, < 5.1) foreman (0.78.0) thor (~> 0.19.1) @@ -299,7 +299,7 @@ GEM gitlab-license (0.0.4) gitlab_emoji (0.3.1) gemojione (~> 2.2, >= 2.2.1) - gitlab_git (10.1.3) + gitlab_git (10.2.3) activesupport (~> 4.0) charlock_holmes (~> 0.7.3) github-linguist (~> 4.7.0) @@ -344,14 +344,10 @@ GEM multi_json (>= 1.3.2) gssapi (1.2.0) ffi (>= 1.0.1) - haml (4.0.7) + hamlit (2.5.0) + temple (~> 0.7.6) + thor tilt - haml-rails (0.9.0) - actionpack (>= 4.0.1) - activesupport (>= 4.0.1) - haml (>= 4.0.6, < 5.0) - html2haml (>= 1.0.1) - railties (>= 4.0.1) hashie (3.4.3) health_check (1.5.1) rails (>= 2.3.0) @@ -361,11 +357,6 @@ GEM html-pipeline (1.11.0) activesupport (>= 2) nokogiri (~> 1.4) - html2haml (2.0.0) - erubis (~> 2.7.0) - haml (~> 4.0.0) - nokogiri (~> 1.6.0) - ruby_parser (~> 3.5) htmlentities (4.3.4) http_parser.rb (0.5.3) httparty (0.13.7) @@ -422,7 +413,7 @@ GEM systemu (~> 2.6.2) mail (2.6.4) mime-types (>= 1.16, < 4) - mail_room (0.7.0) + mail_room (0.8.0) method_source (0.8.2) mime-types (2.99.2) mimemagic (0.3.0) @@ -689,7 +680,7 @@ GEM activesupport (>= 3.1, < 4.3) select2-rails (3.5.9.3) thor (~> 0.14) - sentry-raven (0.15.6) + sentry-raven (1.1.0) faraday (>= 0.7.6) settingslogic (2.0.9) sexp_processor (4.7.0) @@ -757,6 +748,7 @@ GEM railties (>= 3.2.5, < 6) teaspoon-jasmine (2.2.0) teaspoon (>= 1.0.0) + temple (0.7.7) term-ansicolor (1.3.2) tins (~> 1.0) test_after_commit (0.4.2) @@ -860,7 +852,7 @@ DEPENDENCIES binding_of_caller (~> 0.7.2) bootstrap-sass (~> 3.3.0) brakeman (~> 3.3.0) - browser (~> 2.0.3) + browser (~> 2.2) bullet bundler-audit byebug @@ -895,7 +887,7 @@ DEPENDENCIES fog-google (~> 0.3) fog-local (~> 0.3) fog-openstack (~> 0.1) - font-awesome-rails (~> 4.2) + font-awesome-rails (~> 4.6.1) foreman fuubar (~> 2.0.0) gemnasium-gitlab-service (~> 0.2) @@ -905,7 +897,7 @@ DEPENDENCIES gitlab-flowdock-git-hook (~> 1.0.1) gitlab-license (~> 0.0.4) gitlab_emoji (~> 0.3.0) - gitlab_git (~> 10.0) + gitlab_git (~> 10.2) gitlab_meta (= 7.0) gitlab_omniauth-ldap (~> 1.2.1) gollum-lib (~> 4.1.0) @@ -914,7 +906,7 @@ DEPENDENCIES grape (~> 0.13.0) grape-entity (~> 0.4.2) gssapi - haml-rails (~> 0.9.0) + hamlit (~> 2.5) health_check (~> 1.5.1) hipchat (~> 1.5.0) html-pipeline (~> 1.11.0) @@ -931,7 +923,7 @@ DEPENDENCIES license_finder licensee (~> 8.0.0) loofah (~> 2.0.3) - mail_room (~> 0.7) + mail_room (~> 0.8) method_source (~> 0.8) minitest (~> 5.7.0) mousetrap-rails (~> 1.4.6) @@ -993,7 +985,7 @@ DEPENDENCIES sdoc (~> 0.3.20) seed-fu (~> 2.3.5) select2-rails (~> 3.5.9) - sentry-raven (~> 0.15) + sentry-raven (~> 1.1.0) settingslogic (~> 2.0.9) sham_rack shoulda-matchers (~> 2.8.0) diff --git a/VERSION b/VERSION index c74ee0f5a070032d5f725c3af160dfd8b5e8b360..26c6eda830228cb66600cafc33bc0f6860c17e25 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.9.0-ee-pre +8.10.0-ee-pre diff --git a/app/assets/javascripts/LabelManager.js.coffee b/app/assets/javascripts/LabelManager.js.coffee index b06bcf0fcbf33c007ff8f0135a3e2404a3abb61c..6d8faba40d73464a7d7931e06a2f349809245ce6 100644 --- a/app/assets/javascripts/LabelManager.js.coffee +++ b/app/assets/javascripts/LabelManager.js.coffee @@ -27,6 +27,11 @@ class @LabelManager $btn = $(e.currentTarget) $label = $("##{$btn.data('domId')}") action = if $btn.parents('.js-prioritized-labels').length then 'remove' else 'add' + + # Make sure tooltip will hide + $tooltip = $ "##{$btn.find('.has-tooltip:visible').attr('aria-describedby')}" + $tooltip.tooltip 'destroy' + _this.toggleLabelPriority($label, action) toggleLabelPriority: ($label, action, persistState = true) -> diff --git a/app/assets/javascripts/api.js.coffee b/app/assets/javascripts/api.js.coffee index 84a87fadd0bf66ca11b11dcb9746f958ef5430d1..9aa9f454e72a6c3eb7a83b99414a252920df3ac2 100644 --- a/app/assets/javascripts/api.js.coffee +++ b/app/assets/javascripts/api.js.coffee @@ -8,6 +8,7 @@ licensePath: "/api/:version/licenses/:key" gitignorePath: "/api/:version/gitignores/:key" ldapGroupsPath: "/api/:version/ldap/:provider/groups.json" + gitlabCiYmlPath: "/api/:version/gitlab_ci_ymls/:key" group: (group_id, callback) -> url = Api.buildUrl(Api.groupPath) @@ -111,6 +112,12 @@ $.get url, (gitignore) -> callback(gitignore) + gitlabCiYml: (key, callback) -> + url = Api.buildUrl(Api.gitlabCiYmlPath).replace(':key', key) + + $.get url, (file) -> + callback(file) + buildUrl: (url) -> url = gon.relative_url_root + url if gon.relative_url_root? return url.replace(':version', gon.api_version) diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index 58fd30dd919ad7d0052cf04eb0186e16764013b3..a8947ec1916b72ee2e59f15946d5a5a61f9e3799 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -51,7 +51,7 @@ #= require_directory ./ci #= require_directory ./commit #= require_directory ./extensions -#= require_directory ./lib +#= require_directory ./lib/utils #= require_directory ./u2f #= require_directory . #= require fuzzaldrin-plus @@ -124,6 +124,11 @@ window.onload = -> setTimeout shiftWindow, 100 $ -> + + $document = $(document) + $window = $(window) + $body = $('body') + gl.utils.preventDisabledButtons() bootstrapBreakpoint = bp.getBreakpointSize() @@ -155,7 +160,7 @@ $ -> ), 1 # Initialize tooltips - $('body').tooltip( + $body.tooltip( selector: '.has-tooltip, [data-toggle="tooltip"]' placement: (_, el) -> $el = $(el) @@ -174,7 +179,7 @@ $ -> flash.show() # Disable form buttons while a form is submitting - $('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) -> + $body.on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) -> buttons = $('[type="submit"]', @) switch e.type @@ -187,7 +192,7 @@ $ -> $('.account-box').hover -> $(@).toggleClass('hover') # Commit show suppressed diff - $(document).on 'click', '.diff-content .js-show-suppressed-diff', -> + $document.on 'click', '.diff-content .js-show-suppressed-diff', -> $container = $(@).parent() $container.next('table').show() $container.remove() @@ -200,13 +205,13 @@ $ -> $('.navbar-toggle i').toggleClass("fa-angle-right fa-angle-left") # Show/hide comments on diff - $("body").on "click", ".js-toggle-diff-comments", (e) -> + $body.on "click", ".js-toggle-diff-comments", (e) -> $(@).toggleClass('active') $(@).closest(".diff-file").find(".notes_holder").toggle() e.preventDefault() - $(document).off "click", '.js-confirm-danger' - $(document).on "click", '.js-confirm-danger', (e) -> + $document.off "click", '.js-confirm-danger' + $document.on "click", '.js-confirm-danger', (e) -> e.preventDefault() btn = $(e.target) text = btn.data("confirm-danger-message") @@ -215,7 +220,7 @@ $ -> new ConfirmDangerModal(form, text, warningMessage: warningMessage) - $(document).on 'click', 'button', -> + $document.on 'click', 'button', -> $(this).blur() $('input[type="search"]').each -> @@ -223,7 +228,7 @@ $ -> $this.attr 'value', $this.val() return - $(document) + $document .off 'keyup', 'input[type="search"]' .on 'keyup', 'input[type="search"]' , (e) -> $this = $(this) @@ -231,7 +236,7 @@ $ -> $sidebarGutterToggle = $('.js-sidebar-toggle') - $(document) + $document .off 'breakpoint:change' .on 'breakpoint:change', (e, breakpoint) -> if breakpoint is 'sm' or breakpoint is 'xs' @@ -243,14 +248,14 @@ $ -> oldBootstrapBreakpoint = bootstrapBreakpoint bootstrapBreakpoint = bp.getBreakpointSize() if bootstrapBreakpoint != oldBootstrapBreakpoint - $(document).trigger('breakpoint:change', [bootstrapBreakpoint]) + $document.trigger('breakpoint:change', [bootstrapBreakpoint]) checkInitialSidebarSize = -> bootstrapBreakpoint = bp.getBreakpointSize() if bootstrapBreakpoint is "xs" or "sm" - $(document).trigger('breakpoint:change', [bootstrapBreakpoint]) + $document.trigger('breakpoint:change', [bootstrapBreakpoint]) - $(window) + $window .off "resize.app" .on "resize.app", (e) -> fitSidebarForSize() @@ -260,29 +265,45 @@ $ -> new Aside() # Sidenav pinning - if $(window).width() < 1440 and $.cookie('pin_nav') is 'true' - $.cookie('pin_nav', 'false') + if $window.width() < 1440 and $.cookie('pin_nav') is 'true' + $.cookie('pin_nav', 'false', { path: '/' }) $('.page-with-sidebar') .toggleClass('page-sidebar-collapsed page-sidebar-expanded') .removeClass('page-sidebar-pinned') $('.navbar-fixed-top').removeClass('header-pinned-nav') - $(document) + $document .off 'click', '.js-nav-pin' .on 'click', '.js-nav-pin', (e) -> e.preventDefault() + $pinBtn = $(e.currentTarget) + $page = $ '.page-with-sidebar' + $topNav = $ '.navbar-fixed-top' + $tooltip = $ "##{$pinBtn.attr('aria-describedby')}" + doPinNav = not $page.is('.page-sidebar-pinned') + tooltipText = 'Pin navigation' + $(this).toggleClass 'is-active' - if $.cookie('pin_nav') is 'true' - $.cookie 'pin_nav', 'false' - $('.page-with-sidebar') - .removeClass('page-sidebar-pinned') - .toggleClass('page-sidebar-collapsed page-sidebar-expanded') - $('.navbar-fixed-top') - .removeClass('header-pinned-nav') - .toggleClass('header-collapsed header-expanded') + if doPinNav + $page.addClass('page-sidebar-pinned') + $topNav.addClass('header-pinned-nav') else - $.cookie 'pin_nav', 'true' - $('.page-with-sidebar').addClass('page-sidebar-pinned') - $('.navbar-fixed-top').addClass('header-pinned-nav') + $tooltip.remove() # Remove it immediately when collapsing the sidebar + $page.removeClass('page-sidebar-pinned') + .toggleClass('page-sidebar-collapsed page-sidebar-expanded') + $topNav.removeClass('header-pinned-nav') + .toggleClass('header-collapsed header-expanded') + + # Save settings + $.cookie 'pin_nav', doPinNav, { path: '/' } + + if $.cookie('pin_nav') is 'true' or doPinNav + tooltipText = 'Unpin navigation' + + # Update tooltip text immediately + $tooltip.find('.tooltip-inner').text(tooltipText) + + # Persist tooltip title + $pinBtn.attr('title', tooltipText).tooltip('fixTitle') diff --git a/app/assets/javascripts/blob/blob_ci_yaml.js.coffee b/app/assets/javascripts/blob/blob_ci_yaml.js.coffee new file mode 100644 index 0000000000000000000000000000000000000000..d9a03d055290a2e4c6cd35809b52149db802c07d --- /dev/null +++ b/app/assets/javascripts/blob/blob_ci_yaml.js.coffee @@ -0,0 +1,23 @@ +#= require blob/template_selector + +class @BlobCiYamlSelector extends TemplateSelector + requestFile: (query) -> + Api.gitlabCiYml query.name, @requestFileSuccess.bind(@) + +class @BlobCiYamlSelectors + constructor: (opts) -> + { + @$dropdowns = $('.js-gitlab-ci-yml-selector') + @editor + } = opts + + @$dropdowns.each (i, dropdown) => + $dropdown = $(dropdown) + + new BlobCiYamlSelector( + pattern: /(.gitlab-ci.yml)/, + data: $dropdown.data('data'), + wrapper: $dropdown.closest('.js-gitlab-ci-yml-selector-wrap'), + dropdown: $dropdown, + editor: @editor + ) diff --git a/app/assets/javascripts/blob/blob_gitignore_selector.js.coffee b/app/assets/javascripts/blob/blob_gitignore_selector.js.coffee index cc8a497d081537c3edee103f89480f9463248682..8d0e3f363d1738b53c96340a3a0f50e972175f23 100644 --- a/app/assets/javascripts/blob/blob_gitignore_selector.js.coffee +++ b/app/assets/javascripts/blob/blob_gitignore_selector.js.coffee @@ -1,58 +1,5 @@ -class @BlobGitignoreSelector - constructor: (opts) -> - { - @dropdown - @editor - @$wrapper = @dropdown.closest('.gitignore-selector') - @$filenameInput = $('#file_name') - @data = @dropdown.data('filenames') - } = opts +#= require blob/template_selector - @dropdown.glDropdown( - data: @data, - filterable: true, - selectable: true, - search: - fields: ['name'] - clicked: @onClick - text: (gitignore) -> - gitignore.name - ) - - @toggleGitignoreSelector() - @bindEvents() - - bindEvents: -> - @$filenameInput - .on 'keyup blur', (e) => - @toggleGitignoreSelector() - - toggleGitignoreSelector: -> - filename = @$filenameInput.val() or $('.editor-file-name').text().trim() - @$wrapper.toggleClass 'hidden', filename isnt '.gitignore' - - onClick: (item, el, e) => - e.preventDefault() - @requestIgnoreFile(item.name) - - requestIgnoreFile: (name) -> - Api.gitignoreText name, @requestIgnoreFileSuccess.bind(@) - - requestIgnoreFileSuccess: (gitignore) -> - @editor.setValue(gitignore.content, 1) - @editor.focus() - -class @BlobGitignoreSelectors - constructor: (opts) -> - { - @$dropdowns = $('.js-gitignore-selector') - @editor - } = opts - - @$dropdowns.each (i, dropdown) => - $dropdown = $(dropdown) - - new BlobGitignoreSelector( - dropdown: $dropdown, - editor: @editor - ) +class @BlobGitignoreSelector extends TemplateSelector + requestFile: (query) -> + Api.gitignoreText query.name, @requestFileSuccess.bind(@) diff --git a/app/assets/javascripts/blob/blob_gitignore_selectors.js.coffee b/app/assets/javascripts/blob/blob_gitignore_selectors.js.coffee new file mode 100644 index 0000000000000000000000000000000000000000..a719ba251222f26000ee9e1cba9f117832d5cd45 --- /dev/null +++ b/app/assets/javascripts/blob/blob_gitignore_selectors.js.coffee @@ -0,0 +1,17 @@ +class @BlobGitignoreSelectors + constructor: (opts) -> + { + @$dropdowns = $('.js-gitignore-selector') + @editor + } = opts + + @$dropdowns.each (i, dropdown) => + $dropdown = $(dropdown) + + new BlobGitignoreSelector( + pattern: /(.gitignore)/, + data: $dropdown.data('data'), + wrapper: $dropdown.closest('.js-gitignore-selector-wrap'), + dropdown: $dropdown, + editor: @editor + ) diff --git a/app/assets/javascripts/blob/blob_license_selector.js.coffee b/app/assets/javascripts/blob/blob_license_selector.js.coffee index e17eaa75dc11274c455593bd77e0887de39165d8..a3cc8dd844c0af229c1944c5cfa6e851e75534a4 100644 --- a/app/assets/javascripts/blob/blob_license_selector.js.coffee +++ b/app/assets/javascripts/blob/blob_license_selector.js.coffee @@ -1,30 +1,9 @@ -class @BlobLicenseSelector - licenseRegex: /^(.+\/)?(licen[sc]e|copying)($|\.)/i +#= require blob/template_selector - constructor: (editor) -> - @$licenseSelector = $('.js-license-selector') - $fileNameInput = $('#file_name') +class @BlobLicenseSelector extends TemplateSelector + requestFile: (query) -> + data = + project: @dropdown.data('project') + fullname: @dropdown.data('fullname') - initialFileNameValue = if $fileNameInput.length - $fileNameInput.val() - else if $('.editor-file-name').length - $('.editor-file-name').text().trim() - - @toggleLicenseSelector(initialFileNameValue) - - if $fileNameInput - $fileNameInput.on 'keyup blur', (e) => - @toggleLicenseSelector($(e.target).val()) - - $('select.license-select').on 'change', (e) -> - data = - project: $(this).data('project') - fullname: $(this).data('fullname') - Api.licenseText $(this).val(), data, (license) -> - editor.setValue(license.content, -1) - - toggleLicenseSelector: (fileName) => - if @licenseRegex.test(fileName) - @$licenseSelector.show() - else - @$licenseSelector.hide() + Api.licenseText query.id, data, @requestFileSuccess.bind(@) diff --git a/app/assets/javascripts/blob/blob_license_selectors.js.coffee b/app/assets/javascripts/blob/blob_license_selectors.js.coffee new file mode 100644 index 0000000000000000000000000000000000000000..6843873310881d3a4eeadee6f49ef2704c76ad11 --- /dev/null +++ b/app/assets/javascripts/blob/blob_license_selectors.js.coffee @@ -0,0 +1,17 @@ +class @BlobLicenseSelectors + constructor: (opts) -> + { + @$dropdowns = $('.js-license-selector') + @editor + } = opts + + @$dropdowns.each (i, dropdown) => + $dropdown = $(dropdown) + + new BlobLicenseSelector( + pattern: /^(.+\/)?(licen[sc]e|copying)($|\.)/i, + data: $dropdown.data('data'), + wrapper: $dropdown.closest('.js-license-selector-wrap'), + dropdown: $dropdown, + editor: @editor + ) diff --git a/app/assets/javascripts/blob/edit_blob.js.coffee b/app/assets/javascripts/blob/edit_blob.js.coffee index 79141e768b8464ecc31ce6d6de8b2b13ba647628..19e584519d7470f84ba811502bd564c1b0148085 100644 --- a/app/assets/javascripts/blob/edit_blob.js.coffee +++ b/app/assets/javascripts/blob/edit_blob.js.coffee @@ -12,8 +12,10 @@ class @EditBlob $("#file-content").val(@editor.getValue()) @initModePanesAndLinks() - new BlobLicenseSelector(@editor) - new BlobGitignoreSelectors(editor: @editor) + + new BlobLicenseSelectors { @editor } + new BlobGitignoreSelectors { @editor } + new BlobCiYamlSelectors { @editor } initModePanesAndLinks: -> @$editModePanes = $(".js-edit-mode-pane") diff --git a/app/assets/javascripts/blob/template_selector.js.coffee b/app/assets/javascripts/blob/template_selector.js.coffee new file mode 100644 index 0000000000000000000000000000000000000000..40c9169beac4e4393f70af5bf2382af456ff306a --- /dev/null +++ b/app/assets/javascripts/blob/template_selector.js.coffee @@ -0,0 +1,60 @@ +class @TemplateSelector + constructor: (opts = {}) -> + { + @dropdown, + @data, + @pattern, + @wrapper, + @editor, + @fileEndpoint, + @$input = $('#file_name') + } = opts + + @buildDropdown() + @bindEvents() + @onFilenameUpdate() + + buildDropdown: -> + @dropdown.glDropdown( + data: @data, + filterable: true, + selectable: true, + toggleLabel: @toggleLabel, + search: + fields: ['name'] + clicked: @onClick + text: (item) -> + item.name + ) + + bindEvents: -> + @$input.on('keyup blur', (e) => + @onFilenameUpdate() + ) + + toggleLabel: (item) -> + item.name + + onFilenameUpdate: -> + return unless @$input.length + + filenameMatches = @pattern.test(@$input.val().trim()) + + if not filenameMatches + @wrapper.addClass('hidden') + return + + @wrapper.removeClass('hidden') + + onClick: (item, el, e) => + e.preventDefault() + @requestFile(item) + + requestFile: (item) -> + # To be implemented on the extending class + # e.g. + # Api.gitignoreText item.name, @requestFileSuccess.bind(@) + + requestFileSuccess: (file) -> + @editor.setValue(file.content, 1) + @editor.focus() diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index a032dd791755333d7215780327181777a0d909bf..e1163a90c627c796950e40431119c1b904d9699d 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -78,6 +78,7 @@ class Dispatcher when 'projects:show' shortcut_handler = new ShortcutsNavigation() + new NotificationsForm() new TreeView() if $('#tree-slider').length when 'groups:activity' new Activities() @@ -133,6 +134,8 @@ class Dispatcher shortcut_handler = new ShortcutsDashboardNavigation() when 'profiles' new Profile() + new NotificationsForm() + new NotificationsDropdown() when 'projects' new Project() new ProjectAvatar() @@ -140,8 +143,12 @@ class Dispatcher when 'edit' shortcut_handler = new ShortcutsNavigation() new ProjectNew() - when 'new', 'show' + when 'new' new ProjectNew() + when 'show' + new ProjectNew() + new ProjectShow() + new NotificationsDropdown() when 'wikis' new Wikis() shortcut_handler = new ShortcutsNavigation() diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index 76c3083232becf0880cf9e649c7f79c692d68922..190bb38504c97c66af697c6962ca17085d717b55 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -15,6 +15,9 @@ GitLab.GfmAutoComplete = Members: template: '
  • ${username} ${title}
  • ' + Labels: + template: '
  • ${title}
  • ' + # Issues and MergeRequests Issues: template: '
  • ${id} ${title}
  • ' @@ -176,6 +179,25 @@ GitLab.GfmAutoComplete = title: sanitize(m.title) search: "#{m.iid} #{m.title}" + @input.atwho + at: '~' + alias: 'labels' + searchKey: 'search' + displayTpl: @Labels.template + insertTpl: '${atwho-at}${title}' + callbacks: + beforeSave: (merges) -> + sanitizeLabelTitle = (title)-> + if /\w+\s+\w+/g.test(title) + "\"#{sanitize(title)}\"" + else + sanitize(title) + + $.map merges, (m) -> + title: sanitizeLabelTitle(m.title) + color: m.color + search: "#{m.title}" + destroyAtWho: -> @input.atwho('destroy') @@ -195,6 +217,8 @@ GitLab.GfmAutoComplete = @input.atwho 'load', 'mergerequests', data.mergerequests # load emojis @input.atwho 'load', ':', data.emojis + # load labels + @input.atwho 'load', '~', data.labels # This trigger at.js again # otherwise we would be stuck with loading until the user types diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index b49bd4565a7c75b11dbead10c80abb1d08815c7e..703128fecb306214c00d406c7baaef06c9974517 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -58,7 +58,7 @@ class GitLabDropdownFilter filter: (search_text) -> data = @options.data() - if data? + if data? and not @options.filterByText results = data if search_text isnt '' @@ -102,10 +102,11 @@ class GitLabDropdownFilter $el = $(@) matches = fuzzaldrinPlus.match($el.text().trim(), search_text) - if matches.length - $el.show() - else - $el.hide() + unless $el.is('.dropdown-header') + if matches.length + $el.show() + else + $el.hide() else elements.show() @@ -191,6 +192,7 @@ class GitLabDropdown if @options.filterable @filter = new GitLabDropdownFilter @filterInput, filterInputBlur: @filterInputBlur + filterByText: @options.filterByText remote: @options.filterRemote query: @options.data keys: searchFields @@ -278,7 +280,7 @@ class GitLabDropdown html = @renderData(data) # Render the full menu - full_html = @renderMenu(html.join("")) + full_html = @renderMenu(html) @appendMenu(full_html) @@ -302,6 +304,9 @@ class GitLabDropdown if @options.setIndeterminateIds @options.setIndeterminateIds.call(@) + if @options.setActiveIds + @options.setActiveIds.call(@) + # Makes indeterminate items effective if @fullData and @dropdown.find('.dropdown-menu-toggle').hasClass('js-filter-bulk-update') @parseData @fullData @@ -346,7 +351,8 @@ class GitLabDropdown if @options.renderMenu menu_html = @options.renderMenu(html) else - menu_html = "" + menu_html = $('