Merge remote-tracking branch 'origin/master' into eReGeBe/gitlab-ce-feature/milestone-md
Signed-off-by: Rémy Coutable <remy@rymai.me>
This commit is contained in:
commit
f29d8b64e4
13
.rubocop.yml
13
.rubocop.yml
|
@ -531,7 +531,7 @@ Style/SpaceAroundKeyword:
|
|||
|
||||
# Use a single space around operators.
|
||||
Style/SpaceAroundOperators:
|
||||
Enabled: false
|
||||
Enabled: true
|
||||
|
||||
# Checks that the left block brace has or doesn't have space before it.
|
||||
Style/SpaceBeforeBlockBraces:
|
||||
|
@ -770,7 +770,7 @@ Lint/DefEndAlignment:
|
|||
|
||||
# Check for deprecated class method calls.
|
||||
Lint/DeprecatedClassMethods:
|
||||
Enabled: false
|
||||
Enabled: true
|
||||
|
||||
# Check for duplicate method definitions.
|
||||
Lint/DuplicateMethods:
|
||||
|
@ -937,10 +937,9 @@ Lint/Void:
|
|||
|
||||
##################### Performance ############################
|
||||
|
||||
# TODO: Enable Casecmp Cop.
|
||||
# Use `casecmp` rather than `downcase ==`.
|
||||
Performance/Casecmp:
|
||||
Enabled: false
|
||||
Enabled: true
|
||||
|
||||
# TODO: Enable DoubleStartEndWith Cop.
|
||||
# Use `str.{start,end}_with?(x, ..., y, ...)` instead of
|
||||
|
@ -953,10 +952,9 @@ Performance/DoubleStartEndWith:
|
|||
Performance/EndWith:
|
||||
Enabled: false
|
||||
|
||||
# TODO: Enable LstripRstrip Cop.
|
||||
# Use `strip` instead of `lstrip.rstrip`.
|
||||
Performance/LstripRstrip:
|
||||
Enabled: false
|
||||
Enabled: true
|
||||
|
||||
# TODO: Enable RangeInclude Cop.
|
||||
# Use `Range#cover?` instead of `Range#include?`.
|
||||
|
@ -991,11 +989,12 @@ Performance/RedundantSortBy:
|
|||
# string.
|
||||
Performance/StartWith:
|
||||
Enabled: false
|
||||
|
||||
# Use `tr` instead of `gsub` when you are replacing the same number of
|
||||
# characters. Use `delete` instead of `gsub` when you are deleting
|
||||
# characters.
|
||||
Performance/StringReplacement:
|
||||
Enabled: false
|
||||
Enabled: true
|
||||
|
||||
# TODO: Enable TimesMap Cop.
|
||||
# Checks for `.times.map` calls.
|
||||
|
|
|
@ -65,7 +65,7 @@ linters:
|
|||
|
||||
# Reports when you have an empty rule set.
|
||||
EmptyRule:
|
||||
enabled: false
|
||||
enabled: true
|
||||
|
||||
# Reports when you have an @extend directive.
|
||||
ExtendDirective:
|
||||
|
@ -244,11 +244,11 @@ linters:
|
|||
|
||||
# URLs should be valid and not contain protocols or domain names.
|
||||
UrlFormat:
|
||||
enabled: false
|
||||
enabled: true
|
||||
|
||||
# URLs should always be enclosed within quotes.
|
||||
UrlQuotes:
|
||||
enabled: false
|
||||
enabled: true
|
||||
|
||||
# Properties, like color and font, are easier to read and maintain
|
||||
# when defined using variables rather than literals.
|
||||
|
|
172
CHANGELOG
172
CHANGELOG
|
@ -4,6 +4,107 @@ v 8.8.0 (unreleased)
|
|||
- Implement GFM references for milestones (Alejandro Rodríguez)
|
||||
|
||||
v 8.7.1 (unreleased)
|
||||
- Snippets tab under user profile. !4001 (Long Nguyen)
|
||||
- Fix error when using link to uploads in global snippets
|
||||
- Assign labels and milestone to target project when moving issue. !3934 (Long Nguyen)
|
||||
- Use a case-insensitive comparison in sanitizing URI schemes
|
||||
- Toggle sign-up confirmation emails in application settings
|
||||
- Project#open_branches has been cleaned up and no longer loads entire records into memory.
|
||||
- Escape HTML in commit titles in system note messages
|
||||
- Improve multiple branch push performance by memoizing permission checking
|
||||
- Log to application.log when an admin starts and stops impersonating a user
|
||||
- Updated gitlab_git to 10.1.0
|
||||
- GitAccess#protected_tag? no longer loads all tags just to check if a single one exists
|
||||
- Reduce delay in destroying a project from 1-minute to immediately
|
||||
- Make build status canceled if any of the jobs was canceled and none failed
|
||||
- Upgrade Sidekiq to 4.1.2
|
||||
- Added /health_check endpoint for checking service status
|
||||
- Make 'upcoming' filter for milestones work better across projects
|
||||
- Sanitize repo paths in new project error message
|
||||
- Bump mail_room to 0.7.0 to fix stuck IDLE connections
|
||||
- Remove future dates from contribution calendar graph.
|
||||
- Support e-mail notifications for comments on project snippets
|
||||
- Fix API leak of notes of unauthorized issues, snippets and merge requests
|
||||
- Use ActionDispatch Remote IP for Akismet checking
|
||||
- Fix error when visiting commit builds page before build was updated
|
||||
- Add 'l' shortcut to open Label dropdown on issuables and 'i' to create new issue on a project
|
||||
- Update SVG sanitizer to conform to SVG 1.1
|
||||
- Speed up push emails with multiple recipients by only generating the email once
|
||||
- Updated search UI
|
||||
- Added authentication service for Container Registry
|
||||
- Display informative message when new milestone is created
|
||||
- Sanitize milestones and labels titles
|
||||
- Support multi-line tag messages. !3833 (Calin Seciu)
|
||||
- Force users to reset their password after an admin changes it
|
||||
- Allow "NEWS" and "CHANGES" as alternative names for CHANGELOG. !3768 (Connor Shea)
|
||||
- Added button to toggle whitespaces changes on diff view
|
||||
- Backport GitHub Enterprise import support from EE
|
||||
- Create tags using Rugged for performance reasons. !3745
|
||||
- API: Expose Issue#user_notes_count. !3126 (Anton Popov)
|
||||
- Don't show forks button when user can't view forks
|
||||
- Fix atom feed links and rendering
|
||||
- Files over 5MB can only be viewed in their raw form, files over 1MB without highlighting !3718
|
||||
- Add support for supressing text diffs using .gitattributes on the default branch (Matt Oakes)
|
||||
- Add eager load paths to help prevent dependency load issues in Sidekiq workers. !3724
|
||||
- Added multiple colors for labels in dropdowns when dups happen.
|
||||
- Always group commits by server timezone, not commit timestamp
|
||||
- Improve description for the Two-factor Authentication sign-in screen. (Connor Shea)
|
||||
- API support for the 'since' and 'until' operators on commit requests (Paco Guzman)
|
||||
- Fix Gravatar hint in user profile when Gravatar is disabled. !3988 (Artem Sidorenko)
|
||||
- Expire repository exists? and has_visible_content? caches after a push if necessary
|
||||
- Fix unintentional filtering bug in Issue/MR sorted by milestone due (Takuya Noguchi)
|
||||
- Fix adding a todo for private group members (Ahmad Sherif)
|
||||
- Bump ace-rails-ap gem version from 2.0.1 to 4.0.2 which upgrades Ace Editor from 1.1.2 to 1.2.3
|
||||
- Total method execution timings are no longer tracked
|
||||
- Allow Admins to remove the Login with buttons for OAuth services and still be able to import !4034. (Andrei Gliga)
|
||||
- Add API endpoints for un/subscribing from/to a label. !4051 (Ahmad Sherif)
|
||||
- Hide left sidebar on phone screens to give more space for content
|
||||
- Redesign navigation for profile and group pages
|
||||
- Add counter metrics for rails cache
|
||||
- Import pull requests from GitHub where the source or target branches were removed
|
||||
- All Grape API helpers are now instrumented
|
||||
- Improve Issue formatting for the Slack Service (Jeroen van Baarsen)
|
||||
|
||||
v 8.7.6
|
||||
- Fix links on wiki pages for relative url setups. !4131 (Artem Sidorenko)
|
||||
- Fix import from GitLab.com to a private instance failure. !4181
|
||||
- Fix external imports not finding the import data. !4106
|
||||
|
||||
v 8.7.5
|
||||
- Fix relative links in wiki pages. !4050
|
||||
- Fix always showing build notification message when switching between merge requests !4086
|
||||
- Fix an issue when filtering merge requests with more than one label. !3886
|
||||
- Fix short note for the default scope on build page (Takuya Noguchi)
|
||||
|
||||
v 8.7.4
|
||||
- Links for Redmine issue references are generated correctly again !4048 (Benedikt Huss)
|
||||
- Fix setting trusted proxies !3970
|
||||
- Fix BitBucket importer bug when throwing exceptions !3941
|
||||
- Use sign out path only if not empty !3989
|
||||
- Running rake gitlab:db:drop_tables now drops tables with cascade !4020
|
||||
- Running rake gitlab:db:drop_tables uses "IF EXISTS" as a precaution !4100
|
||||
- Use a case-insensitive comparison in sanitizing URI schemes
|
||||
|
||||
v 8.7.3
|
||||
- Emails, Gitlab::Email::Message, Gitlab::Diff, and Premailer::Adapter::Nokogiri are now instrumented
|
||||
- Merge request widget displays TeamCity build state and code coverage correctly again.
|
||||
- Fix the line code when importing PR review comments from GitHub. !4010
|
||||
- Wikis are now initialized on legacy projects when checking repositories
|
||||
|
||||
v 8.7.2
|
||||
- The "New Branch" button is now loaded asynchronously
|
||||
- Fix error 500 when trying to create a wiki page
|
||||
- Updated spacing between notification label and button
|
||||
- Label titles in filters are now escaped properly
|
||||
|
||||
v 8.7.1
|
||||
- Throttle the update of `project.last_activity_at` to 1 minute. !3848
|
||||
- Fix .gitlab-ci.yml parsing issue when hidde job is a template without script definition. !3849
|
||||
- Fix license detection to detect all license files, not only known licenses. !3878
|
||||
- Use the `can?` helper instead of `current_user.can?`. !3882
|
||||
- Prevent users from deleting Webhooks via API they do not own
|
||||
- Fix Error 500 due to stale cache when projects are renamed or transferred
|
||||
- Update width of search box to fix Safari bug. !3900 (Jedidiah)
|
||||
- Use the `can?` helper instead of `current_user.can?`
|
||||
|
||||
v 8.7.0
|
||||
|
@ -116,13 +217,25 @@ v 8.7.0
|
|||
- Import GitHub labels
|
||||
- Add option to filter by "Owned projects" on dashboard page
|
||||
- Import GitHub milestones
|
||||
- Fix emoji catgories in the emoji picker
|
||||
- Execute system web hooks on push to the project
|
||||
- Allow enable/disable push events for system hooks
|
||||
- Fix GitHub project's link in the import page when provider has a custom URL
|
||||
- Add RAW build trace output and button on build page
|
||||
- Add incremental build trace update into CI API
|
||||
|
||||
v 8.6.8
|
||||
- Prevent privilege escalation via "impersonate" feature
|
||||
- Prevent privilege escalation via notes API
|
||||
- Prevent privilege escalation via project webhook API
|
||||
- Prevent XSS via Git branch and tag names
|
||||
- Prevent XSS via custom issue tracker URL
|
||||
- Prevent XSS via `window.opener`
|
||||
- Prevent XSS via label drop-down
|
||||
- Prevent information disclosure via milestone API
|
||||
- Prevent information disclosure via snippet API
|
||||
- Prevent information disclosure via project labels
|
||||
- Prevent information disclosure via new merge request page
|
||||
|
||||
v 8.6.7
|
||||
- Fix persistent XSS vulnerability in `commit_person_link` helper
|
||||
- Fix persistent XSS vulnerability in Label and Milestone dropdowns
|
||||
|
@ -264,6 +377,17 @@ v 8.6.0
|
|||
- Trigger a todo for mentions on commits page
|
||||
- Let project owners and admins soft delete issues and merge requests
|
||||
|
||||
v 8.5.12
|
||||
- Prevent privilege escalation via "impersonate" feature
|
||||
- Prevent privilege escalation via notes API
|
||||
- Prevent privilege escalation via project webhook API
|
||||
- Prevent XSS via Git branch and tag names
|
||||
- Prevent XSS via custom issue tracker URL
|
||||
- Prevent XSS via `window.opener`
|
||||
- Prevent information disclosure via snippet API
|
||||
- Prevent information disclosure via project labels
|
||||
- Prevent information disclosure via new merge request page
|
||||
|
||||
v 8.5.11
|
||||
- Fix persistent XSS vulnerability in `commit_person_link` helper
|
||||
|
||||
|
@ -414,6 +538,17 @@ v 8.5.0
|
|||
- Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul)
|
||||
- Add Todos
|
||||
|
||||
v 8.4.10
|
||||
- Prevent privilege escalation via "impersonate" feature
|
||||
- Prevent privilege escalation via notes API
|
||||
- Prevent privilege escalation via project webhook API
|
||||
- Prevent XSS via Git branch and tag names
|
||||
- Prevent XSS via custom issue tracker URL
|
||||
- Prevent XSS via `window.opener`
|
||||
- Prevent information disclosure via snippet API
|
||||
- Prevent information disclosure via project labels
|
||||
- Prevent information disclosure via new merge request page
|
||||
|
||||
v 8.4.9
|
||||
- Fix persistent XSS vulnerability in `commit_person_link` helper
|
||||
|
||||
|
@ -539,6 +674,15 @@ v 8.4.0
|
|||
- Add IP check against DNSBLs at account sign-up
|
||||
- Added cache:key to .gitlab-ci.yml allowing to fine tune the caching
|
||||
|
||||
v 8.3.9
|
||||
- Prevent privilege escalation via "impersonate" feature
|
||||
- Prevent privilege escalation via notes API
|
||||
- Prevent privilege escalation via project webhook API
|
||||
- Prevent XSS via custom issue tracker URL
|
||||
- Prevent XSS via `window.opener`
|
||||
- Prevent information disclosure via project labels
|
||||
- Prevent information disclosure via new merge request page
|
||||
|
||||
v 8.3.8
|
||||
- Fix persistent XSS vulnerability in `commit_person_link` helper
|
||||
|
||||
|
@ -648,6 +792,17 @@ v 8.3.0
|
|||
- Expose Git's version in the admin area
|
||||
- Show "New Merge Request" buttons on canonical repos when you have a fork (Josh Frye)
|
||||
|
||||
v 8.2.5
|
||||
- Prevent privilege escalation via "impersonate" feature
|
||||
- Prevent privilege escalation via notes API
|
||||
- Prevent privilege escalation via project webhook API
|
||||
- Prevent XSS via `window.opener`
|
||||
- Prevent information disclosure via project labels
|
||||
- Prevent information disclosure via new merge request page
|
||||
|
||||
v 8.2.4
|
||||
- Bump Git version requirement to 2.7.4
|
||||
|
||||
v 8.2.3
|
||||
- Fix application settings cache not expiring after changes (Stan Hu)
|
||||
- Fix Error 500s when creating global milestones with Unicode characters (Stan Hu)
|
||||
|
@ -743,7 +898,7 @@ v 8.1.3
|
|||
- Use issue editor as cross reference comment author when issue is edited with a new mention
|
||||
- Add Facebook authentication
|
||||
|
||||
v 8.1.2
|
||||
v 8.1.1
|
||||
- Fix cloning Wiki repositories via HTTP (Stan Hu)
|
||||
- Add migration to remove satellites directory
|
||||
- Fix specific runners visibility
|
||||
|
@ -1368,20 +1523,17 @@ v 7.10.0
|
|||
- Fix stuck Merge Request merging events from old installations (Ben Bodenmiller)
|
||||
- Fix merge request comments on files with multiple commits
|
||||
- Fix Resource Owner Password Authentication Flow
|
||||
|
||||
v 7.9.4
|
||||
- Security: Fix project import URL regex to prevent arbitary local repos from being imported
|
||||
- Fixed issue where only 25 commits would load in file listings
|
||||
- Fix LDAP identities after config update
|
||||
|
||||
v 7.9.3
|
||||
- Contains no changes
|
||||
- Add icons to Add dropdown items.
|
||||
- Allow admin to create public deploy keys that are accessible to any project.
|
||||
- Warn when gitlab-shell version doesn't match requirement.
|
||||
- Skip email confirmation when set by admin or via LDAP.
|
||||
- Only allow users to reference groups, projects, issues, MRs, commits they have access to.
|
||||
|
||||
v 7.9.4
|
||||
- Security: Fix project import URL regex to prevent arbitary local repos from being imported
|
||||
- Fixed issue where only 25 commits would load in file listings
|
||||
- Fix LDAP identities after config update
|
||||
|
||||
v 7.9.3
|
||||
- Contains no changes
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ source edition, and GitLab Enterprise Edition (EE) which is our commercial
|
|||
edition. Throughout this guide you will see references to CE and EE for
|
||||
abbreviation.
|
||||
|
||||
If you have read this guide and want to know how the GitLab [core team][core-team]
|
||||
If you have read this guide and want to know how the GitLab [core team]
|
||||
operates please see [the GitLab contributing process](PROCESS.md).
|
||||
|
||||
## Contributor license agreement
|
||||
|
@ -135,12 +135,23 @@ For feature proposals for EE, open an issue on the
|
|||
|
||||
In order to help track the feature proposals, we have created a
|
||||
[`feature proposal`][fpl] label. For the time being, users that are not members
|
||||
of the project cannot add labels. You can instead ask one of the [core team][core-team]
|
||||
members to add the label `feature proposal` to the issue.
|
||||
of the project cannot add labels. You can instead ask one of the [core team]
|
||||
members to add the label `feature proposal` to the issue or add the following
|
||||
code snippet right after your description in a new line: `~"feature proposal"`.
|
||||
|
||||
Please keep feature proposals as small and simple as possible, complex ones
|
||||
might be edited to make them small and simple.
|
||||
|
||||
You are encouraged to use the template below for feature proposals.
|
||||
|
||||
```
|
||||
## Description including problem, use cases, benefits, and/or goals
|
||||
|
||||
## Proposal
|
||||
|
||||
## Links / references
|
||||
```
|
||||
|
||||
For changes in the interface, it can be helpful to create a mockup first.
|
||||
If you want to create something yourself, consider opening an issue first to
|
||||
discuss whether it is interesting to include this in GitLab.
|
||||
|
@ -344,12 +355,11 @@ is it will be merged (quickly). After that you can send more MRs to enhance it.
|
|||
For examples of feedback on merge requests please look at already
|
||||
[closed merge requests][closed-merge-requests]. If you would like quick feedback
|
||||
on your merge request feel free to mention one of the Merge Marshalls in the
|
||||
[core team][core-team] or one of the
|
||||
[Merge request coaches](https://about.gitlab.com/team/).
|
||||
[core team] or one of the [Merge request coaches](https://about.gitlab.com/team/).
|
||||
Please ensure that your merge request meets the contribution acceptance criteria.
|
||||
|
||||
When having your code reviewed and when reviewing merge requests please take the
|
||||
[Thoughtbot code review guide] into account.
|
||||
[code review guidelines](doc/development/code_review.md) into account.
|
||||
|
||||
### Merge request description format
|
||||
|
||||
|
@ -497,7 +507,7 @@ reported by emailing `contact@gitlab.com`.
|
|||
This Code of Conduct is adapted from the [Contributor Covenant][contributor-covenant], version 1.1.0,
|
||||
available at [http://contributor-covenant.org/version/1/1/0/](http://contributor-covenant.org/version/1/1/0/).
|
||||
|
||||
[core-team]: https://about.gitlab.com/core-team/
|
||||
[core team]: https://about.gitlab.com/core-team/
|
||||
[getting-help]: https://about.gitlab.com/getting-help/
|
||||
[codetriage]: http://www.codetriage.com/gitlabhq/gitlabhq
|
||||
[up-for-grabs]: https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name=up-for-grabs
|
||||
|
@ -523,4 +533,3 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor
|
|||
[gitlab-design]: https://gitlab.com/gitlab-org/gitlab-design
|
||||
[free Antetype viewer (Mac OSX only)]: https://itunes.apple.com/us/app/antetype-viewer/id824152298?mt=12
|
||||
[`gitlab1.atype` file]: https://gitlab.com/gitlab-org/gitlab-design/tree/master/gitlab1.atype/
|
||||
[Thoughtbot code review guide]: https://github.com/thoughtbot/guides/tree/master/code-review
|
||||
|
|
22
Gemfile
22
Gemfile
|
@ -19,8 +19,8 @@ gem "pg", '~> 0.18.2', group: :postgres
|
|||
|
||||
# Authentication libraries
|
||||
gem 'devise', '~> 3.5.4'
|
||||
gem 'doorkeeper', '~> 3.1'
|
||||
gem 'devise-async', '~> 0.9.0'
|
||||
gem 'doorkeeper', '~> 2.2.0'
|
||||
gem 'omniauth', '~> 1.3.1'
|
||||
gem 'omniauth-auth0', '~> 1.4.1'
|
||||
gem 'omniauth-azure-oauth2', '~> 0.0.6'
|
||||
|
@ -36,6 +36,7 @@ gem 'omniauth-shibboleth', '~> 1.2.0'
|
|||
gem 'omniauth-twitter', '~> 1.2.0'
|
||||
gem 'omniauth_crowd', '~> 2.2.0'
|
||||
gem 'rack-oauth2', '~> 1.2.1'
|
||||
gem 'jwt'
|
||||
|
||||
# Spam and anti-bot protection
|
||||
gem 'recaptcha', require: 'recaptcha/rails'
|
||||
|
@ -178,7 +179,7 @@ gem 'ruby-fogbugz', '~> 0.2.1'
|
|||
gem 'd3_rails', '~> 3.5.0'
|
||||
|
||||
#cal-heatmap
|
||||
gem 'cal-heatmap-rails', '~> 3.5.0'
|
||||
gem 'cal-heatmap-rails', '~> 3.6.0'
|
||||
|
||||
# underscore-rails
|
||||
gem "underscore-rails", "~> 1.8.0"
|
||||
|
@ -197,7 +198,7 @@ gem 'licensee', '~> 8.0.0'
|
|||
gem "rack-attack", '~> 4.3.1'
|
||||
|
||||
# Ace editor
|
||||
gem 'ace-rails-ap', '~> 2.0.1'
|
||||
gem 'ace-rails-ap', '~> 4.0.2'
|
||||
|
||||
# Keyboard shortcuts
|
||||
gem 'mousetrap-rails', '~> 1.4.6'
|
||||
|
@ -217,14 +218,14 @@ gem 'font-awesome-rails', '~> 4.2'
|
|||
gem 'gitlab_emoji', '~> 0.3.0'
|
||||
gem 'gon', '~> 6.0.1'
|
||||
gem 'jquery-atwho-rails', '~> 1.3.2'
|
||||
gem 'jquery-rails', '~> 4.0.0'
|
||||
gem 'jquery-scrollto-rails', '~> 1.4.3'
|
||||
gem 'jquery-rails', '~> 4.1.0'
|
||||
gem 'jquery-ui-rails', '~> 5.0.0'
|
||||
gem 'raphael-rails', '~> 2.1.2'
|
||||
gem 'request_store', '~> 1.3.0'
|
||||
gem 'select2-rails', '~> 3.5.9'
|
||||
gem 'virtus', '~> 1.0.1'
|
||||
gem 'net-ssh', '~> 3.0.1'
|
||||
gem 'base32', '~> 0.3.0'
|
||||
|
||||
# Sentry integration
|
||||
gem 'sentry-raven', '~> 0.15'
|
||||
|
@ -242,8 +243,7 @@ group :development do
|
|||
gem "foreman"
|
||||
gem 'brakeman', '~> 3.2.0', require: false
|
||||
|
||||
gem "annotate", "~> 2.7.0"
|
||||
gem "letter_opener", '~> 1.1.2'
|
||||
gem 'letter_opener_web', '~> 1.3.0'
|
||||
gem 'quiet_assets', '~> 1.0.2'
|
||||
gem 'rerun', '~> 0.11.0'
|
||||
gem 'bullet', require: false
|
||||
|
@ -270,7 +270,7 @@ group :development, :test do
|
|||
|
||||
gem 'database_cleaner', '~> 1.4.0'
|
||||
gem 'factory_girl_rails', '~> 4.6.0'
|
||||
gem 'rspec-rails', '~> 3.3.0'
|
||||
gem 'rspec-rails', '~> 3.4.0'
|
||||
gem 'rspec-retry'
|
||||
gem 'spinach-rails', '~> 0.2.1'
|
||||
gem 'spinach-rerun-reporter', '~> 0.0.2'
|
||||
|
@ -320,12 +320,11 @@ gem "newrelic_rpm", '~> 3.14'
|
|||
|
||||
gem 'octokit', '~> 4.3.0'
|
||||
|
||||
gem "mail_room", "~> 0.6.1"
|
||||
gem "mail_room", "~> 0.7"
|
||||
|
||||
gem 'email_reply_parser', '~> 0.5.8'
|
||||
|
||||
## CI
|
||||
gem 'activerecord-deprecated_finders', '~> 1.0.3'
|
||||
gem 'activerecord-session_store', '~> 0.1.0'
|
||||
gem "nested_form", '~> 0.3.2'
|
||||
|
||||
|
@ -334,3 +333,6 @@ gem 'oauth2', '~> 1.0.0'
|
|||
|
||||
# Soft deletion
|
||||
gem "paranoia", "~> 2.0"
|
||||
|
||||
# Health check
|
||||
gem 'health_check', '~> 1.5.1'
|
||||
|
|
97
Gemfile.lock
97
Gemfile.lock
|
@ -3,7 +3,7 @@ GEM
|
|||
specs:
|
||||
CFPropertyList (2.3.2)
|
||||
RedCloth (4.2.9)
|
||||
ace-rails-ap (2.0.1)
|
||||
ace-rails-ap (4.0.2)
|
||||
actionmailer (4.2.6)
|
||||
actionpack (= 4.2.6)
|
||||
actionview (= 4.2.6)
|
||||
|
@ -33,7 +33,6 @@ GEM
|
|||
activemodel (= 4.2.6)
|
||||
activesupport (= 4.2.6)
|
||||
arel (~> 6.0)
|
||||
activerecord-deprecated_finders (1.0.4)
|
||||
activerecord-session_store (0.1.2)
|
||||
actionpack (>= 4.0.0, < 5)
|
||||
activerecord (>= 4.0.0, < 5)
|
||||
|
@ -51,9 +50,6 @@ GEM
|
|||
activerecord (>= 3.0)
|
||||
akismet (2.0.0)
|
||||
allocations (1.0.4)
|
||||
annotate (2.7.0)
|
||||
activerecord (>= 3.2, < 6.0)
|
||||
rake (~> 10.4)
|
||||
arel (6.0.3)
|
||||
asana (0.4.0)
|
||||
faraday (~> 0.9)
|
||||
|
@ -74,6 +70,7 @@ GEM
|
|||
ice_nine (~> 0.11.0)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
babosa (1.0.2)
|
||||
base32 (0.3.2)
|
||||
bcrypt (3.1.10)
|
||||
benchmark-ips (2.3.0)
|
||||
better_errors (1.0.1)
|
||||
|
@ -103,7 +100,7 @@ GEM
|
|||
bundler (~> 1.2)
|
||||
thor (~> 0.18)
|
||||
byebug (8.2.1)
|
||||
cal-heatmap-rails (3.5.1)
|
||||
cal-heatmap-rails (3.6.0)
|
||||
capybara (2.6.2)
|
||||
addressable
|
||||
mime-types (>= 1.16)
|
||||
|
@ -134,7 +131,7 @@ GEM
|
|||
execjs
|
||||
coffee-script-source (1.10.0)
|
||||
colorize (0.7.7)
|
||||
concurrent-ruby (1.0.1)
|
||||
concurrent-ruby (1.0.2)
|
||||
connection_pool (2.2.0)
|
||||
coveralls (0.8.13)
|
||||
json (~> 1.8)
|
||||
|
@ -175,7 +172,7 @@ GEM
|
|||
diff-lcs (1.2.5)
|
||||
diffy (3.0.7)
|
||||
docile (1.1.5)
|
||||
doorkeeper (2.2.2)
|
||||
doorkeeper (3.1.0)
|
||||
railties (>= 3.2)
|
||||
dropzonejs-rails (0.7.2)
|
||||
rails (> 3.1)
|
||||
|
@ -186,7 +183,7 @@ GEM
|
|||
encryptor (1.3.0)
|
||||
equalizer (0.0.11)
|
||||
erubis (2.7.0)
|
||||
escape_utils (1.1.0)
|
||||
escape_utils (1.1.1)
|
||||
eventmachine (1.0.8)
|
||||
excon (0.45.4)
|
||||
execjs (2.6.0)
|
||||
|
@ -336,7 +333,7 @@ GEM
|
|||
json
|
||||
get_process_mem (0.2.0)
|
||||
gherkin-ruby (0.3.2)
|
||||
github-linguist (4.7.5)
|
||||
github-linguist (4.7.6)
|
||||
charlock_holmes (~> 0.7.3)
|
||||
escape_utils (~> 1.1.0)
|
||||
mime-types (>= 1.19)
|
||||
|
@ -346,14 +343,14 @@ GEM
|
|||
flowdock (~> 0.7)
|
||||
gitlab-grit (>= 2.4.1)
|
||||
multi_json
|
||||
gitlab-grit (2.7.3)
|
||||
gitlab-grit (2.8.1)
|
||||
charlock_holmes (~> 0.6)
|
||||
diff-lcs (~> 1.1)
|
||||
mime-types (~> 1.15)
|
||||
mime-types (>= 1.16, < 3)
|
||||
posix-spawn (~> 0.3)
|
||||
gitlab_emoji (0.3.1)
|
||||
gemojione (~> 2.2, >= 2.2.1)
|
||||
gitlab_git (10.0.0)
|
||||
gitlab_git (10.1.0)
|
||||
activesupport (~> 4.0)
|
||||
charlock_holmes (~> 0.7.3)
|
||||
github-linguist (~> 4.7.0)
|
||||
|
@ -405,6 +402,8 @@ GEM
|
|||
html2haml (>= 1.0.1)
|
||||
railties (>= 4.0.1)
|
||||
hashie (3.4.3)
|
||||
health_check (1.5.1)
|
||||
rails (>= 2.3.0)
|
||||
highline (1.7.8)
|
||||
hipchat (1.5.2)
|
||||
httparty
|
||||
|
@ -431,12 +430,10 @@ GEM
|
|||
json
|
||||
ipaddress (0.8.2)
|
||||
jquery-atwho-rails (1.3.2)
|
||||
jquery-rails (4.0.5)
|
||||
rails-dom-testing (~> 1.0)
|
||||
jquery-rails (4.1.1)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
jquery-scrollto-rails (1.4.3)
|
||||
railties (> 3.1, < 5.0)
|
||||
jquery-turbolinks (2.1.0)
|
||||
railties (>= 3.1.0)
|
||||
turbolinks
|
||||
|
@ -450,8 +447,12 @@ GEM
|
|||
kgio (2.10.0)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
letter_opener (1.1.2)
|
||||
letter_opener (1.4.1)
|
||||
launchy (~> 2.2)
|
||||
letter_opener_web (1.3.0)
|
||||
actionmailer (>= 3.2)
|
||||
letter_opener (~> 1.0)
|
||||
railties (>= 3.2)
|
||||
licensee (8.0.0)
|
||||
rugged (>= 0.24b)
|
||||
listen (3.0.5)
|
||||
|
@ -463,9 +464,9 @@ GEM
|
|||
systemu (~> 2.6.2)
|
||||
mail (2.6.4)
|
||||
mime-types (>= 1.16, < 4)
|
||||
mail_room (0.6.1)
|
||||
mail_room (0.7.0)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
mime-types (2.99.1)
|
||||
mimemagic (0.3.0)
|
||||
mini_portile2 (2.0.0)
|
||||
minitest (5.7.0)
|
||||
|
@ -660,29 +661,29 @@ GEM
|
|||
chunky_png
|
||||
rqrcode-rails3 (0.1.7)
|
||||
rqrcode (>= 0.4.2)
|
||||
rspec (3.3.0)
|
||||
rspec-core (~> 3.3.0)
|
||||
rspec-expectations (~> 3.3.0)
|
||||
rspec-mocks (~> 3.3.0)
|
||||
rspec-core (3.3.2)
|
||||
rspec-support (~> 3.3.0)
|
||||
rspec-expectations (3.3.1)
|
||||
rspec (3.4.0)
|
||||
rspec-core (~> 3.4.0)
|
||||
rspec-expectations (~> 3.4.0)
|
||||
rspec-mocks (~> 3.4.0)
|
||||
rspec-core (3.4.4)
|
||||
rspec-support (~> 3.4.0)
|
||||
rspec-expectations (3.4.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.3.0)
|
||||
rspec-mocks (3.3.2)
|
||||
rspec-support (~> 3.4.0)
|
||||
rspec-mocks (3.4.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.3.0)
|
||||
rspec-rails (3.3.3)
|
||||
rspec-support (~> 3.4.0)
|
||||
rspec-rails (3.4.2)
|
||||
actionpack (>= 3.0, < 4.3)
|
||||
activesupport (>= 3.0, < 4.3)
|
||||
railties (>= 3.0, < 4.3)
|
||||
rspec-core (~> 3.3.0)
|
||||
rspec-expectations (~> 3.3.0)
|
||||
rspec-mocks (~> 3.3.0)
|
||||
rspec-support (~> 3.3.0)
|
||||
rspec-core (~> 3.4.0)
|
||||
rspec-expectations (~> 3.4.0)
|
||||
rspec-mocks (~> 3.4.0)
|
||||
rspec-support (~> 3.4.0)
|
||||
rspec-retry (0.4.5)
|
||||
rspec-core
|
||||
rspec-support (3.3.0)
|
||||
rspec-support (3.4.1)
|
||||
rubocop (0.38.0)
|
||||
parser (>= 2.3.0.6, < 3.0)
|
||||
powerpack (~> 0.1)
|
||||
|
@ -736,7 +737,7 @@ GEM
|
|||
rack
|
||||
shoulda-matchers (2.8.0)
|
||||
activesupport (>= 3.0.0)
|
||||
sidekiq (4.1.1)
|
||||
sidekiq (4.1.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
connection_pool (~> 2.2, >= 2.2.0)
|
||||
redis (~> 3.2, >= 3.2.1)
|
||||
|
@ -881,20 +882,19 @@ PLATFORMS
|
|||
|
||||
DEPENDENCIES
|
||||
RedCloth (~> 4.2.9)
|
||||
ace-rails-ap (~> 2.0.1)
|
||||
activerecord-deprecated_finders (~> 1.0.3)
|
||||
ace-rails-ap (~> 4.0.2)
|
||||
activerecord-session_store (~> 0.1.0)
|
||||
acts-as-taggable-on (~> 3.4)
|
||||
addressable (~> 2.3.8)
|
||||
after_commit_queue
|
||||
akismet (~> 2.0)
|
||||
allocations (~> 1.0)
|
||||
annotate (~> 2.7.0)
|
||||
asana (~> 0.4.0)
|
||||
asciidoctor (~> 1.5.2)
|
||||
attr_encrypted (~> 1.3.4)
|
||||
awesome_print (~> 1.2.0)
|
||||
babosa (~> 1.0.2)
|
||||
base32 (~> 0.3.0)
|
||||
benchmark-ips
|
||||
better_errors (~> 1.0.1)
|
||||
binding_of_caller (~> 0.7.2)
|
||||
|
@ -904,7 +904,7 @@ DEPENDENCIES
|
|||
bullet
|
||||
bundler-audit
|
||||
byebug
|
||||
cal-heatmap-rails (~> 3.5.0)
|
||||
cal-heatmap-rails (~> 3.6.0)
|
||||
capybara (~> 2.6.2)
|
||||
capybara-screenshot (~> 1.0.0)
|
||||
carrierwave (~> 0.10.0)
|
||||
|
@ -921,7 +921,7 @@ DEPENDENCIES
|
|||
devise-async (~> 0.9.0)
|
||||
devise-two-factor (~> 2.0.0)
|
||||
diffy (~> 3.0.3)
|
||||
doorkeeper (~> 2.2.0)
|
||||
doorkeeper (~> 3.1)
|
||||
dropzonejs-rails (~> 0.7.1)
|
||||
email_reply_parser (~> 0.5.8)
|
||||
email_spec (~> 1.6.0)
|
||||
|
@ -947,20 +947,21 @@ DEPENDENCIES
|
|||
grape (~> 0.13.0)
|
||||
grape-entity (~> 0.4.2)
|
||||
haml-rails (~> 0.9.0)
|
||||
health_check (~> 1.5.1)
|
||||
hipchat (~> 1.5.0)
|
||||
html-pipeline (~> 1.11.0)
|
||||
httparty (~> 0.13.3)
|
||||
influxdb (~> 0.2)
|
||||
jquery-atwho-rails (~> 1.3.2)
|
||||
jquery-rails (~> 4.0.0)
|
||||
jquery-scrollto-rails (~> 1.4.3)
|
||||
jquery-rails (~> 4.1.0)
|
||||
jquery-turbolinks (~> 2.1.0)
|
||||
jquery-ui-rails (~> 5.0.0)
|
||||
jwt
|
||||
kaminari (~> 0.16.3)
|
||||
letter_opener (~> 1.1.2)
|
||||
letter_opener_web (~> 1.3.0)
|
||||
licensee (~> 8.0.0)
|
||||
loofah (~> 2.0.3)
|
||||
mail_room (~> 0.6.1)
|
||||
mail_room (~> 0.7)
|
||||
method_source (~> 0.8)
|
||||
minitest (~> 5.7.0)
|
||||
mousetrap-rails (~> 1.4.6)
|
||||
|
@ -1010,7 +1011,7 @@ DEPENDENCIES
|
|||
responders (~> 2.0)
|
||||
rouge (~> 1.10.1)
|
||||
rqrcode-rails3 (~> 0.1.7)
|
||||
rspec-rails (~> 3.3.0)
|
||||
rspec-rails (~> 3.4.0)
|
||||
rspec-retry
|
||||
rubocop (~> 0.38.0)
|
||||
ruby-fogbugz (~> 0.2.1)
|
||||
|
@ -1057,4 +1058,4 @@ DEPENDENCIES
|
|||
wikicloth (= 0.8.1)
|
||||
|
||||
BUNDLED WITH
|
||||
1.11.2
|
||||
1.12.3
|
||||
|
|
|
@ -59,7 +59,7 @@ core team members will mention this person.
|
|||
|
||||
Workflow labels are purposely not very detailed since that would be hard to keep
|
||||
updated as you would need to re-evaluate them after every comment. We optionally
|
||||
use functional labels on demand when want to group related issues to get an
|
||||
use functional labels on demand when we want to group related issues to get an
|
||||
overview (for example all issues related to RVM, to tackle them in one go) and
|
||||
to add details to the issue.
|
||||
|
||||
|
@ -73,6 +73,7 @@ in support or comment for further detail. Do not use `feature request`.
|
|||
- ~bug is an issue reporting undesirable or incorrect behavior.
|
||||
- ~customer is an issue reported by enterprise subscribers. This label should
|
||||
be accompanied by *bug* or *feature proposal* labels.
|
||||
|
||||
Example workflow: when a UX designer provided a design but it needs frontend work they remove the UX label and add the frontend label.
|
||||
|
||||
## Functional labels
|
||||
|
|
12
README.md
12
README.md
|
@ -1,6 +1,6 @@
|
|||
# GitLab
|
||||
|
||||
[![build status](https://ci.gitlab.com/projects/1/status.svg?ref=master)](https://ci.gitlab.com/projects/1?ref=master)
|
||||
[![build status](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/build.svg)](https://gitlab.com/gitlab-org/gitlab-ce/commits/master)
|
||||
[![Build Status](https://semaphoreci.com/api/v1/projects/2f1a5809-418b-4cc2-a1f4-819607579fe7/400484/shields_badge.svg)](https://semaphoreci.com/gitlabhq/gitlabhq)
|
||||
[![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq)
|
||||
[![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.svg?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master)
|
||||
|
@ -20,6 +20,10 @@ To see how GitLab looks please see the [features page on our website](https://ab
|
|||
- Completely free and open source (MIT Expat license)
|
||||
- Powered by [Ruby on Rails](https://github.com/rails/rails)
|
||||
|
||||
## Hiring
|
||||
|
||||
We're hiring developers, support people, and production engineers all the time, please see our [jobs page](https://about.gitlab.com/jobs/).
|
||||
|
||||
## Editions
|
||||
|
||||
There are two editions of GitLab:
|
||||
|
@ -31,11 +35,11 @@ There are two editions of GitLab:
|
|||
|
||||
On [about.gitlab.com](https://about.gitlab.com/) you can find more information about:
|
||||
|
||||
- [Subscriptions](https://about.gitlab.com/subscription/)
|
||||
- [Subscriptions](https://about.gitlab.com/pricing/)
|
||||
- [Consultancy](https://about.gitlab.com/consultancy/)
|
||||
- [Community](https://about.gitlab.com/community/)
|
||||
- [Hosted GitLab.com](https://about.gitlab.com/gitlab-com/) use GitLab as a free service
|
||||
- [GitLab Enterprise Edition](https://about.gitlab.com/gitlab-ee/) with additional features aimed at larger organizations.
|
||||
- [GitLab Enterprise Edition](https://about.gitlab.com/features/#enterprise) with additional features aimed at larger organizations.
|
||||
- [GitLab CI](https://about.gitlab.com/gitlab-ci/) a continuous integration (CI) server that is easy to integrate with GitLab.
|
||||
|
||||
## Requirements
|
||||
|
@ -80,7 +84,7 @@ There are a lot of [third-party applications integrating with GitLab](https://ab
|
|||
|
||||
## GitLab release cycle
|
||||
|
||||
For more information about the release process see the [release documentation](http://doc.gitlab.com/ce/release/).
|
||||
For more information about the release process see the [release documentation](https://gitlab.com/gitlab-org/release-tools/blob/master/README.md).
|
||||
|
||||
## Upgrading
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 25 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 74 KiB |
|
@ -204,6 +204,7 @@ $ ->
|
|||
$('.header-content .title').toggle()
|
||||
$('.header-content .navbar-collapse').toggle()
|
||||
$('.navbar-toggle').toggleClass('active')
|
||||
$('.navbar-toggle i').toggleClass("fa-angle-right fa-angle-left")
|
||||
|
||||
# Show/hide comments on diff
|
||||
$("body").on "click", ".js-toggle-diff-comments", (e) ->
|
||||
|
|
|
@ -1,77 +1,77 @@
|
|||
class @AwardsHandler
|
||||
constructor: (@get_emojis_url, @post_emoji_url, @noteable_type, @noteable_id, @aliases) ->
|
||||
$(".js-add-award").on "click", (event) =>
|
||||
constructor: (@getEmojisUrl, @postEmojiUrl, @noteableType, @noteableId, @unicodes) ->
|
||||
$('.js-add-award').on 'click', (event) =>
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
|
||||
@showEmojiMenu()
|
||||
|
||||
$("html").on 'click', (event) ->
|
||||
if !$(event.target).closest(".emoji-menu").length
|
||||
if $(".emoji-menu").is(":visible")
|
||||
$(".emoji-menu").removeClass "is-visible"
|
||||
$('html').on 'click', (event) ->
|
||||
if !$(event.target).closest('.emoji-menu').length
|
||||
if $('.emoji-menu').is(':visible')
|
||||
$('.emoji-menu').removeClass 'is-visible'
|
||||
|
||||
$(".awards")
|
||||
.off "click"
|
||||
.on "click", ".js-emoji-btn", @handleClick
|
||||
$('.awards')
|
||||
.off 'click'
|
||||
.on 'click', '.js-emoji-btn', @handleClick
|
||||
|
||||
@renderFrequentlyUsedBlock()
|
||||
|
||||
handleClick: (e) ->
|
||||
e.preventDefault()
|
||||
emoji = $(this)
|
||||
.find(".icon")
|
||||
.data "emoji"
|
||||
.find('.icon')
|
||||
.data 'emoji'
|
||||
|
||||
if emoji is "thumbsup" and awards_handler.didUserClickEmoji $(this), "thumbsdown"
|
||||
awards_handler.addAward "thumbsdown"
|
||||
if emoji is 'thumbsup' and awardsHandler.didUserClickEmoji $(this), 'thumbsdown'
|
||||
awardsHandler.addAward 'thumbsdown'
|
||||
|
||||
else if emoji is "thumbsdown" and awards_handler.didUserClickEmoji $(this), "thumbsup"
|
||||
awards_handler.addAward "thumbsup"
|
||||
else if emoji is 'thumbsdown' and awardsHandler.didUserClickEmoji $(this), 'thumbsup'
|
||||
awardsHandler.addAward 'thumbsup'
|
||||
|
||||
awards_handler.addAward emoji
|
||||
awardsHandler.addAward emoji
|
||||
|
||||
$(this).trigger 'blur'
|
||||
|
||||
didUserClickEmoji: (that, emoji) ->
|
||||
if $(that).siblings("button:has([data-emoji=#{emoji}])").attr("data-original-title")
|
||||
$(that).siblings("button:has([data-emoji=#{emoji}])").attr("data-original-title").indexOf('me') > -1
|
||||
if $(that).siblings("button:has([data-emoji=#{emoji}])").attr('data-original-title')
|
||||
$(that).siblings("button:has([data-emoji=#{emoji}])").attr('data-original-title').indexOf('me') > -1
|
||||
|
||||
showEmojiMenu: ->
|
||||
if $(".emoji-menu").length
|
||||
if $(".emoji-menu").is ".is-visible"
|
||||
$(".emoji-menu").removeClass "is-visible"
|
||||
$("#emoji_search").blur()
|
||||
if $('.emoji-menu').length
|
||||
if $('.emoji-menu').is '.is-visible'
|
||||
$('.emoji-menu').removeClass 'is-visible'
|
||||
$('#emoji_search').blur()
|
||||
else
|
||||
$(".emoji-menu").addClass "is-visible"
|
||||
$("#emoji_search").focus()
|
||||
$('.emoji-menu').addClass 'is-visible'
|
||||
$('#emoji_search').focus()
|
||||
else
|
||||
$('.js-add-award').addClass "is-loading"
|
||||
$.get @get_emojis_url, (response) =>
|
||||
$('.js-add-award').removeClass "is-loading"
|
||||
$(".js-award-holder").append response
|
||||
$('.js-add-award').addClass 'is-loading'
|
||||
$.get @getEmojisUrl, (response) =>
|
||||
$('.js-add-award').removeClass 'is-loading'
|
||||
$('.js-award-holder').append response
|
||||
setTimeout =>
|
||||
$(".emoji-menu").addClass "is-visible"
|
||||
$("#emoji_search").focus()
|
||||
$('.emoji-menu').addClass 'is-visible'
|
||||
$('#emoji_search').focus()
|
||||
@setupSearch()
|
||||
, 200
|
||||
|
||||
addAward: (emoji) ->
|
||||
emoji = @normilizeEmojiName(emoji)
|
||||
@postEmoji emoji, =>
|
||||
@addAwardToEmojiBar(emoji)
|
||||
|
||||
$(".emoji-menu").removeClass "is-visible"
|
||||
$('.emoji-menu').removeClass 'is-visible'
|
||||
|
||||
addAwardToEmojiBar: (emoji) ->
|
||||
@addEmojiToFrequentlyUsedList(emoji)
|
||||
|
||||
emoji = @normilizeEmojiName(emoji)
|
||||
if @exist(emoji)
|
||||
if @isActive(emoji)
|
||||
@decrementCounter(emoji)
|
||||
else
|
||||
counter = @findEmojiIcon(emoji).siblings(".js-counter")
|
||||
counter = @findEmojiIcon(emoji).siblings('.js-counter')
|
||||
counter.text(parseInt(counter.text()) + 1)
|
||||
counter.parent().addClass("active")
|
||||
counter.parent().addClass('active')
|
||||
@addMeToAuthorList(emoji)
|
||||
else
|
||||
@createEmoji(emoji)
|
||||
|
@ -80,47 +80,47 @@ class @AwardsHandler
|
|||
@findEmojiIcon(emoji).length > 0
|
||||
|
||||
isActive: (emoji) ->
|
||||
@findEmojiIcon(emoji).parent().hasClass("active")
|
||||
@findEmojiIcon(emoji).parent().hasClass('active')
|
||||
|
||||
decrementCounter: (emoji) ->
|
||||
counter = @findEmojiIcon(emoji).siblings(".js-counter")
|
||||
counter = @findEmojiIcon(emoji).siblings('.js-counter')
|
||||
emojiIcon = counter.parent()
|
||||
if parseInt(counter.text()) > 1
|
||||
counter.text(parseInt(counter.text()) - 1)
|
||||
emojiIcon.removeClass("active")
|
||||
emojiIcon.removeClass('active')
|
||||
@removeMeFromAuthorList(emoji)
|
||||
else if emoji == "thumbsup" || emoji == "thumbsdown"
|
||||
emojiIcon.tooltip("destroy")
|
||||
else if emoji == 'thumbsup' || emoji == 'thumbsdown'
|
||||
emojiIcon.tooltip('destroy')
|
||||
counter.text(0)
|
||||
emojiIcon.removeClass("active")
|
||||
emojiIcon.removeClass('active')
|
||||
@removeMeFromAuthorList(emoji)
|
||||
else
|
||||
emojiIcon.tooltip("destroy")
|
||||
emojiIcon.tooltip('destroy')
|
||||
emojiIcon.remove()
|
||||
|
||||
removeMeFromAuthorList: (emoji) ->
|
||||
award_block = @findEmojiIcon(emoji).parent()
|
||||
authors = award_block
|
||||
.attr("data-original-title")
|
||||
.split(", ")
|
||||
authors.splice(authors.indexOf("me"),1)
|
||||
award_block
|
||||
.closest(".js-emoji-btn")
|
||||
.attr("data-original-title", authors.join(", "))
|
||||
@resetTooltip(award_block)
|
||||
awardBlock = @findEmojiIcon(emoji).parent()
|
||||
authors = awardBlock
|
||||
.attr('data-original-title')
|
||||
.split(', ')
|
||||
authors.splice(authors.indexOf('me'),1)
|
||||
awardBlock
|
||||
.closest('.js-emoji-btn')
|
||||
.attr('data-original-title', authors.join(', '))
|
||||
@resetTooltip(awardBlock)
|
||||
|
||||
addMeToAuthorList: (emoji) ->
|
||||
award_block = @findEmojiIcon(emoji).parent()
|
||||
origTitle = award_block.attr("data-original-title").trim()
|
||||
awardBlock = @findEmojiIcon(emoji).parent()
|
||||
origTitle = awardBlock.attr('data-original-title').trim()
|
||||
authors = []
|
||||
if origTitle
|
||||
authors = origTitle.split(', ')
|
||||
authors.push("me")
|
||||
award_block.attr("data-original-title", authors.join(", "))
|
||||
@resetTooltip(award_block)
|
||||
authors.push('me')
|
||||
awardBlock.attr('data-original-title', authors.join(', '))
|
||||
@resetTooltip(awardBlock)
|
||||
|
||||
resetTooltip: (award) ->
|
||||
award.tooltip("destroy")
|
||||
award.tooltip('destroy')
|
||||
|
||||
# "destroy" call is asynchronous and there is no appropriate callback on it, this is why we need to set timeout.
|
||||
setTimeout (->
|
||||
|
@ -139,28 +139,28 @@ class @AwardsHandler
|
|||
"</button>"
|
||||
)
|
||||
|
||||
emoji_node = $(nodes.join("\n"))
|
||||
.insertBefore(".js-award-holder")
|
||||
.find(".emoji-icon")
|
||||
.data("emoji", emoji)
|
||||
$(nodes.join("\n"))
|
||||
.insertBefore('.js-award-holder')
|
||||
.find('.emoji-icon')
|
||||
.data('emoji', emoji)
|
||||
$('.award-control').tooltip()
|
||||
|
||||
resolveNameToCssClass: (emoji) ->
|
||||
emoji_icon = $(".emoji-menu-content [data-emoji='#{emoji}']")
|
||||
emojiIcon = $(".emoji-menu-content [data-emoji='#{emoji}']")
|
||||
|
||||
if emoji_icon.length > 0
|
||||
unicodeName = emoji_icon.data("unicode-name")
|
||||
if emojiIcon.length > 0
|
||||
unicodeName = emojiIcon.data('unicode-name')
|
||||
else
|
||||
# Find by alias
|
||||
unicodeName = $(".emoji-menu-content [data-aliases*=':#{emoji}:']").data("unicode-name")
|
||||
unicodeName = $(".emoji-menu-content [data-aliases*=':#{emoji}:']").data('unicode-name')
|
||||
|
||||
"emoji-#{unicodeName}"
|
||||
|
||||
postEmoji: (emoji, callback) ->
|
||||
$.post @post_emoji_url, { note: {
|
||||
$.post @postEmojiUrl, { note: {
|
||||
note: ":#{emoji}:"
|
||||
noteable_type: @noteable_type
|
||||
noteable_id: @noteable_id
|
||||
noteable_type: @noteableType
|
||||
noteable_id: @noteableId
|
||||
}},(data) ->
|
||||
if data.ok
|
||||
callback.call()
|
||||
|
@ -173,46 +173,43 @@ class @AwardsHandler
|
|||
scrollTop: $('.awards').offset().top - 80
|
||||
}, 200)
|
||||
|
||||
normilizeEmojiName: (emoji) ->
|
||||
@aliases[emoji] || emoji
|
||||
|
||||
addEmojiToFrequentlyUsedList: (emoji) ->
|
||||
frequently_used_emojis = @getFrequentlyUsedEmojis()
|
||||
frequently_used_emojis.push(emoji)
|
||||
$.cookie('frequently_used_emojis', frequently_used_emojis.join(","), { expires: 365 })
|
||||
frequentlyUsedEmojis = @getFrequentlyUsedEmojis()
|
||||
frequentlyUsedEmojis.push(emoji)
|
||||
$.cookie('frequently_used_emojis', frequentlyUsedEmojis.join(','), { expires: 365 })
|
||||
|
||||
getFrequentlyUsedEmojis: ->
|
||||
frequently_used_emojis = ($.cookie('frequently_used_emojis') || "").split(",")
|
||||
_.compact(_.uniq(frequently_used_emojis))
|
||||
frequentlyUsedEmojis = ($.cookie('frequently_used_emojis') || '').split(',')
|
||||
_.compact(_.uniq(frequentlyUsedEmojis))
|
||||
|
||||
renderFrequentlyUsedBlock: ->
|
||||
if $.cookie('frequently_used_emojis')
|
||||
frequently_used_emojis = @getFrequentlyUsedEmojis()
|
||||
frequentlyUsedEmojis = @getFrequentlyUsedEmojis()
|
||||
|
||||
ul = $("<ul>")
|
||||
ul = $('<ul>')
|
||||
|
||||
for emoji in frequently_used_emojis
|
||||
for emoji in frequentlyUsedEmojis
|
||||
do (emoji) ->
|
||||
$(".emoji-menu-content [data-emoji='#{emoji}']").closest("li").clone().appendTo(ul)
|
||||
$(".emoji-menu-content [data-emoji='#{emoji}']").closest('li').clone().appendTo(ul)
|
||||
|
||||
$("input.emoji-search").after(ul).after($("<h5>").text("Frequently used"))
|
||||
$('input.emoji-search').after(ul).after($('<h5>').text('Frequently used'))
|
||||
|
||||
setupSearch: ->
|
||||
$("input.emoji-search").keyup (ev) =>
|
||||
$('input.emoji-search').keyup (ev) =>
|
||||
term = $(ev.target).val()
|
||||
|
||||
# Clean previous search results
|
||||
$("ul.emoji-menu-search, h5.emoji-search").remove()
|
||||
$('ul.emoji-menu-search, h5.emoji-search').remove()
|
||||
|
||||
if term
|
||||
# Generate a search result block
|
||||
h5 = $("<h5>").text("Search results").addClass("emoji-search")
|
||||
found_emojis = @searchEmojis(term).show()
|
||||
ul = $("<ul>").addClass("emoji-menu-list emoji-menu-search").append(found_emojis)
|
||||
$(".emoji-menu-content ul, .emoji-menu-content h5").hide()
|
||||
$(".emoji-menu-content").append(h5).append(ul)
|
||||
h5 = $('<h5>').text('Search results').addClass('emoji-search')
|
||||
foundEmojis = @searchEmojis(term).show()
|
||||
ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(foundEmojis)
|
||||
$('.emoji-menu-content ul, .emoji-menu-content h5').hide()
|
||||
$('.emoji-menu-content').append(h5).append(ul)
|
||||
else
|
||||
$(".emoji-menu-content").children().show()
|
||||
$('.emoji-menu-content').children().show()
|
||||
|
||||
searchEmojis: (term)->
|
||||
$(".emoji-menu-content [data-emoji*='#{term}']").closest("li").clone()
|
||||
|
|
|
@ -1,34 +1,6 @@
|
|||
# This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||
# listed below.
|
||||
#
|
||||
# Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||
# or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
||||
#
|
||||
# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||
# the compiled file.
|
||||
#
|
||||
# WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
||||
# GO AFTER THE REQUIRES BELOW.
|
||||
#
|
||||
#= require pager
|
||||
#= require jquery_nested_form
|
||||
#= require_tree .
|
||||
#
|
||||
$(document).on 'click', '.edit-runner-link', (event) ->
|
||||
event.preventDefault()
|
||||
|
||||
descr = $(this).closest('.runner-description').first()
|
||||
descr.addClass('hide')
|
||||
form = descr.next('.runner-description-form')
|
||||
descrInput = form.find('input.description')
|
||||
originalValue = descrInput.val()
|
||||
form.removeClass('hide')
|
||||
form.find('.cancel').on 'click', (event) ->
|
||||
event.preventDefault()
|
||||
|
||||
form.addClass('hide')
|
||||
descrInput.val(originalValue)
|
||||
descr.removeClass('hide')
|
||||
|
||||
$(document).on 'click', '.assign-all-runner', ->
|
||||
$(this).replaceWith('<i class="fa fa-refresh fa-spin"></i> Assign in progress..')
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
class CiBuild
|
||||
@interval: null
|
||||
@state: null
|
||||
|
||||
constructor: (build_url, build_status) ->
|
||||
constructor: (build_url, build_status, build_state) ->
|
||||
clearInterval(CiBuild.interval)
|
||||
|
||||
@state = build_state
|
||||
|
||||
@initScrollButtonAffix()
|
||||
|
||||
if build_status == "running" || build_status == "pending"
|
||||
|
@ -26,14 +29,18 @@ class CiBuild
|
|||
CiBuild.interval = setInterval =>
|
||||
if window.location.href.split("#").first() is build_url
|
||||
$.ajax
|
||||
url: build_url
|
||||
url: build_url + "/trace.json?state=" + encodeURIComponent(@state)
|
||||
dataType: "json"
|
||||
success: (build) =>
|
||||
if build.status == "running"
|
||||
$('#build-trace code').html build.trace_html
|
||||
success: (log) =>
|
||||
@state = log.state
|
||||
if log.status is "running"
|
||||
if log.append
|
||||
$('.fa-refresh').before log.html
|
||||
else
|
||||
$('#build-trace code').html log.html
|
||||
$('#build-trace code').append '<i class="fa fa-refresh fa-spin"/>'
|
||||
@checkAutoscroll()
|
||||
else if build.status != build_status
|
||||
else if log.status isnt build_status
|
||||
Turbolinks.visit build_url
|
||||
, 4000
|
||||
|
||||
|
|
|
@ -108,6 +108,8 @@ class Dispatcher
|
|||
new BuildArtifacts()
|
||||
when 'projects:group_links:index'
|
||||
new GroupsSelect()
|
||||
when 'search:show'
|
||||
new Search()
|
||||
|
||||
switch path.first()
|
||||
when 'admin'
|
||||
|
|
|
@ -184,6 +184,9 @@ class GitLabDropdown
|
|||
@dropdown.on "shown.bs.dropdown", @opened
|
||||
@dropdown.on "hidden.bs.dropdown", @hidden
|
||||
@dropdown.on "click", ".dropdown-menu, .dropdown-menu-close", @shouldPropagate
|
||||
@dropdown.on 'keyup', (e) =>
|
||||
if e.which is 27 # Escape key
|
||||
$('.dropdown-menu-close', @dropdown).trigger 'click'
|
||||
|
||||
if @dropdown.find(".dropdown-toggle-page").length
|
||||
@dropdown.find(".dropdown-toggle-page, .dropdown-menu-back").on "click", (e) =>
|
||||
|
|
|
@ -10,8 +10,8 @@ class @IssuableContext
|
|||
$(this).submit()
|
||||
|
||||
$(document)
|
||||
.off 'click', '.dropdown-content a'
|
||||
.on 'click', '.dropdown-content a', (e) ->
|
||||
.off 'click', '.issuable-sidebar .dropdown-content a'
|
||||
.on 'click', '.issuable-sidebar .dropdown-content a', (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
$(document)
|
||||
|
|
|
@ -12,6 +12,7 @@ class @Issue
|
|||
|
||||
@initMergeRequests()
|
||||
@initRelatedBranches()
|
||||
@initCanCreateBranch()
|
||||
|
||||
initTaskList: ->
|
||||
$('.detail-page-description .js-task-list-container').taskList('enable')
|
||||
|
@ -92,3 +93,25 @@ class @Issue
|
|||
.success (data) ->
|
||||
if 'html' of data
|
||||
$container.html(data.html)
|
||||
|
||||
initCanCreateBranch: ->
|
||||
$container = $('div#new-branch')
|
||||
|
||||
# If the user doesn't have the required permissions the container isn't
|
||||
# rendered at all.
|
||||
return unless $container
|
||||
|
||||
$.getJSON($container.data('path'))
|
||||
.error ->
|
||||
$container.find('.checking').hide()
|
||||
$container.find('.unavailable').show()
|
||||
|
||||
new Flash('Failed to check if a new branch can be created.', 'alert')
|
||||
.success (data) ->
|
||||
if data.can_create_branch
|
||||
$container.find('.checking').hide()
|
||||
$container.find('.available').show()
|
||||
$container.find('a').attr('disabled', false)
|
||||
else
|
||||
$container.find('.checking').hide()
|
||||
$container.find('.unavailable').show()
|
||||
|
|
|
@ -30,7 +30,7 @@ class @LabelsSelect
|
|||
if issueUpdateURL
|
||||
labelHTMLTemplate = _.template(
|
||||
'<% _.each(labels, function(label){ %>
|
||||
<a href="<%= ["",issueURLSplit[1], issueURLSplit[2],""].join("/") %>issues?label_name=<%= _.escape(label.title) %>">
|
||||
<a href="<%= ["",issueURLSplit[1], issueURLSplit[2],""].join("/") %>issues?label_name[]=<%= _.escape(label.title) %>">
|
||||
<span class="label has-tooltip color-label" title="<%= _.escape(label.description) %>" style="background-color: <%= label.color %>; color: <%= label.text_color %>;">
|
||||
<%= _.escape(label.title) %>
|
||||
</span>
|
||||
|
@ -163,6 +163,21 @@ class @LabelsSelect
|
|||
$.ajax(
|
||||
url: labelUrl
|
||||
).done (data) ->
|
||||
data = _.chain data
|
||||
.groupBy (label) ->
|
||||
label.title
|
||||
.map (label) ->
|
||||
color = _.map label, (dup) ->
|
||||
dup.color
|
||||
|
||||
return {
|
||||
id: label[0].id
|
||||
title: label[0].title
|
||||
color: color
|
||||
duplicate: color.length > 1
|
||||
}
|
||||
.value()
|
||||
|
||||
if $dropdown.hasClass 'js-extra-options'
|
||||
if showNo
|
||||
data.unshift(
|
||||
|
@ -178,6 +193,7 @@ class @LabelsSelect
|
|||
|
||||
if data.length > 2
|
||||
data.splice 2, 0, 'divider'
|
||||
|
||||
callback data
|
||||
|
||||
renderRow: (label) ->
|
||||
|
@ -192,11 +208,31 @@ class @LabelsSelect
|
|||
if $dropdown.hasClass('js-multiselect') and removesAll
|
||||
selectedClass.push 'dropdown-clear-active'
|
||||
|
||||
color = if label.color? then "<span class='dropdown-label-box' style='background-color: #{label.color}'></span>" else ""
|
||||
if label.duplicate
|
||||
spacing = 100 / label.color.length
|
||||
|
||||
# Reduce the colors to 4
|
||||
label.color = label.color.filter (color, i) ->
|
||||
i < 4
|
||||
|
||||
color = _.map(label.color, (color, i) ->
|
||||
percentFirst = Math.floor(spacing * i)
|
||||
percentSecond = Math.floor(spacing * (i + 1))
|
||||
"#{color} #{percentFirst}%,#{color} #{percentSecond}% "
|
||||
).join(',')
|
||||
color = "linear-gradient(#{color})"
|
||||
else
|
||||
if label.color?
|
||||
color = label.color[0]
|
||||
|
||||
if color
|
||||
colorEl = "<span class='dropdown-label-box' style='background: #{color}'></span>"
|
||||
else
|
||||
colorEl = ''
|
||||
|
||||
"<li>
|
||||
<a href='#' class='#{selectedClass.join(' ')}'>
|
||||
#{color}
|
||||
#{colorEl}
|
||||
#{_.escape(label.title)}
|
||||
</a>
|
||||
</li>"
|
||||
|
|
|
@ -9,11 +9,12 @@ class @MergeRequestWidget
|
|||
constructor: (@opts) ->
|
||||
$('#modal_merge_info').modal(show: false)
|
||||
@firstCICheck = true
|
||||
@readyForCICheck = true
|
||||
@readyForCICheck = false
|
||||
clearInterval @fetchBuildStatusInterval
|
||||
|
||||
@clearEventListeners()
|
||||
@addEventListeners()
|
||||
@getCIStatus(false)
|
||||
@pollCIStatus()
|
||||
notifyPermissions()
|
||||
|
||||
|
@ -68,20 +69,18 @@ class @MergeRequestWidget
|
|||
$.getJSON @opts.ci_status_url, (data) =>
|
||||
@readyForCICheck = true
|
||||
|
||||
if @firstCICheck
|
||||
@firstCICheck = false
|
||||
@opts.ci_status = data.status
|
||||
|
||||
if @opts.ci_status is ''
|
||||
@opts.ci_status = data.status
|
||||
if data.status is ''
|
||||
return
|
||||
|
||||
if data.status isnt @opts.ci_status and data.status?
|
||||
if @firstCICheck || data.status isnt @opts.ci_status and data.status?
|
||||
@opts.ci_status = data.status
|
||||
@showCIStatus data.status
|
||||
if data.coverage
|
||||
@showCICoverage data.coverage
|
||||
|
||||
if showNotification
|
||||
# The first check should only update the UI, a notification
|
||||
# should only be displayed on status changes
|
||||
if showNotification and not @firstCICheck
|
||||
status = @ciLabelForStatus(data.status)
|
||||
|
||||
if status is "preparing"
|
||||
|
@ -104,8 +103,7 @@ class @MergeRequestWidget
|
|||
@close()
|
||||
Turbolinks.visit _this.opts.builds_path
|
||||
)
|
||||
|
||||
@opts.ci_status = data.status
|
||||
@firstCICheck = false
|
||||
|
||||
showCIStatus: (state) ->
|
||||
$('.ci_widget').hide()
|
||||
|
|
|
@ -167,8 +167,8 @@ class @Notes
|
|||
return
|
||||
|
||||
if note.award
|
||||
awards_handler.addAwardToEmojiBar(note.note)
|
||||
awards_handler.scrollToAwards()
|
||||
awardsHandler.addAwardToEmojiBar(note.note)
|
||||
awardsHandler.scrollToAwards()
|
||||
|
||||
# render note if it not present in loaded list
|
||||
# or skip if rendered
|
||||
|
@ -285,6 +285,7 @@ class @Notes
|
|||
form.addClass "js-main-target-form"
|
||||
|
||||
form.find("#note_line_code").remove()
|
||||
form.find("#note_type").remove()
|
||||
|
||||
###
|
||||
General note form setup.
|
||||
|
@ -472,6 +473,7 @@ class @Notes
|
|||
setupDiscussionNoteForm: (dataHolder, form) =>
|
||||
# setup note target
|
||||
form.attr 'id', "new-discussion-note-form-#{dataHolder.data("discussionId")}"
|
||||
form.find("#note_type").val dataHolder.data("noteType")
|
||||
form.find("#line_type").val dataHolder.data("lineType")
|
||||
form.find("#note_commit_id").val dataHolder.data("commitId")
|
||||
form.find("#note_line_code").val dataHolder.data("lineCode")
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
class @Sidebar
|
||||
constructor: (currentUser) ->
|
||||
@sidebar = $('aside')
|
||||
|
||||
@addEventListeners()
|
||||
|
||||
addEventListeners: ->
|
||||
$('aside').on('click', '.sidebar-collapsed-icon', @sidebarCollapseClicked)
|
||||
$('.dropdown').on('hidden.gl.dropdown', @sidebarDropdownHidden)
|
||||
@sidebar.on('click', '.sidebar-collapsed-icon', @, @sidebarCollapseClicked)
|
||||
$('.dropdown').on('hidden.gl.dropdown', @, @onSidebarDropdownHidden)
|
||||
$('.dropdown').on('loading.gl.dropdown', @sidebarDropdownLoading)
|
||||
$('.dropdown').on('loaded.gl.dropdown', @sidebarDropdownLoaded)
|
||||
|
||||
|
@ -30,26 +32,56 @@ class @Sidebar
|
|||
else
|
||||
i.show()
|
||||
|
||||
|
||||
sidebarCollapseClicked: (e) ->
|
||||
sidebar = e.data
|
||||
e.preventDefault()
|
||||
$block = $(@).closest('.block')
|
||||
sidebar.openDropdown($block);
|
||||
|
||||
$('aside')
|
||||
.find('.gutter-toggle')
|
||||
.trigger('click')
|
||||
$editLink = $block.find('.edit-link')
|
||||
openDropdown: (blockOrName) ->
|
||||
$block = if _.isString(blockOrName) then @getBlock(blockOrName) else blockOrName
|
||||
|
||||
if $editLink.length
|
||||
$editLink.trigger('click')
|
||||
$block.find('.edit-link').trigger('click')
|
||||
|
||||
if not @isOpen()
|
||||
@setCollapseAfterUpdate($block)
|
||||
@toggleSidebar('open')
|
||||
|
||||
setCollapseAfterUpdate: ($block) ->
|
||||
$block.addClass('collapse-after-update')
|
||||
$('.page-with-sidebar').addClass('with-overlay')
|
||||
|
||||
sidebarDropdownHidden: (e) ->
|
||||
onSidebarDropdownHidden: (e) ->
|
||||
sidebar = e.data
|
||||
e.preventDefault()
|
||||
$block = $(@).closest('.block')
|
||||
sidebar.sidebarDropdownHidden($block)
|
||||
|
||||
sidebarDropdownHidden: ($block) ->
|
||||
if $block.hasClass('collapse-after-update')
|
||||
$block.removeClass('collapse-after-update')
|
||||
$('.page-with-sidebar').removeClass('with-overlay')
|
||||
$('aside')
|
||||
.find('.gutter-toggle')
|
||||
@toggleSidebar('hide')
|
||||
|
||||
triggerOpenSidebar: ->
|
||||
@sidebar
|
||||
.find('.js-sidebar-toggle')
|
||||
.trigger('click')
|
||||
|
||||
toggleSidebar: (action = 'toggle') ->
|
||||
if action is 'toggle'
|
||||
@triggerOpenSidebar()
|
||||
|
||||
if action is 'open'
|
||||
@triggerOpenSidebar() if not @isOpen()
|
||||
|
||||
if action is 'hide'
|
||||
@triggerOpenSidebar() is @isOpen()
|
||||
|
||||
isOpen: ->
|
||||
@sidebar.is('.right-sidebar-expanded')
|
||||
|
||||
getBlock: (name) ->
|
||||
@sidebar.find(".block.#{name}")
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
class @Search
|
||||
constructor: ->
|
||||
$groupDropdown = $('.js-search-group-dropdown')
|
||||
$projectDropdown = $('.js-search-project-dropdown')
|
||||
@eventListeners()
|
||||
|
||||
$groupDropdown.glDropdown(
|
||||
selectable: true
|
||||
filterable: true
|
||||
fieldName: 'group_id'
|
||||
data: (term, callback) ->
|
||||
Api.groups term, null, (data) ->
|
||||
data.unshift(
|
||||
name: 'Any'
|
||||
)
|
||||
data.splice 1, 0, 'divider'
|
||||
|
||||
callback(data)
|
||||
id: (obj) ->
|
||||
obj.id
|
||||
text: (obj) ->
|
||||
obj.name
|
||||
toggleLabel: (obj) ->
|
||||
"#{$groupDropdown.data('default-label')} #{obj.name}"
|
||||
clicked: =>
|
||||
@submitSearch()
|
||||
)
|
||||
|
||||
$projectDropdown.glDropdown(
|
||||
selectable: true
|
||||
filterable: true
|
||||
fieldName: 'project_id'
|
||||
data: (term, callback) ->
|
||||
Api.projects term, 'id', (data) ->
|
||||
data.unshift(
|
||||
name_with_namespace: 'Any'
|
||||
)
|
||||
data.splice 1, 0, 'divider'
|
||||
|
||||
callback(data)
|
||||
id: (obj) ->
|
||||
obj.id
|
||||
text: (obj) ->
|
||||
obj.name_with_namespace
|
||||
toggleLabel: (obj) ->
|
||||
"#{$projectDropdown.data('default-label')} #{obj.name_with_namespace}"
|
||||
clicked: =>
|
||||
@submitSearch()
|
||||
)
|
||||
|
||||
eventListeners: ->
|
||||
$(document)
|
||||
.off 'keyup', '.js-search-input'
|
||||
.on 'keyup', '.js-search-input', @searchKeyUp
|
||||
|
||||
$(document)
|
||||
.off 'click', '.js-search-clear'
|
||||
.on 'click', '.js-search-clear', @clearSearchField
|
||||
|
||||
submitSearch: ->
|
||||
$('.js-search-form').submit()
|
||||
|
||||
searchKeyUp: ->
|
||||
$input = $(@)
|
||||
|
||||
if $input.val() is ''
|
||||
$('.js-search-clear').addClass 'hidden'
|
||||
else
|
||||
$('.js-search-clear').removeClass 'hidden'
|
||||
|
||||
clearSearchField: ->
|
||||
$('.js-search-input')
|
||||
.val ''
|
||||
.trigger 'keyup'
|
||||
.focus()
|
|
@ -2,25 +2,27 @@ class @Shortcuts
|
|||
constructor: ->
|
||||
@enabledHelp = []
|
||||
Mousetrap.reset()
|
||||
Mousetrap.bind('?', @selectiveHelp)
|
||||
Mousetrap.bind('?', @onToggleHelp)
|
||||
Mousetrap.bind('s', Shortcuts.focusSearch)
|
||||
Mousetrap.bind(['ctrl+shift+p', 'command+shift+p'], @toggleMarkdownPreview)
|
||||
Mousetrap.bind('t', -> Turbolinks.visit(findFileURL)) if findFileURL?
|
||||
|
||||
selectiveHelp: (e) =>
|
||||
Shortcuts.showHelp(e, @enabledHelp)
|
||||
onToggleHelp: (e) =>
|
||||
e.preventDefault()
|
||||
@toggleHelp(@enabledHelp)
|
||||
|
||||
toggleMarkdownPreview: (e) =>
|
||||
$(document).triggerHandler('markdown-preview:toggle', [e])
|
||||
|
||||
@showHelp: (e, location) ->
|
||||
if $('#modal-shortcuts').length > 0
|
||||
$('#modal-shortcuts').modal('show')
|
||||
else
|
||||
url = '/help/shortcuts'
|
||||
url = gon.relative_url_root + url if gon.relative_url_root?
|
||||
toggleHelp: (location) ->
|
||||
$modal = $('#modal-shortcuts')
|
||||
|
||||
if $modal.length
|
||||
$modal.modal('toggle')
|
||||
return
|
||||
|
||||
$.ajax(
|
||||
url: url,
|
||||
url: gon.shortcuts_path,
|
||||
dataType: 'script',
|
||||
success: (e) ->
|
||||
if location and location.length > 0
|
||||
|
@ -29,7 +31,6 @@ class @Shortcuts
|
|||
$('.hidden-shortcut').show()
|
||||
$('.js-more-help-button').remove()
|
||||
)
|
||||
e.preventDefault()
|
||||
|
||||
@focusSearch: (e) ->
|
||||
$('#search').focus()
|
||||
|
|
|
@ -4,14 +4,8 @@
|
|||
class @ShortcutsIssuable extends ShortcutsNavigation
|
||||
constructor: (isMergeRequest) ->
|
||||
super()
|
||||
Mousetrap.bind('a', ->
|
||||
$('.block.assignee .edit-link').trigger('click')
|
||||
return false
|
||||
)
|
||||
Mousetrap.bind('m', ->
|
||||
$('.block.milestone .edit-link').trigger('click')
|
||||
return false
|
||||
)
|
||||
Mousetrap.bind('a', @openSidebarDropdown.bind(@, 'assignee'))
|
||||
Mousetrap.bind('m', @openSidebarDropdown.bind(@, 'milestone'))
|
||||
Mousetrap.bind('r', =>
|
||||
@replyWithSelectedText()
|
||||
return false
|
||||
|
@ -28,7 +22,7 @@ class @ShortcutsIssuable extends ShortcutsNavigation
|
|||
@editIssue()
|
||||
return false
|
||||
)
|
||||
|
||||
Mousetrap.bind('l', @openSidebarDropdown.bind(@, 'labels'))
|
||||
|
||||
if isMergeRequest
|
||||
@enabledHelp.push('.hidden-shortcut.merge_requests')
|
||||
|
@ -71,3 +65,7 @@ class @ShortcutsIssuable extends ShortcutsNavigation
|
|||
editIssue: ->
|
||||
$editBtn = $('.issuable-edit')
|
||||
Turbolinks.visit($editBtn.attr('href'))
|
||||
|
||||
openSidebarDropdown: (name) ->
|
||||
sidebar.openDropdown(name)
|
||||
return false
|
||||
|
|
|
@ -14,6 +14,7 @@ class @ShortcutsNavigation extends Shortcuts
|
|||
Mousetrap.bind('g m', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-merge_requests'))
|
||||
Mousetrap.bind('g w', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-wiki'))
|
||||
Mousetrap.bind('g s', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-snippets'))
|
||||
Mousetrap.bind('i', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-new-issue'))
|
||||
@enabledHelp.push('.hidden-shortcut.project')
|
||||
|
||||
@findAndFollowLink: (selector) ->
|
||||
|
|
|
@ -12,7 +12,7 @@ toggleSidebar = ->
|
|||
niceScrollBars.updateScrollBar();
|
||||
), 300
|
||||
|
||||
$(document).on("click", '.toggle-nav-collapse', (e) ->
|
||||
$(document).on("click", '.toggle-nav-collapse, .side-nav-toggle', (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
toggleSidebar()
|
||||
|
|
|
@ -102,7 +102,8 @@ class @Todos
|
|||
todoLink = $(this).data('url')
|
||||
return unless todoLink
|
||||
|
||||
if e.metaKey
|
||||
# Allow Meta-Click or Mouse3-click to open in a new tab
|
||||
if e.metaKey or e.which is 2
|
||||
e.preventDefault()
|
||||
window.open(todoLink,'_blank')
|
||||
else
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
# Personal projects
|
||||
# </a>
|
||||
# </li>
|
||||
# <li class="snippets-tab">
|
||||
# <a data-action="snippets" data-target="#snippets" data-toggle="tab" href="/u/username/snippets">
|
||||
# </a>
|
||||
# </li>
|
||||
# </ul>
|
||||
#
|
||||
# <div class="tab-content">
|
||||
|
@ -41,6 +45,9 @@
|
|||
# <div class="tab-pane" id="projects">
|
||||
# Projects content
|
||||
# </div>
|
||||
# <div class="tab-pane" id="snippets">
|
||||
# Snippets content
|
||||
# </div>
|
||||
# </div>
|
||||
#
|
||||
# <div class="loading-status">
|
||||
|
@ -92,7 +99,7 @@ class @UserTabs
|
|||
@setCurrentAction(action)
|
||||
|
||||
activateTab: (action) ->
|
||||
@parentEl.find(".nav-links .#{action}-tab a").tab('show')
|
||||
@parentEl.find(".nav-links .js-#{action}-tab a").tab('show')
|
||||
|
||||
setTab: (source, action) ->
|
||||
return if @loaded[action] is true
|
||||
|
@ -100,7 +107,7 @@ class @UserTabs
|
|||
if action is 'activity'
|
||||
@loadActivities(source)
|
||||
|
||||
if action in ['groups', 'contributed', 'projects']
|
||||
if action in ['groups', 'contributed', 'projects', 'snippets']
|
||||
@loadTab(source, action)
|
||||
|
||||
loadTab: (source, action) ->
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
@import "framework/lists.scss";
|
||||
@import "framework/markdown_area.scss";
|
||||
@import "framework/mobile.scss";
|
||||
@import "framework/modal.scss";
|
||||
@import "framework/nav.scss";
|
||||
@import "framework/pagination.scss";
|
||||
@import "framework/progress.scss";
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
&.s46 { width: 46px; height: 46px; margin-right: 15px; }
|
||||
&.s48 { width: 48px; height: 48px; margin-right: 10px; }
|
||||
&.s60 { width: 60px; height: 60px; margin-right: 12px; }
|
||||
&.s70 { width: 70px; height: 70px; margin-right: 14px; }
|
||||
&.s90 { width: 90px; height: 90px; margin-right: 15px; }
|
||||
&.s110 { width: 110px; height: 110px; margin-right: 15px; }
|
||||
&.s140 { width: 140px; height: 140px; margin-right: 20px; }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.light-well {
|
||||
background-color: #f8fafc;
|
||||
background-color: $background-color;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
|||
line-height: 36px;
|
||||
}
|
||||
|
||||
.gray-content-block {
|
||||
.row-content-block {
|
||||
margin-top: 0;
|
||||
margin-bottom: -$gl-padding;
|
||||
background-color: $background-color;
|
||||
|
@ -81,6 +81,11 @@
|
|||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&.build-content {
|
||||
background-color: $white-light;
|
||||
border-top: none;
|
||||
}
|
||||
}
|
||||
|
||||
.cover-block {
|
||||
|
@ -113,7 +118,7 @@
|
|||
line-height: 1.1;
|
||||
|
||||
h1 {
|
||||
color: #313236;
|
||||
color: $gl-gray-dark;
|
||||
margin-bottom: 6px;
|
||||
font-size: 23px;
|
||||
}
|
||||
|
@ -150,6 +155,41 @@
|
|||
right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.groups-cover-block {
|
||||
background: $white-light;
|
||||
border-bottom: 1px solid $border-color;
|
||||
text-align: left;
|
||||
padding: 24px 0;
|
||||
|
||||
.group-info {
|
||||
.cover-title {
|
||||
margin-top: 9px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
text-align: center;
|
||||
|
||||
.avatar {
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-info {
|
||||
|
||||
h1 {
|
||||
display: inline;
|
||||
font-weight: normal;
|
||||
font-size: 24px;
|
||||
color: $gl-title-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.block-connector {
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
}
|
||||
|
||||
@mixin btn-gray {
|
||||
@include btn-color($gray-light, $border-gray-light, $gray-normal, $border-gray-light, $gray-dark, $border-gray-dark, #313236);
|
||||
@include btn-color($gray-light, $border-gray-light, $gray-normal, $border-gray-light, $gray-dark, $border-gray-dark, $gl-gray-dark);
|
||||
}
|
||||
|
||||
@mixin btn-white {
|
||||
|
@ -139,6 +139,10 @@
|
|||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
.caret {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
@ -247,3 +251,10 @@
|
|||
.btn-file-option {
|
||||
background: linear-gradient(180deg, $white-light 25%, $gray-light 100%);
|
||||
}
|
||||
|
||||
.btn-build {
|
||||
margin-left: 10px;
|
||||
i {
|
||||
color: $gl-icon-color;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,10 @@
|
|||
fill: #254e77 !important;
|
||||
}
|
||||
|
||||
.future {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.domain-background {
|
||||
fill: none;
|
||||
shape-rendering: crispedges;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
.prepend-top-10 { margin-top: 10px }
|
||||
.prepend-top-default { margin-top: $gl-padding !important; }
|
||||
.prepend-top-20 { margin-top: 20px }
|
||||
.prepend-left-5 { margin-left: 5px }
|
||||
.prepend-left-10 { margin-left: 10px }
|
||||
.prepend-left-default { margin-left: $gl-padding; }
|
||||
.prepend-left-20 { margin-left: 20px }
|
||||
|
@ -288,7 +289,7 @@ table {
|
|||
text-shadow: none;
|
||||
|
||||
@media (min-width: $screen-sm-min) {
|
||||
margin-top: 11px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
font-size: 15px;
|
||||
text-align: left;
|
||||
border: 1px solid $dropdown-toggle-border-color;
|
||||
border-radius: $dropdown-border-radius;
|
||||
border-radius: $border-radius-base;
|
||||
outline: 0;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
@ -80,7 +80,7 @@
|
|||
padding: 10px 0;
|
||||
background-color: $dropdown-bg;
|
||||
border: 1px solid $dropdown-border-color;
|
||||
border-radius: $dropdown-border-radius;
|
||||
border-radius: $border-radius-base;
|
||||
box-shadow: 0 2px 4px $dropdown-shadow-color;
|
||||
|
||||
&.is-loading {
|
||||
|
|
|
@ -84,10 +84,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.blob_file {
|
||||
|
||||
}
|
||||
|
||||
&.blob-no-preview {
|
||||
background: #eee;
|
||||
text-shadow: 0 1px 2px #fff;
|
||||
|
|
|
@ -78,6 +78,24 @@ label {
|
|||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.select-wrapper {
|
||||
position: relative;
|
||||
|
||||
.caret {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: $gl-padding;
|
||||
color: $gray-darkest;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.select-control {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.form-control-inline {
|
||||
display: inline;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
@mixin gitlab-theme($color-light, $color, $color-darker, $color-dark) {
|
||||
.page-with-sidebar {
|
||||
.header-logo {
|
||||
background-color: $color;
|
||||
border-color: $color;
|
||||
background: $color-darker;
|
||||
|
||||
a {
|
||||
color: $color-light;
|
||||
|
@ -21,9 +20,13 @@
|
|||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $color-darker;
|
||||
background-color: $color-dark;
|
||||
a {
|
||||
color: #fff;
|
||||
|
||||
h3 {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,8 +90,8 @@
|
|||
}
|
||||
|
||||
$theme-blue: #2980b9;
|
||||
$theme-charcoal: #333c47;
|
||||
$theme-graphite: #888;
|
||||
$theme-charcoal: #3d454d;
|
||||
$theme-graphite: #666;
|
||||
$theme-gray: #373737;
|
||||
$theme-green: #019875;
|
||||
$theme-violet: #548;
|
||||
|
@ -99,11 +102,11 @@ body {
|
|||
}
|
||||
|
||||
&.ui_charcoal {
|
||||
@include gitlab-theme(#c5d0de, $theme-charcoal, #2b333d, #24272d);
|
||||
@include gitlab-theme(#d6d7d9, #485157, $theme-charcoal, #353b41);
|
||||
}
|
||||
|
||||
&.ui_graphite {
|
||||
@include gitlab-theme(#ccc, $theme-graphite, #777, #666);
|
||||
@include gitlab-theme(#ccc, #777, $theme-graphite, #555);
|
||||
}
|
||||
|
||||
&.ui_gray {
|
||||
|
|
|
@ -6,12 +6,12 @@ header {
|
|||
transition-duration: .3s;
|
||||
|
||||
&.navbar-empty {
|
||||
height: 58px;
|
||||
height: $header-height;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid $btn-gray-hover;
|
||||
|
||||
.center-logo {
|
||||
margin: 11px 0;
|
||||
margin: 8px 0;
|
||||
text-align: center;
|
||||
|
||||
#tanuki-logo, img {
|
||||
|
@ -22,13 +22,21 @@ header {
|
|||
}
|
||||
|
||||
&.navbar-gitlab {
|
||||
padding: 0 20px;
|
||||
padding: 0 16px;
|
||||
z-index: 100;
|
||||
margin-bottom: 0;
|
||||
min-height: $header-height;
|
||||
background-color: #fff;
|
||||
height: $header-height;
|
||||
background-color: $background-color;
|
||||
border: none;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid $border-color;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
&.with-horizontal-nav {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
width: 100% !important;
|
||||
|
@ -47,7 +55,7 @@ header {
|
|||
text-align: center;
|
||||
|
||||
&:hover, &:focus, &:active {
|
||||
background-color: #fff;
|
||||
background-color: $background-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,16 +64,44 @@ header {
|
|||
margin: 6px 0;
|
||||
border-radius: 0;
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
right: -10px;
|
||||
padding: 6px 10px;
|
||||
|
||||
&:hover {
|
||||
background-color: #eee;
|
||||
background-color: $btn-gray-hover;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $gl-icon-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.header-collapsed {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.side-nav-toggle {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
margin: 6px 0;
|
||||
padding: 6px 10px;
|
||||
border: none;
|
||||
background-color: $background-color;
|
||||
|
||||
&:hover {
|
||||
background-color: $btn-gray-hover;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header-content {
|
||||
|
@ -73,6 +109,10 @@ header {
|
|||
height: $header-height;
|
||||
padding-right: 40px;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
@media (min-width: $screen-sm-min) {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
@ -141,6 +181,10 @@ header {
|
|||
@media (min-width: $screen-md-min) {
|
||||
@include collapsed-header;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.header-expanded {
|
||||
|
@ -149,6 +193,10 @@ header {
|
|||
@media (min-width: $screen-md-min) {
|
||||
margin-left: $sidebar_width;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
&.md-preview-holder {
|
||||
code {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
word-break: keep-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
}
|
||||
|
||||
.rss-btn {
|
||||
display: none !important;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.project-home-links {
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
.modal-body {
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
padding: 15px;
|
||||
|
||||
.form-actions {
|
||||
margin: -$gl-padding+1;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
body.modal-open {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modal .modal-dialog {
|
||||
width: 860px;
|
||||
}
|
|
@ -26,8 +26,8 @@
|
|||
}
|
||||
|
||||
&.active a {
|
||||
color: #000;
|
||||
border-bottom: 2px solid #4688f1;
|
||||
border-bottom: 2px solid $link-underline-blue;
|
||||
color: $black;
|
||||
}
|
||||
|
||||
.badge {
|
||||
|
@ -140,6 +140,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
.project-filter-form {
|
||||
input {
|
||||
background-color: $background-color;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
padding-bottom: 0;
|
||||
|
||||
|
@ -185,3 +191,92 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layout-nav {
|
||||
position: fixed;
|
||||
top: $header-height;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
background: $background-color;
|
||||
border-bottom: 1px solid $border-color;
|
||||
transition-duration: .3s;
|
||||
|
||||
.container-fluid {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.controls {
|
||||
float: right;
|
||||
padding: 7px 0 0;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
float: none;
|
||||
padding: 0 9px;
|
||||
|
||||
.dropdown-new {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
color: $layout-link-gray;
|
||||
}
|
||||
|
||||
.fa-rss,
|
||||
.fa-cog {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.fa-caret-down {
|
||||
margin-left: 5px;
|
||||
color: $gl-icon-color;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
margin-left: 7px;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
border-bottom: none;
|
||||
height: 51px;
|
||||
white-space: nowrap;
|
||||
overflow-x: auto;
|
||||
|
||||
li {
|
||||
|
||||
a {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
a, i {
|
||||
color: $layout-link-gray;
|
||||
}
|
||||
|
||||
&.active {
|
||||
a, i {
|
||||
color: $black;
|
||||
}
|
||||
}
|
||||
|
||||
.badge {
|
||||
color: $gl-icon-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.page-with-layout-nav {
|
||||
margin-top: 50px;
|
||||
|
||||
&.controls-dropdown-visible {
|
||||
@media (max-width: $screen-xs-min) {
|
||||
margin-top: 96px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,13 +7,11 @@
|
|||
.select2-choice {
|
||||
background: #fff;
|
||||
border-color: $input-border;
|
||||
border-color: $border-white-light;
|
||||
height: 35px;
|
||||
padding: $gl-vert-padding $gl-btn-padding;
|
||||
font-size: $gl-font-size;
|
||||
line-height: 1.42857143;
|
||||
|
||||
@include border-radius($border-radius-default);
|
||||
border-radius: $border-radius-base;
|
||||
|
||||
.select2-arrow {
|
||||
background-image: none;
|
||||
|
@ -121,9 +119,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices .select2-search-choice {
|
||||
}
|
||||
|
||||
.select2-drop-active {
|
||||
margin-top: 6px;
|
||||
font-size: 14px;
|
||||
|
@ -202,6 +197,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
.select2-highlighted {
|
||||
.group-result {
|
||||
.group-path {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-result {
|
||||
.group-image {
|
||||
float: left;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
position: absolute;
|
||||
width: 58px;
|
||||
cursor: pointer;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.page-with-sidebar {
|
||||
|
@ -62,7 +63,7 @@
|
|||
float: left;
|
||||
height: $header-height;
|
||||
width: 100%;
|
||||
padding: 11px 0 11px 22px;
|
||||
padding-left: 22px;
|
||||
overflow: hidden;
|
||||
outline: none;
|
||||
transition-duration: .3s;
|
||||
|
@ -85,7 +86,7 @@
|
|||
margin: 0;
|
||||
margin-left: 50px;
|
||||
font-size: 19px;
|
||||
line-height: 41px;
|
||||
line-height: 50px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +98,7 @@
|
|||
}
|
||||
|
||||
.sidebar-user {
|
||||
padding: 9px 22px;
|
||||
padding: 7px 22px;
|
||||
position: fixed;
|
||||
bottom: 40px;
|
||||
width: $sidebar_width;
|
||||
|
@ -209,15 +210,33 @@
|
|||
}
|
||||
}
|
||||
|
||||
.sidebar-wrapper {
|
||||
&.hidden-nav {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.page-sidebar-collapsed {
|
||||
padding-left: $sidebar_collapsed_width;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.sidebar-wrapper {
|
||||
width: $sidebar_collapsed_width;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: $sidebar_collapsed_width;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
padding-left: ($sidebar_collapsed_width - 36) / 2;
|
||||
|
||||
|
@ -243,17 +262,35 @@
|
|||
|
||||
.collapse-nav a {
|
||||
width: $sidebar_collapsed_width;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-user {
|
||||
padding-left: ($sidebar_collapsed_width - 36) / 2;
|
||||
width: $sidebar_collapsed_width;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
width: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.username {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layout-nav {
|
||||
padding-right: $sidebar_collapsed_width;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
padding-right: 0;;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-sidebar-expanded {
|
||||
|
@ -263,6 +300,10 @@
|
|||
padding-left: $sidebar_width;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.sidebar-wrapper {
|
||||
width: $sidebar_width;
|
||||
|
||||
|
@ -271,7 +312,7 @@
|
|||
}
|
||||
|
||||
.nav-sidebar li a {
|
||||
width: 230px;
|
||||
width: $sidebar_width;
|
||||
|
||||
&.back-link {
|
||||
i {
|
||||
|
@ -280,6 +321,20 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layout-nav {
|
||||
@media (max-width: $screen-xs-min) {
|
||||
padding-right: 0;;
|
||||
}
|
||||
|
||||
@media (min-width: $screen-xs-min) and (max-width: $screen-md-min) {
|
||||
padding-right: 62px;
|
||||
}
|
||||
|
||||
@media (min-width: $screen-md-min) {
|
||||
padding-right: $sidebar_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-sidebar-collapsed {
|
||||
|
|
|
@ -32,13 +32,11 @@ table {
|
|||
th {
|
||||
background-color: $background-color;
|
||||
font-weight: normal;
|
||||
font-size: 15px;
|
||||
border-bottom: 1px solid $border-color;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
td {
|
||||
border-color: $table-border-color;
|
||||
border-bottom: 1px solid $border-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
border-bottom: 1px solid $border-white-light;
|
||||
|
||||
&:target {
|
||||
background: $row-hover;
|
||||
background: $line-target-blue;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
|
||||
// Labels
|
||||
.label {
|
||||
padding: 2px 4px;
|
||||
padding: 4px 5px;
|
||||
font-size: 13px;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
|
|
|
@ -153,8 +153,8 @@ $nav-link-padding: 13px $gl-padding;
|
|||
//== Code
|
||||
//
|
||||
//##
|
||||
$pre-bg: #f8fafc !default;
|
||||
$pre-bg: $background-color !default;
|
||||
$pre-color: $gl-gray !default;
|
||||
$pre-border-color: #e7e9ed;
|
||||
$pre-border-color: $border-color;
|
||||
|
||||
$table-bg-accent: $background-color;
|
||||
|
|
|
@ -42,14 +42,14 @@
|
|||
margin: 24px 0 12px;
|
||||
padding: 0 0 10px;
|
||||
border-bottom: 1px solid #e7e9ed;
|
||||
color: #313236;
|
||||
color: $gl-gray-dark;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.2em;
|
||||
font-weight: 600;
|
||||
margin: 24px 0 12px;
|
||||
color: #313236;
|
||||
color: $gl-gray-dark;
|
||||
}
|
||||
|
||||
h3 {
|
||||
|
@ -205,6 +205,10 @@ h1, h2, h3, h4, h5, h6 {
|
|||
font-weight: 600;
|
||||
}
|
||||
|
||||
.light-header {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/** CODE **/
|
||||
pre {
|
||||
font-family: $monospace_font;
|
||||
|
@ -259,3 +263,9 @@ h1, h2, h3, h4 {
|
|||
color: $gl-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.text-right-lg {
|
||||
@media (min-width: $screen-lg-min) {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Layout
|
||||
*/
|
||||
$sidebar_collapsed_width: 62px;
|
||||
$sidebar_width: 230px;
|
||||
$sidebar_width: 220px;
|
||||
$gutter_collapsed_width: 62px;
|
||||
$gutter_width: 290px;
|
||||
$gutter_inner_width: 258px;
|
||||
|
@ -12,7 +12,7 @@ $gutter_inner_width: 258px;
|
|||
*/
|
||||
$border-color: #e5e5e5;
|
||||
$focus-border-color: #3aabf0;
|
||||
$table-border-color: #eef0f2;
|
||||
$table-border-color: #ececec;
|
||||
$background-color: #fafafa;
|
||||
|
||||
/*
|
||||
|
@ -20,7 +20,7 @@ $background-color: #fafafa;
|
|||
*/
|
||||
$gl-font-size: 15px;
|
||||
$gl-title-color: #333;
|
||||
$gl-text-color: #555;
|
||||
$gl-text-color: #5c5c5c;
|
||||
$gl-text-green: #4a2;
|
||||
$gl-text-red: #d12f19;
|
||||
$gl-text-orange: #d90;
|
||||
|
@ -30,6 +30,7 @@ $gl-placeholder-color: #8f8f8f;
|
|||
$gl-icon-color: $gl-placeholder-color;
|
||||
$gl-grayish-blue: #7f8fa4;
|
||||
$gl-gray: $gl-text-color;
|
||||
$gl-gray-dark: #313236;
|
||||
$gl-header-color: $gl-title-color;
|
||||
|
||||
/*
|
||||
|
@ -65,16 +66,18 @@ $gl-padding-top: 10px;
|
|||
$row-hover: #f4f8fe;
|
||||
$progress-color: #c0392b;
|
||||
$avatar_radius: 50%;
|
||||
$header-height: 58px;
|
||||
$header-height: 50px;
|
||||
$fixed-layout-width: 1280px;
|
||||
$gl-avatar-size: 40px;
|
||||
$error-exclamation-point: #e62958;
|
||||
$border-radius-default: 2px;
|
||||
$btn-transparent-color: #8f8f8f;
|
||||
$ssh-key-icon-color: #8f8f8f;
|
||||
$ssh-key-icon-size: 18px;
|
||||
$settings-icon-size: 18px;
|
||||
$provider-btn-group-border: #e5e5e5;
|
||||
$provider-btn-not-active-color: #4688f1;
|
||||
$link-underline-blue: #4a8bee;
|
||||
$layout-link-gray: #7e7c7c;
|
||||
$todo-alert-blue: #428bca;
|
||||
|
||||
/*
|
||||
* Color schema
|
||||
|
@ -109,6 +112,7 @@ $red-light: #e52c5a;
|
|||
$red-normal: #d22852;
|
||||
$red-dark: darken($red-normal, 5%);
|
||||
|
||||
$black: #000;
|
||||
$black-transparent: rgba(0, 0, 0, 0.3);
|
||||
|
||||
$border-white-light: #f1f2f4;
|
||||
|
@ -168,8 +172,12 @@ $line-removed: #fbe9eb;
|
|||
$line-removed-dark: #fac5cd;
|
||||
$line-number-old: #f9d7dc;
|
||||
$line-number-new: #ddfbe6;
|
||||
$line-number-select: #fbf2da;
|
||||
$match-line: #fafafa;
|
||||
$table-border-gray: #f0f0f0;
|
||||
$line-target-blue: #eaf3fc;
|
||||
$line-select-yellow: #fcf8e7;
|
||||
$line-select-yellow-dark: #f0e2bd;
|
||||
/*
|
||||
* Fonts
|
||||
*/
|
||||
|
@ -179,7 +187,6 @@ $regular_font: 'Source Sans Pro', "Helvetica Neue", Helvetica, Arial, sans-serif
|
|||
/*
|
||||
* Dropdowns
|
||||
*/
|
||||
$dropdown-border-radius: 2px;
|
||||
$dropdown-width: 300px;
|
||||
$dropdown-bg: #fff;
|
||||
$dropdown-link-color: #555;
|
||||
|
@ -208,6 +215,7 @@ $dropdown-toggle-hover-icon-color: $dropdown-toggle-hover-border-color;
|
|||
$btn-active-gray: #ececec;
|
||||
$btn-placeholder-gray: #c7c7c7;
|
||||
$btn-white-active: #848484;
|
||||
$btn-gray-hover: #eee;
|
||||
|
||||
/*
|
||||
* Award emoji
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.zen-cotrol {
|
||||
.zen-control {
|
||||
padding: 0;
|
||||
color: #555;
|
||||
background: none;
|
||||
|
|
|
@ -111,8 +111,6 @@
|
|||
.vg { color: #f8f8f2 } /* Name.Variable.Global */
|
||||
.vi { color: #f8f8f2 } /* Name.Variable.Instance */
|
||||
.il { color: #ae81ff } /* Literal.Number.Integer.Long */
|
||||
|
||||
.gh { } /* Generic Heading & Diff Header */
|
||||
.gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */
|
||||
.gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */
|
||||
.gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */
|
||||
|
|
|
@ -21,11 +21,6 @@
|
|||
|
||||
// Diff line
|
||||
.line_holder {
|
||||
td.diff-line-num.hll:not(.empty-cell),
|
||||
td.line_content.hll:not(.empty-cell) {
|
||||
background-color: #f8eec7;
|
||||
border-color: darken(#f8eec7, 15%);
|
||||
}
|
||||
|
||||
.diff-line-num {
|
||||
&.old {
|
||||
|
@ -37,11 +32,16 @@
|
|||
background-color: $line-number-new;
|
||||
border-color: $line-added-dark;
|
||||
}
|
||||
|
||||
&.hll:not(.empty-cell) {
|
||||
background-color: $line-number-select;
|
||||
border-color: $line-select-yellow-dark;
|
||||
}
|
||||
}
|
||||
|
||||
.line_content {
|
||||
&.old {
|
||||
background: $line-removed;
|
||||
background-color: $line-removed;
|
||||
|
||||
span.idiff {
|
||||
background-color: $line-removed-dark;
|
||||
|
@ -58,7 +58,11 @@
|
|||
|
||||
&.match {
|
||||
color: $black-transparent;
|
||||
background: $match-line;
|
||||
background-color: $match-line;
|
||||
}
|
||||
|
||||
&.hll:not(.empty-cell) {
|
||||
background-color: $line-select-yellow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,3 +83,12 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
table.builds {
|
||||
|
||||
.build-link {
|
||||
a {
|
||||
color: $gl-dark-link-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,9 +31,23 @@
|
|||
}
|
||||
.commit-committer-link,
|
||||
.commit-author-link {
|
||||
color: #444;
|
||||
color: $gl-gray;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.time_ago {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.fa-clipboard {
|
||||
color: $dropdown-title-btn-color;
|
||||
}
|
||||
|
||||
.commit-info {
|
||||
&.branches {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.commit-box {
|
||||
|
@ -42,7 +56,7 @@
|
|||
.commit-title {
|
||||
margin: 0;
|
||||
font-size: 23px;
|
||||
color: #313236;
|
||||
color: $gl-gray-dark;
|
||||
}
|
||||
|
||||
.commit-description {
|
||||
|
@ -83,6 +97,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
.commit-action-buttons {
|
||||
i {
|
||||
color: $gl-icon-color;
|
||||
font-size: 13px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Commit message textarea for web editor and
|
||||
* custom merge request message
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
.title {
|
||||
margin: 0;
|
||||
font-size: 23px;
|
||||
color: #313236;
|
||||
color: $gl-gray-dark;
|
||||
}
|
||||
|
||||
.description {
|
||||
|
@ -40,6 +40,7 @@
|
|||
.wiki {
|
||||
code {
|
||||
white-space: pre-wrap;
|
||||
word-break: keep-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,7 +98,11 @@
|
|||
}
|
||||
|
||||
td.line_content.parallel {
|
||||
width: 50%;
|
||||
width: 46%;
|
||||
}
|
||||
|
||||
.add-diff-note {
|
||||
margin-left: -65px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,8 +131,13 @@
|
|||
margin: 0;
|
||||
padding: 0 0.5em;
|
||||
border: none;
|
||||
|
||||
&.parallel {
|
||||
display: table-cell;
|
||||
|
||||
span {
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
}
|
||||
|
||||
.graphs {
|
||||
.graph-author-commits-count {
|
||||
}
|
||||
|
||||
.graph-author-email {
|
||||
float: right;
|
||||
color: #777;
|
||||
|
|
|
@ -55,25 +55,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
padding: 15px;
|
||||
|
||||
.form-actions {
|
||||
margin: -$gl-padding+1;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
body.modal-open {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modal .modal-dialog {
|
||||
width: 860px;
|
||||
}
|
||||
|
||||
.documentation {
|
||||
padding: 7px;
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
|
||||
.right-sidebar {
|
||||
position: fixed;
|
||||
top: 58px;
|
||||
top: $header-height;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
font-weight: 600;
|
||||
font-size: 17px;
|
||||
margin: 5px 0;
|
||||
color: #313236;
|
||||
color: $gl-gray-dark;
|
||||
}
|
||||
|
||||
p:last-child {
|
||||
|
@ -136,7 +136,7 @@
|
|||
}
|
||||
|
||||
.label-branch {
|
||||
color: #313236;
|
||||
color: $gl-gray-dark;
|
||||
font-family: $monospace_font;
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
|
@ -272,3 +272,19 @@
|
|||
display: inline-block;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.table-holder {
|
||||
.builds {
|
||||
|
||||
th {
|
||||
background-color: $white-light;
|
||||
color: $gl-placeholder-color;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ li.milestone {
|
|||
|
||||
// Issue title
|
||||
span a {
|
||||
color: rgba(0,0,0,0.64);
|
||||
color: $gl-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ li.milestone {
|
|||
margin-top: 7px;
|
||||
|
||||
.issuable-number {
|
||||
color: rgba(0,0,0,0.44);
|
||||
color: $gl-placeholder-color;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.avatar {
|
||||
|
|
|
@ -109,10 +109,10 @@ ul.notes {
|
|||
border-color: darken(#f5f5f5, 8%);
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
word-break: break-all;
|
||||
code {
|
||||
word-break: keep-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,11 @@ ul.notes {
|
|||
.notes {
|
||||
background-color: $white-light;
|
||||
}
|
||||
|
||||
a code {
|
||||
top: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +216,7 @@ ul.notes {
|
|||
}
|
||||
|
||||
.discussion-actions {
|
||||
@media (max-width: $screen-sm-max) {
|
||||
@media (max-width: $screen-md-max) {
|
||||
float: none;
|
||||
margin-left: 0;
|
||||
|
||||
|
@ -221,8 +226,7 @@ ul.notes {
|
|||
}
|
||||
}
|
||||
|
||||
.note-action-button,
|
||||
.discussion-action-button {
|
||||
.note-action-button {
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
line-height: 24px;
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
}
|
||||
|
||||
.account-btn-link,
|
||||
.profile-settings-sidebar a {
|
||||
.profile-settings-sidebar a,
|
||||
.settings-sidebar a {
|
||||
color: $md-link-color;
|
||||
}
|
||||
|
||||
|
@ -123,12 +124,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.key-icon {
|
||||
color: $ssh-key-icon-color;
|
||||
font-size: $ssh-key-icon-size;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
.key-created-at {
|
||||
line-height: 42px;
|
||||
}
|
||||
|
@ -180,14 +175,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.profile-settings-message {
|
||||
line-height: 32px;
|
||||
color: $warning-message-color;
|
||||
background-color: $warning-message-bg;
|
||||
border: 1px solid $warning-message-border;
|
||||
border-radius: $border-radius-base;
|
||||
}
|
||||
|
||||
.oauth-applications {
|
||||
form {
|
||||
display: inline-block;
|
||||
|
@ -218,3 +205,21 @@
|
|||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
@media (max-width: $screen-xs-max) {
|
||||
.cover-block {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.cover-controls {
|
||||
position: static;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
width: 46%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
}
|
||||
.no-ssh-key-message, .project-limit-message {
|
||||
background-color: #f28d35;
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.new_project,
|
||||
.edit_project {
|
||||
|
@ -178,7 +178,7 @@
|
|||
.option-title {
|
||||
font-weight: normal;
|
||||
display: inline-block;
|
||||
color: #313236;
|
||||
color: $gl-gray-dark;
|
||||
}
|
||||
|
||||
.option-descr {
|
||||
|
@ -202,8 +202,31 @@
|
|||
min-width: 200px;
|
||||
}
|
||||
|
||||
.deploy-project-label {
|
||||
margin: 1px;
|
||||
.deploy-key-content {
|
||||
@media (min-width: $screen-sm-min) {
|
||||
float: left;
|
||||
|
||||
&:last-child {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.deploy-key-projects {
|
||||
@media (min-width: $screen-sm-min) {
|
||||
line-height: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
a.deploy-project-label {
|
||||
padding: 5px;
|
||||
margin-right: 5px;
|
||||
color: $gl-gray;
|
||||
background-color: $row-hover;
|
||||
|
||||
&:hover {
|
||||
color: $gl-link-color;
|
||||
}
|
||||
}
|
||||
|
||||
.vs-public {
|
||||
|
@ -256,12 +279,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
table.table.protected-branches-list tr.no-border {
|
||||
th, td {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.project-import .btn {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
|
@ -474,3 +491,14 @@ pre.light-well {
|
|||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.protected-branches-list {
|
||||
a {
|
||||
color: $gl-gray;
|
||||
font-weight: 600;
|
||||
|
||||
&:hover {
|
||||
color: $gl-link-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,17 +10,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.search-holder {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 20px;
|
||||
|
||||
input {
|
||||
border-color: #bbb;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
margin-right: 10px;
|
||||
margin-left: 10px;
|
||||
|
@ -159,7 +148,85 @@
|
|||
|
||||
&.has-location-badge {
|
||||
.search-input-wrap {
|
||||
width: 78%;
|
||||
width: 68%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-holder {
|
||||
@media (min-width: $screen-sm-min) {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.search-field-holder {
|
||||
-webkit-flex: 1 0 auto;
|
||||
-ms-flex: 1 0 auto;
|
||||
flex: 1 0 auto;
|
||||
position: relative;
|
||||
margin-right: 0;
|
||||
|
||||
@media (min-width: $screen-sm-min) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 10px;
|
||||
color: $gray-darkest;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.search-text-input {
|
||||
padding-left: $gl-padding + 15px;
|
||||
padding-right: $gl-padding + 15px;
|
||||
}
|
||||
|
||||
.btn-search {
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
|
||||
@media (min-width: $screen-sm-min) {
|
||||
width: auto;
|
||||
margin-top: 0;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
@media (min-width: $screen-sm-min) {
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu-toggle {
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
|
||||
@media (min-width: $screen-sm-min) {
|
||||
width: 160px;
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-clear {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
padding: 0;
|
||||
color: $gray-darkest;
|
||||
line-height: 0;
|
||||
background: none;
|
||||
border: 0;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $gl-link-color;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
.settings-list-icon {
|
||||
color: $gl-placeholder-color;
|
||||
font-size: $settings-icon-size;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
.settings-message {
|
||||
padding: 5px;
|
||||
line-height: 1.3;
|
||||
color: $warning-message-color;
|
||||
background-color: $warning-message-bg;
|
||||
border: 1px solid $warning-message-border;
|
||||
border-radius: $border-radius-base;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
.container-fluid {
|
||||
.ci-status {
|
||||
padding: 2px 7px;
|
||||
margin-right: 5px;
|
||||
margin-right: 10px;
|
||||
border: 1px solid #eee;
|
||||
white-space: nowrap;
|
||||
@include border-radius(4px);
|
||||
|
|
|
@ -6,9 +6,16 @@
|
|||
.navbar-nav {
|
||||
li {
|
||||
.badge.todos-pending-count {
|
||||
background-color: $gl-icon-color;
|
||||
margin-top: -5px;
|
||||
font-weight: normal;
|
||||
background: $todo-alert-blue;
|
||||
margin-left: -17px;
|
||||
font-size: 11px;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
tr {
|
||||
> td, > th {
|
||||
line-height: 26px;
|
||||
line-height: 23px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
|
|
@ -9,6 +9,6 @@ class Admin::AbuseReportsController < Admin::ApplicationController
|
|||
abuse_report.remove_user(deleted_by: current_user) if params[:remove_user]
|
||||
abuse_report.destroy
|
||||
|
||||
render nothing: true
|
||||
head :ok
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,12 +6,6 @@ class Admin::ApplicationController < ApplicationController
|
|||
layout 'admin'
|
||||
|
||||
def authenticate_admin!
|
||||
return render_404 unless current_user.is_admin?
|
||||
end
|
||||
|
||||
def authorize_impersonator!
|
||||
if session[:impersonator_id]
|
||||
User.find_by!(username: session[:impersonator_id]).admin?
|
||||
end
|
||||
render_404 unless current_user.is_admin?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,6 +19,12 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
|||
redirect_to admin_runners_path
|
||||
end
|
||||
|
||||
def reset_health_check_token
|
||||
@application_setting.reset_health_check_access_token!
|
||||
flash[:notice] = 'New health check access token has been generated!'
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
def clear_repository_check_states
|
||||
RepositoryCheck::ClearWorker.perform_async
|
||||
|
||||
|
@ -53,6 +59,12 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
enabled_oauth_sign_in_sources = params[:application_setting].delete(:enabled_oauth_sign_in_sources)
|
||||
|
||||
params[:application_setting][:disabled_oauth_sign_in_sources] =
|
||||
AuthHelper.button_based_providers.map(&:to_s) -
|
||||
Array(enabled_oauth_sign_in_sources)
|
||||
|
||||
params.require(:application_setting).permit(
|
||||
:default_projects_limit,
|
||||
:default_branch_protection,
|
||||
|
@ -94,8 +106,10 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
|||
:email_author_in_body,
|
||||
:repository_checks_enabled,
|
||||
:metrics_packet_size,
|
||||
:send_user_confirmation_email,
|
||||
restricted_visibility_levels: [],
|
||||
import_sources: []
|
||||
import_sources: [],
|
||||
disabled_oauth_sign_in_sources: []
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,7 +32,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html { redirect_back_or_default(default: { action: 'index' }) }
|
||||
format.js { render nothing: true }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class Admin::HealthCheckController < Admin::ApplicationController
|
||||
def show
|
||||
@errors = HealthCheck::Utils.process_checks('standard')
|
||||
end
|
||||
end
|
|
@ -39,6 +39,12 @@ class Admin::HooksController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def hook_params
|
||||
params.require(:hook).permit(:url, :enable_ssl_verification, :push_events, :tag_push_events)
|
||||
params.require(:hook).permit(
|
||||
:enable_ssl_verification,
|
||||
:push_events,
|
||||
:tag_push_events,
|
||||
:token,
|
||||
:url
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
class Admin::ImpersonationController < Admin::ApplicationController
|
||||
skip_before_action :authenticate_admin!, only: :destroy
|
||||
|
||||
before_action :user
|
||||
before_action :authorize_impersonator!
|
||||
|
||||
def create
|
||||
if @user.blocked?
|
||||
flash[:alert] = "You cannot impersonate a blocked user"
|
||||
|
||||
redirect_to admin_user_path(@user)
|
||||
else
|
||||
session[:impersonator_id] = current_user.username
|
||||
session[:impersonator_return_to] = admin_user_path(@user)
|
||||
|
||||
warden.set_user(user, scope: 'user')
|
||||
|
||||
flash[:alert] = "You are impersonating #{user.username}."
|
||||
|
||||
redirect_to root_path
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
redirect = session[:impersonator_return_to]
|
||||
|
||||
warden.set_user(user, scope: 'user')
|
||||
|
||||
session[:impersonator_return_to] = nil
|
||||
session[:impersonator_id] = nil
|
||||
|
||||
redirect_to redirect || root_path
|
||||
end
|
||||
|
||||
def user
|
||||
@user ||= User.find_by!(username: params[:id] || session[:impersonator_id])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
class Admin::ImpersonationsController < Admin::ApplicationController
|
||||
skip_before_action :authenticate_admin!
|
||||
before_action :authenticate_impersonator!
|
||||
|
||||
def destroy
|
||||
original_user = current_user
|
||||
|
||||
warden.set_user(impersonator, scope: :user)
|
||||
|
||||
Gitlab::AppLogger.info("User #{original_user.username} has stopped impersonating #{impersonator.username}")
|
||||
|
||||
session[:impersonator_id] = nil
|
||||
|
||||
redirect_to admin_user_path(original_user)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def impersonator
|
||||
@impersonator ||= User.find(session[:impersonator_id]) if session[:impersonator_id]
|
||||
end
|
||||
|
||||
def authenticate_impersonator!
|
||||
render_404 unless impersonator && impersonator.is_admin? && !impersonator.blocked?
|
||||
end
|
||||
end
|
|
@ -6,7 +6,7 @@ class Admin::KeysController < Admin::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.js { render nothing: true }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -58,6 +58,6 @@ class Admin::RunnersController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def runner_params
|
||||
params.require(:runner).permit(:token, :description, :tag_list, :active)
|
||||
params.require(:runner).permit(Ci::Runner::FORM_EDITABLE)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@ class Admin::SpamLogsController < Admin::ApplicationController
|
|||
redirect_to admin_spam_logs_path, notice: "User #{spam_log.user.username} was successfully removed."
|
||||
else
|
||||
spam_log.destroy
|
||||
render nothing: true
|
||||
head :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,6 +31,24 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
user
|
||||
end
|
||||
|
||||
def impersonate
|
||||
if user.blocked?
|
||||
flash[:alert] = "You cannot impersonate a blocked user"
|
||||
|
||||
redirect_to admin_user_path(user)
|
||||
else
|
||||
session[:impersonator_id] = current_user.id
|
||||
|
||||
warden.set_user(user, scope: :user)
|
||||
|
||||
Gitlab::AppLogger.info("User #{current_user.username} has started impersonating #{user.username}")
|
||||
|
||||
flash[:alert] = "You are now impersonating #{user.username}"
|
||||
|
||||
redirect_to root_path
|
||||
end
|
||||
end
|
||||
|
||||
def block
|
||||
if user.block
|
||||
redirect_back_or_admin_user(notice: "Successfully blocked")
|
||||
|
@ -101,6 +119,7 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
user_params_with_pass.merge!(
|
||||
password: params[:user][:password],
|
||||
password_confirmation: params[:user][:password_confirmation],
|
||||
password_expires_at: Time.now
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -135,7 +154,7 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html { redirect_back_or_admin_user(notice: "Successfully removed email.") }
|
||||
format.js { render nothing: true }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def after_sign_out_path_for(resource)
|
||||
current_application_settings.after_sign_out_path || new_user_session_path
|
||||
current_application_settings.after_sign_out_path.presence || new_user_session_path
|
||||
end
|
||||
|
||||
def abilities
|
||||
|
|
|
@ -6,7 +6,7 @@ module ToggleSubscriptionAction
|
|||
|
||||
subscribable_resource.toggle_subscription(current_user)
|
||||
|
||||
render nothing: true
|
||||
head :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class Dashboard::LabelsController < Dashboard::ApplicationController
|
||||
def index
|
||||
labels = Label.where(project_id: projects).select(:title, :color).uniq(:title)
|
||||
labels = Label.where(project_id: projects).select(:id, :title, :color).uniq(:title)
|
||||
|
||||
respond_to do |format|
|
||||
format.json { render json: labels }
|
||||
|
|
|
@ -28,7 +28,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
|
|||
end
|
||||
|
||||
def starred
|
||||
@projects = current_user.starred_projects.sorted_by_activity
|
||||
@projects = current_user.viewable_starred_projects.sorted_by_activity
|
||||
@projects = filter_projects(@projects)
|
||||
@projects = @projects.includes(:namespace, :forked_from_project, :tags)
|
||||
@projects = @projects.sort(@sort = params[:sort])
|
||||
|
|
|
@ -12,7 +12,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to dashboard_todos_path, notice: todo_notice }
|
||||
format.js { render nothing: true }
|
||||
format.js { head :ok }
|
||||
format.json do
|
||||
render json: { count: @todos.size, done_count: current_user.todos.done.count }
|
||||
end
|
||||
|
@ -24,7 +24,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 { render nothing: true }
|
||||
format.js { head :ok }
|
||||
format.json do
|
||||
find_todos
|
||||
render json: { count: @todos.size, done_count: current_user.todos.done.count }
|
||||
|
|
|
@ -25,7 +25,7 @@ class DashboardController < Dashboard::ApplicationController
|
|||
def load_events
|
||||
projects =
|
||||
if params[:filter] == "starred"
|
||||
current_user.starred_projects
|
||||
current_user.viewable_starred_projects
|
||||
else
|
||||
current_user.authorized_projects
|
||||
end
|
||||
|
|
|
@ -40,7 +40,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to group_group_members_path(@group), notice: 'User was successfully removed from group.' }
|
||||
format.js { render nothing: true }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
class HealthCheckController < HealthCheck::HealthCheckController
|
||||
before_action :validate_health_check_access!
|
||||
|
||||
private
|
||||
|
||||
def validate_health_check_access!
|
||||
render_404 unless token_valid?
|
||||
end
|
||||
|
||||
def token_valid?
|
||||
token = params[:token].presence || request.headers['TOKEN']
|
||||
token.present? &&
|
||||
ActiveSupport::SecurityUtils.variable_size_secure_compare(
|
||||
token,
|
||||
current_application_settings.health_check_access_token
|
||||
)
|
||||
end
|
||||
|
||||
def render_404
|
||||
render file: Rails.root.join('public', '404'), layout: false, status: '404'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,87 @@
|
|||
class JwtController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
skip_before_action :verify_authenticity_token
|
||||
before_action :authenticate_project_or_user
|
||||
|
||||
SERVICES = {
|
||||
Auth::ContainerRegistryAuthenticationService::AUDIENCE => Auth::ContainerRegistryAuthenticationService,
|
||||
}
|
||||
|
||||
def auth
|
||||
service = SERVICES[params[:service]]
|
||||
return head :not_found unless service
|
||||
|
||||
result = service.new(@project, @user, auth_params).execute
|
||||
|
||||
render json: result, status: result[:http_status]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authenticate_project_or_user
|
||||
authenticate_with_http_basic do |login, password|
|
||||
# if it's possible we first try to authenticate project with login and password
|
||||
@project = authenticate_project(login, password)
|
||||
return if @project
|
||||
|
||||
@user = authenticate_user(login, password)
|
||||
return if @user
|
||||
|
||||
render_403
|
||||
end
|
||||
end
|
||||
|
||||
def auth_params
|
||||
params.permit(:service, :scope, :offline_token, :account, :client_id)
|
||||
end
|
||||
|
||||
def authenticate_project(login, password)
|
||||
if login == 'gitlab_ci_token'
|
||||
Project.find_by(builds_enabled: true, runners_token: password)
|
||||
end
|
||||
end
|
||||
|
||||
def authenticate_user(login, password)
|
||||
# TODO: this is a copy and paste from grack_auth,
|
||||
# it should be refactored in the future
|
||||
|
||||
user = Gitlab::Auth.new.find(login, password)
|
||||
|
||||
# If the user authenticated successfully, we reset the auth failure count
|
||||
# from Rack::Attack for that IP. A client may attempt to authenticate
|
||||
# with a username and blank password first, and only after it receives
|
||||
# a 401 error does it present a password. Resetting the count prevents
|
||||
# false positives from occurring.
|
||||
#
|
||||
# Otherwise, we let Rack::Attack know there was a failed authentication
|
||||
# attempt from this IP. This information is stored in the Rails cache
|
||||
# (Redis) and will be used by the Rack::Attack middleware to decide
|
||||
# whether to block requests from this IP.
|
||||
config = Gitlab.config.rack_attack.git_basic_auth
|
||||
|
||||
if config.enabled
|
||||
if user
|
||||
# A successful login will reset the auth failure count from this IP
|
||||
Rack::Attack::Allow2Ban.reset(request.ip, config)
|
||||
else
|
||||
banned = Rack::Attack::Allow2Ban.filter(request.ip, config) do
|
||||
# Unless the IP is whitelisted, return true so that Allow2Ban
|
||||
# increments the counter (stored in Rails.cache) for the IP
|
||||
if config.ip_whitelist.include?(request.ip)
|
||||
false
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
if banned
|
||||
Rails.logger.info "IP #{request.ip} failed to login " \
|
||||
"as #{login} but has been temporarily banned from Git auth"
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
user
|
||||
end
|
||||
end
|
|
@ -24,7 +24,7 @@ class Profiles::EmailsController < Profiles::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to profile_emails_url }
|
||||
format.js { render nothing: true }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class Profiles::KeysController < Profiles::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to profile_keys_url }
|
||||
format.js { render nothing: true }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -38,6 +38,14 @@ class Projects::BuildsController < Projects::ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def trace
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: @build.trace_with_state(params[:state]).merge!(id: @build.id, status: @build.status)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def retry
|
||||
unless @build.retryable?
|
||||
return render_404
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue