Commit a66986c0 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge remote-tracking branch 'ce-com/master' into ce-to-ee

Signed-off-by: default avatarDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
parents f9e833c4 aaf37ead
...@@ -46,6 +46,7 @@ eslint-report.html ...@@ -46,6 +46,7 @@ eslint-report.html
/public/uploads.* /public/uploads.*
/public/uploads/ /public/uploads/
/shared/artifacts/ /shared/artifacts/
/spec/javascripts/fixtures/blob/pdf/
/rails_best_practices_output.html /rails_best_practices_output.html
/tags /tags
/tmp/* /tmp/*
......
...@@ -22,8 +22,8 @@ variables: ...@@ -22,8 +22,8 @@ variables:
before_script: before_script:
- bundle --version - bundle --version
- . scripts/utils.sh - source scripts/utils.sh
- ./scripts/prepare_build.sh - source scripts/prepare_build.sh
stages: stages:
- prepare - prepare
...@@ -268,20 +268,21 @@ spinach mysql 9 10: *spinach-knapsack-mysql ...@@ -268,20 +268,21 @@ spinach mysql 9 10: *spinach-knapsack-mysql
SETUP_DB: "false" SETUP_DB: "false"
USE_BUNDLE_INSTALL: "true" USE_BUNDLE_INSTALL: "true"
.exec: &exec .rake-exec: &rake-exec
<<: *ruby-static-analysis <<: *ruby-static-analysis
<<: *dedicated-runner <<: *dedicated-runner
<<: *except-docs <<: *except-docs
stage: test stage: test
script: script:
- bundle exec $CI_JOB_NAME - bundle exec rake $CI_JOB_NAME
rubocop: static-analysis:
<<: *ruby-static-analysis <<: *ruby-static-analysis
<<: *dedicated-runner <<: *dedicated-runner
<<: *except-docs <<: *except-docs
stage: test stage: test
script: script:
<<<<<<< HEAD
- bundle exec "rubocop --require rubocop-rspec" - bundle exec "rubocop --require rubocop-rspec"
rake haml_lint: *exec rake haml_lint: *exec
...@@ -291,6 +292,37 @@ rake brakeman: *exec ...@@ -291,6 +292,37 @@ rake brakeman: *exec
rake flay: *exec rake flay: *exec
license_finder: *exec license_finder: *exec
rake downtime_check: *exec rake downtime_check: *exec
=======
- scripts/static-analysis
downtime_check:
<<: *rake-exec
except:
- master
- tags
- /^[\d-]+-stable(-ee)?$/
- /^docs\/*/
ee_compat_check:
<<: *rake-exec
only:
- branches@gitlab-org/gitlab-ce
except:
- master
- tags
- /^[\d-]+-stable(-ee)?$/
allow_failure: yes
cache:
key: "ee_compat_check_repo"
paths:
- ee_compat_check/ee-repo/
artifacts:
name: "${CI_JOB_NAME}_${CI_COMIT_REF_NAME}_${CI_COMMIT_SHA}"
when: on_failure
expire_in: 10d
paths:
- ee_compat_check/patches/*.patch
>>>>>>> ce-com/master
.db-migrate-reset: &db-migrate-reset .db-migrate-reset: &db-migrate-reset
stage: test stage: test
...@@ -298,12 +330,12 @@ rake downtime_check: *exec ...@@ -298,12 +330,12 @@ rake downtime_check: *exec
script: script:
- bundle exec rake db:migrate:reset - bundle exec rake db:migrate:reset
rake pg db:migrate:reset: db:migrate:reset pg:
<<: *db-migrate-reset <<: *db-migrate-reset
<<: *use-pg <<: *use-pg
<<: *except-docs <<: *except-docs
rake mysql db:migrate:reset: db:migrate:reset mysql:
<<: *db-migrate-reset <<: *db-migrate-reset
<<: *use-mysql <<: *use-mysql
<<: *except-docs <<: *except-docs
...@@ -315,12 +347,12 @@ rake mysql db:migrate:reset: ...@@ -315,12 +347,12 @@ rake mysql db:migrate:reset:
- bundle exec rake db:rollback STEP=120 - bundle exec rake db:rollback STEP=120
- bundle exec rake db:migrate - bundle exec rake db:migrate
rake pg db:rollback: db:rollback pg:
<<: *db-rollback <<: *db-rollback
<<: *use-pg <<: *use-pg
<<: *except-docs <<: *except-docs
rake mysql db:rollback: db:rollback mysql:
<<: *db-rollback <<: *db-rollback
<<: *use-mysql <<: *use-mysql
<<: *except-docs <<: *except-docs
...@@ -342,17 +374,17 @@ rake mysql db:rollback: ...@@ -342,17 +374,17 @@ rake mysql db:rollback:
paths: paths:
- log/development.log - log/development.log
rake pg db:seed_fu: db:seed_fu pg:
<<: *db-seed_fu <<: *db-seed_fu
<<: *use-pg <<: *use-pg
<<: *except-docs <<: *except-docs
rake mysql db:seed_fu: db:seed_fu mysql:
<<: *db-seed_fu <<: *db-seed_fu
<<: *use-mysql <<: *use-mysql
<<: *except-docs <<: *except-docs
rake gitlab:assets:compile: gitlab:assets:compile:
stage: test stage: test
<<: *dedicated-runner <<: *dedicated-runner
<<: *except-docs <<: *except-docs
...@@ -372,7 +404,7 @@ rake gitlab:assets:compile: ...@@ -372,7 +404,7 @@ rake gitlab:assets:compile:
paths: paths:
- webpack-report/ - webpack-report/
rake karma: karma:
cache: cache:
paths: paths:
- vendor/ruby - vendor/ruby
...@@ -391,16 +423,6 @@ rake karma: ...@@ -391,16 +423,6 @@ rake karma:
paths: paths:
- coverage-javascript/ - coverage-javascript/
docs:check:apilint:
image: "phusion/baseimage"
stage: test
<<: *dedicated-runner
cache: {}
dependencies: []
before_script: []
script:
- scripts/lint-doc.sh
docs:check:links: docs:check:links:
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:nanoc-bootstrap-ruby-2.4-alpine" image: "registry.gitlab.com/gitlab-org/gitlab-build-images:nanoc-bootstrap-ruby-2.4-alpine"
stage: test stage: test
...@@ -416,6 +438,7 @@ docs:check:links: ...@@ -416,6 +438,7 @@ docs:check:links:
# Check the internal links # Check the internal links
- bundle exec nanoc check internal_links - bundle exec nanoc check internal_links
<<<<<<< HEAD
bundler:check: bundler:check:
stage: test stage: test
<<: *dedicated-runner <<: *dedicated-runner
...@@ -424,6 +447,8 @@ bundler:check: ...@@ -424,6 +447,8 @@ bundler:check:
script: script:
- bundle check - bundle check
=======
>>>>>>> ce-com/master
bundler:audit: bundler:audit:
stage: test stage: test
<<: *ruby-static-analysis <<: *ruby-static-analysis
...@@ -456,11 +481,11 @@ bundler:audit: ...@@ -456,11 +481,11 @@ bundler:audit:
- . scripts/prepare_build.sh - . scripts/prepare_build.sh
- bundle exec rake db:migrate - bundle exec rake db:migrate
migration pg paths: migration path pg:
<<: *migration-paths <<: *migration-paths
<<: *use-pg <<: *use-pg
migration mysql paths: migration path mysql:
<<: *migration-paths <<: *migration-paths
<<: *use-mysql <<: *use-mysql
...@@ -482,6 +507,7 @@ coverage: ...@@ -482,6 +507,7 @@ coverage:
- coverage/index.html - coverage/index.html
- coverage/assets/ - coverage/assets/
<<<<<<< HEAD
lint:javascript: lint:javascript:
<<: *dedicated-runner <<: *dedicated-runner
<<: *except-docs <<: *except-docs
...@@ -490,6 +516,8 @@ lint:javascript: ...@@ -490,6 +516,8 @@ lint:javascript:
script: script:
- yarn run eslint - yarn run eslint
=======
>>>>>>> ce-com/master
lint:javascript:report: lint:javascript:report:
<<: *dedicated-runner <<: *dedicated-runner
<<: *except-docs <<: *except-docs
...@@ -544,8 +572,8 @@ pages: ...@@ -544,8 +572,8 @@ pages:
<<: *dedicated-runner <<: *dedicated-runner
dependencies: dependencies:
- coverage - coverage
- rake karma - karma
- rake gitlab:assets:compile - gitlab:assets:compile
- lint:javascript:report - lint:javascript:report
script: script:
- mv public/ .public/ - mv public/ .public/
......
Please read this!
Before opening a new issue, make sure to search for keywords in the issues
filtered by the "regression" or "bug" label:
- https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=regression
- https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=bug
and verify the issue you're about to submit isn't a duplicate.
Please remove this notice if you're confident your issue isn't a duplicate.
------
### Summary ### Summary
(Summarize the bug encountered concisely) (Summarize the bug encountered concisely)
...@@ -56,3 +70,5 @@ logs, and code as it's very hard to read otherwise.) ...@@ -56,3 +70,5 @@ logs, and code as it's very hard to read otherwise.)
### Possible fixes ### Possible fixes
(If you can, link to the line of code that might be responsible for the problem) (If you can, link to the line of code that might be responsible for the problem)
/label ~bug
Please read this!
Before opening a new issue, make sure to search for keywords in the issues
filtered by the "feature proposal" label:
- https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=feature+proposal
and verify the issue you're about to submit isn't a duplicate.
Please remove this notice if you're confident your issue isn't a duplicate.
------
### Description ### Description
(Include problem, use cases, benefits, and/or goals) (Include problem, use cases, benefits, and/or goals)
...@@ -15,3 +28,5 @@ ...@@ -15,3 +28,5 @@
3. How does someone use this 3. How does someone use this
During implementation, this can then be copied and used as a starter for the documentation.) During implementation, this can then be copied and used as a starter for the documentation.)
/label ~"feature proposal"
...@@ -4,9 +4,12 @@ entry. ...@@ -4,9 +4,12 @@ entry.
## 9.1.2 (2017-05-01) ## 9.1.2 (2017-05-01)
<<<<<<< HEAD
- No changes. - No changes.
- No changes. - No changes.
- No changes. - No changes.
=======
>>>>>>> ce-com/master
- Add index on ci_runners.contacted_at. !10876 (blackst0ne) - Add index on ci_runners.contacted_at. !10876 (blackst0ne)
- Fix pipeline events description for Slack and Mattermost integration. !10908 - Fix pipeline events description for Slack and Mattermost integration. !10908
- Fixed milestone sidebar showing incorrect number of MRs when collapsed. !10933 - Fixed milestone sidebar showing incorrect number of MRs when collapsed. !10933
......
...@@ -87,14 +87,14 @@ gem 'kaminari', '~> 0.17.0' ...@@ -87,14 +87,14 @@ gem 'kaminari', '~> 0.17.0'
gem 'hamlit', '~> 2.6.1' gem 'hamlit', '~> 2.6.1'
# Files attachments # Files attachments
gem 'carrierwave', '~> 0.11.0' gem 'carrierwave', '~> 1.0'
# Drag and Drop UI # Drag and Drop UI
gem 'dropzonejs-rails', '~> 0.7.1' gem 'dropzonejs-rails', '~> 0.7.1'
# for backups # for backups
gem 'fog-aws', '~> 0.9' gem 'fog-aws', '~> 0.9'
gem 'fog-core', '~> 1.40' gem 'fog-core', '~> 1.44'
gem 'fog-google', '~> 0.5' gem 'fog-google', '~> 0.5'
gem 'fog-local', '~> 0.3' gem 'fog-local', '~> 0.3'
gem 'fog-openstack', '~> 0.1' gem 'fog-openstack', '~> 0.1'
......
...@@ -113,12 +113,10 @@ GEM ...@@ -113,12 +113,10 @@ GEM
capybara-screenshot (1.0.14) capybara-screenshot (1.0.14)
capybara (>= 1.0, < 3) capybara (>= 1.0, < 3)
launchy launchy
carrierwave (0.11.2) carrierwave (1.0.0)
activemodel (>= 3.2.0) activemodel (>= 4.0.0)
activesupport (>= 3.2.0) activesupport (>= 4.0.0)
json (>= 1.7)
mime-types (>= 1.16) mime-types (>= 1.16)
mimemagic (>= 0.3.0)
cause (0.1) cause (0.1)
charlock_holmes (0.7.3) charlock_holmes (0.7.3)
chronic (0.10.2) chronic (0.10.2)
...@@ -205,7 +203,7 @@ GEM ...@@ -205,7 +203,7 @@ GEM
erubis (2.7.0) erubis (2.7.0)
escape_utils (1.1.1) escape_utils (1.1.1)
eventmachine (1.0.8) eventmachine (1.0.8)
excon (0.52.0) excon (0.55.0)
execjs (2.6.0) execjs (2.6.0)
expression_parser (0.9.0) expression_parser (0.9.0)
extlib (0.9.16) extlib (0.9.16)
...@@ -234,12 +232,12 @@ GEM ...@@ -234,12 +232,12 @@ GEM
flowdock (0.7.1) flowdock (0.7.1)
httparty (~> 0.7) httparty (~> 0.7)
multi_json multi_json
fog-aws (0.11.0) fog-aws (0.13.0)
fog-core (~> 1.38) fog-core (~> 1.38)
fog-json (~> 1.0) fog-json (~> 1.0)
fog-xml (~> 0.1) fog-xml (~> 0.1)
ipaddress (~> 0.8) ipaddress (~> 0.8)
fog-core (1.42.0) fog-core (1.44.1)
builder builder
excon (~> 0.49) excon (~> 0.49)
formatador (~> 0.2) formatador (~> 0.2)
...@@ -261,9 +259,9 @@ GEM ...@@ -261,9 +259,9 @@ GEM
fog-json (>= 1.0) fog-json (>= 1.0)
fog-xml (>= 0.1) fog-xml (>= 0.1)
ipaddress (>= 0.8) ipaddress (>= 0.8)
fog-xml (0.1.2) fog-xml (0.1.3)
fog-core fog-core
nokogiri (~> 1.5, >= 1.5.11) nokogiri (>= 1.5.11, < 2.0.0)
font-awesome-rails (4.7.0.1) font-awesome-rails (4.7.0.1)
railties (>= 3.2, < 5.1) railties (>= 3.2, < 5.1)
foreman (0.78.0) foreman (0.78.0)
...@@ -363,7 +361,7 @@ GEM ...@@ -363,7 +361,7 @@ GEM
grape-entity (0.6.0) grape-entity (0.6.0)
activesupport activesupport
multi_json (>= 1.3.2) multi_json (>= 1.3.2)
grpc (1.1.2) grpc (1.2.5)
google-protobuf (~> 3.1) google-protobuf (~> 3.1)
googleauth (~> 0.5.1) googleauth (~> 0.5.1)
gssapi (1.2.0) gssapi (1.2.0)
...@@ -908,7 +906,7 @@ DEPENDENCIES ...@@ -908,7 +906,7 @@ DEPENDENCIES
bundler-audit (~> 0.5.0) bundler-audit (~> 0.5.0)
capybara (~> 2.6.2) capybara (~> 2.6.2)
capybara-screenshot (~> 1.0.0) capybara-screenshot (~> 1.0.0)
carrierwave (~> 0.11.0) carrierwave (~> 1.0)
charlock_holmes (~> 0.7.3) charlock_holmes (~> 0.7.3)
chronic (~> 0.10.2) chronic (~> 0.10.2)
chronic_duration (~> 0.10.6) chronic_duration (~> 0.10.6)
...@@ -937,7 +935,7 @@ DEPENDENCIES ...@@ -937,7 +935,7 @@ DEPENDENCIES
ffaker (~> 2.4) ffaker (~> 2.4)
flay (~> 2.8.0) flay (~> 2.8.0)
fog-aws (~> 0.9) fog-aws (~> 0.9)
fog-core (~> 1.40) fog-core (~> 1.44)
fog-google (~> 0.5) fog-google (~> 0.5)
fog-local (~> 0.3) fog-local (~> 0.3)
fog-openstack (~> 0.1) fog-openstack (~> 0.1)
......
app/assets/images/ci_favicons/favicon_status_canceled.ico

5.3 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_canceled.ico

4.19 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_canceled.ico
app/assets/images/ci_favicons/favicon_status_canceled.ico
app/assets/images/ci_favicons/favicon_status_canceled.ico
app/assets/images/ci_favicons/favicon_status_canceled.ico
  • 2-up
  • Swipe
  • Onion skin
app/assets/images/ci_favicons/favicon_status_created.ico

5.3 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_created.ico

4.19 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_created.ico
app/assets/images/ci_favicons/favicon_status_created.ico
app/assets/images/ci_favicons/favicon_status_created.ico
app/assets/images/ci_favicons/favicon_status_created.ico
  • 2-up
  • Swipe
  • Onion skin
app/assets/images/ci_favicons/favicon_status_failed.ico

5.3 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_failed.ico

4.19 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_failed.ico
app/assets/images/ci_favicons/favicon_status_failed.ico
app/assets/images/ci_favicons/favicon_status_failed.ico
app/assets/images/ci_favicons/favicon_status_failed.ico
  • 2-up
  • Swipe
  • Onion skin
app/assets/images/ci_favicons/favicon_status_manual.ico

5.3 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_manual.ico

4.19 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_manual.ico
app/assets/images/ci_favicons/favicon_status_manual.ico
app/assets/images/ci_favicons/favicon_status_manual.ico
app/assets/images/ci_favicons/favicon_status_manual.ico
  • 2-up
  • Swipe
  • Onion skin
app/assets/images/ci_favicons/favicon_status_not_found.ico

5.3 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_not_found.ico

4.19 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_not_found.ico
app/assets/images/ci_favicons/favicon_status_not_found.ico
app/assets/images/ci_favicons/favicon_status_not_found.ico
app/assets/images/ci_favicons/favicon_status_not_found.ico
  • 2-up
  • Swipe
  • Onion skin
app/assets/images/ci_favicons/favicon_status_pending.ico

5.3 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_pending.ico

4.19 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_pending.ico
app/assets/images/ci_favicons/favicon_status_pending.ico
app/assets/images/ci_favicons/favicon_status_pending.ico
app/assets/images/ci_favicons/favicon_status_pending.ico
  • 2-up
  • Swipe
  • Onion skin
app/assets/images/ci_favicons/favicon_status_running.ico

5.3 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_running.ico

4.19 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_running.ico
app/assets/images/ci_favicons/favicon_status_running.ico
app/assets/images/ci_favicons/favicon_status_running.ico
app/assets/images/ci_favicons/favicon_status_running.ico
  • 2-up
  • Swipe
  • Onion skin
app/assets/images/ci_favicons/favicon_status_skipped.ico

5.3 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_skipped.ico

4.19 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_skipped.ico
app/assets/images/ci_favicons/favicon_status_skipped.ico
app/assets/images/ci_favicons/favicon_status_skipped.ico
app/assets/images/ci_favicons/favicon_status_skipped.ico
  • 2-up
  • Swipe
  • Onion skin
app/assets/images/ci_favicons/favicon_status_success.ico

5.3 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_success.ico

4.19 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_success.ico
app/assets/images/ci_favicons/favicon_status_success.ico
app/assets/images/ci_favicons/favicon_status_success.ico
app/assets/images/ci_favicons/favicon_status_success.ico
  • 2-up
  • Swipe
  • Onion skin
app/assets/images/ci_favicons/favicon_status_warning.ico

5.3 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_warning.ico

4.19 KB | W: | H:

app/assets/images/ci_favicons/favicon_status_warning.ico
app/assets/images/ci_favicons/favicon_status_warning.ico
app/assets/images/ci_favicons/favicon_status_warning.ico
app/assets/images/ci_favicons/favicon_status_warning.ico
  • 2-up
  • Swipe
  • Onion skin
/* eslint-disable no-new */ /* eslint-disable no-new */
import Vue from 'vue'; import Vue from 'vue';
import PDFLab from 'vendor/pdflab'; import pdfLab from '../../pdf/index.vue';
import workerSrc from 'vendor/pdf.worker';
Vue.use(PDFLab, {
workerSrc,
});
export default () => { export default () => {
const el = document.getElementById('js-pdf-viewer'); const el = document.getElementById('js-pdf-viewer');
...@@ -20,6 +15,9 @@ export default () => { ...@@ -20,6 +15,9 @@ export default () => {
pdf: el.dataset.endpoint, pdf: el.dataset.endpoint,
}; };
}, },
components: {
pdfLab,
},
methods: { methods: {
onLoad() { onLoad() {
this.loading = false; this.loading = false;
......
...@@ -6,7 +6,11 @@ export default class BlobViewer { ...@@ -6,7 +6,11 @@ export default class BlobViewer {
this.copySourceBtn = document.querySelector('.js-copy-blob-source-btn'); this.copySourceBtn = document.querySelector('.js-copy-blob-source-btn');
this.simpleViewer = document.querySelector('.blob-viewer[data-type="simple"]'); this.simpleViewer = document.querySelector('.blob-viewer[data-type="simple"]');
this.richViewer = document.querySelector('.blob-viewer[data-type="rich"]'); this.richViewer = document.querySelector('.blob-viewer[data-type="rich"]');
<<<<<<< HEAD
this.$blobContentHolder = $('#blob-content-holder'); this.$blobContentHolder = $('#blob-content-holder');
=======
this.$fileHolder = $('.file-holder');
>>>>>>> ce-com/master
let initialViewerName = document.querySelector('.blob-viewer:not(.hidden)').getAttribute('data-type'); let initialViewerName = document.querySelector('.blob-viewer:not(.hidden)').getAttribute('data-type');
...@@ -82,7 +86,11 @@ export default class BlobViewer { ...@@ -82,7 +86,11 @@ export default class BlobViewer {
viewer.setAttribute('data-loaded', 'true'); viewer.setAttribute('data-loaded', 'true');
<<<<<<< HEAD
this.$blobContentHolder.trigger('highlight:line'); this.$blobContentHolder.trigger('highlight:line');
=======
this.$fileHolder.trigger('highlight:line');
>>>>>>> ce-com/master
this.toggleCopyButtonState(); this.toggleCopyButtonState();
}); });
......
...@@ -47,14 +47,18 @@ import ProjectsList from './projects_list'; ...@@ -47,14 +47,18 @@ import ProjectsList from './projects_list';
import ApproversSelect from './approvers_select'; import ApproversSelect from './approvers_select';
import MiniPipelineGraph from './mini_pipeline_graph_dropdown'; import MiniPipelineGraph from './mini_pipeline_graph_dropdown';
import BlobLinePermalinkUpdater from './blob/blob_line_permalink_updater'; import BlobLinePermalinkUpdater from './blob/blob_line_permalink_updater';
import Landing from './landing';
import BlobForkSuggestion from './blob/blob_fork_suggestion'; import BlobForkSuggestion from './blob/blob_fork_suggestion';
import UserCallout from './user_callout'; import UserCallout from './user_callout';
import { ProtectedTagCreate, ProtectedTagEditList } from './protected_tags'; import { ProtectedTagCreate, ProtectedTagEditList } from './protected_tags';
import ShortcutsWiki from './shortcuts_wiki'; import ShortcutsWiki from './shortcuts_wiki';
import BlobViewer from './blob/viewer/index'; import BlobViewer from './blob/viewer/index';
<<<<<<< HEAD
import GeoNodes from './geo_nodes'; import GeoNodes from './geo_nodes';
import ServiceDeskRoot from './projects/settings_service_desk/service_desk_root'; import ServiceDeskRoot from './projects/settings_service_desk/service_desk_root';
=======
>>>>>>> ce-com/master
const ShortcutsBlob = require('./shortcuts_blob'); const ShortcutsBlob = require('./shortcuts_blob');
...@@ -154,8 +158,19 @@ const ShortcutsBlob = require('./shortcuts_blob'); ...@@ -154,8 +158,19 @@ const ShortcutsBlob = require('./shortcuts_blob');
new ProjectsList(); new ProjectsList();
break; break;
case 'dashboard:groups:index': case 'dashboard:groups:index':
new GroupsList();
break;
case 'explore:groups:index': case 'explore:groups:index':
new GroupsList(); new GroupsList();
const landingElement = document.querySelector('.js-explore-groups-landing');
if (!landingElement) break;
const exploreGroupsLanding = new Landing(
landingElement,
landingElement.querySelector('.dismiss-button'),
'explore_groups_landing_dismissed',
);
exploreGroupsLanding.toggle();
break; break;
case 'projects:milestones:new': case 'projects:milestones:new':
case 'projects:milestones:edit': case 'projects:milestones:edit':
...@@ -378,6 +393,10 @@ const ShortcutsBlob = require('./shortcuts_blob'); ...@@ -378,6 +393,10 @@ const ShortcutsBlob = require('./shortcuts_blob');
case 'users:show': case 'users:show':
new UserCallout(); new UserCallout();
break; break;
case 'snippets:show':
new LineHighlighter();
new BlobViewer();
break;
} }
switch (path.first()) { switch (path.first()) {
case 'sessions': case 'sessions':
...@@ -460,6 +479,8 @@ const ShortcutsBlob = require('./shortcuts_blob'); ...@@ -460,6 +479,8 @@ const ShortcutsBlob = require('./shortcuts_blob');
shortcut_handler = new ShortcutsNavigation(); shortcut_handler = new ShortcutsNavigation();
if (path[2] === 'show') { if (path[2] === 'show') {
new ZenMode(); new ZenMode();
new LineHighlighter();
new BlobViewer();
} }
break; break;
case 'labels': case 'labels':
......
import Cookies from 'js-cookie';
class Landing {
constructor(landingElement, dismissButton, cookieName) {
this.landingElement = landingElement;
this.cookieName = cookieName;
this.dismissButton = dismissButton;
this.eventWrapper = {};
}
toggle() {
const isDismissed = this.isDismissed();
this.landingElement.classList.toggle('hidden', isDismissed);
if (!isDismissed) this.addEvents();
}
addEvents() {
this.eventWrapper.dismissLanding = this.dismissLanding.bind(this);
this.dismissButton.addEventListener('click', this.eventWrapper.dismissLanding);
}
removeEvents() {
this.dismissButton.removeEventListener('click', this.eventWrapper.dismissLanding);
}
dismissLanding() {
this.landingElement.classList.add('hidden');
Cookies.set(this.cookieName, 'true', { expires: 365 });
}
isDismissed() {
return Cookies.get(this.cookieName) === 'true';
}
}
export default Landing;
...@@ -57,9 +57,15 @@ require('vendor/jquery.scrollTo'); ...@@ -57,9 +57,15 @@ require('vendor/jquery.scrollTo');
} }
LineHighlighter.prototype.bindEvents = function() { LineHighlighter.prototype.bindEvents = function() {
<<<<<<< HEAD
const $blobContentHolder = $('#blob-content-holder'); const $blobContentHolder = $('#blob-content-holder');
$blobContentHolder.on('click', 'a[data-line-number]', this.clickHandler); $blobContentHolder.on('click', 'a[data-line-number]', this.clickHandler);
$blobContentHolder.on('highlight:line', this.highlightHash); $blobContentHolder.on('highlight:line', this.highlightHash);
=======
const $fileHolder = $('.file-holder');
$fileHolder.on('click', 'a[data-line-number]', this.clickHandler);
$fileHolder.on('highlight:line', this.highlightHash);
>>>>>>> ce-com/master
}; };
LineHighlighter.prototype.highlightHash = function() { LineHighlighter.prototype.highlightHash = function() {
......
<template>
<div class="pdf-viewer" v-if="hasPDF">
<page v-for="(page, index) in pages"
:key="index"
:v-if="!loading"
:page="page"
:number="index + 1" />
</div>
</template>
<script>
import pdfjsLib from 'pdfjs-dist';
import workerSrc from 'vendor/pdf.worker';
import page from './page/index.vue';
export default {
props: {
pdf: {
type: [String, Uint8Array],
required: true,
},
},
data() {
return {
loading: false,
pages: [],
};
},
components: { page },
watch: { pdf: 'load' },
computed: {
document() {
return typeof this.pdf === 'string' ? this.pdf : { data: this.pdf };
},
hasPDF() {
return this.pdf && this.pdf.length > 0;
},
},
methods: {
load() {
this.pages = [];
return pdfjsLib.getDocument(this.document)
.then(this.renderPages)
.then(() => this.$emit('pdflabload'))
.catch(error => this.$emit('pdflaberror', error))
.then(() => { this.loading = false; });
},
renderPages(pdf) {
const pagePromises = [];
this.loading = true;
for (let num = 1; num <= pdf.numPages; num += 1) {
pagePromises.push(
pdf.getPage(num).then(p => this.pages.push(p)),
);
}
return Promise.all(pagePromises);
},
},
mounted() {
pdfjsLib.PDFJS.workerSrc = workerSrc;
if (this.hasPDF) this.load();
},
};
</script>
<style>
.pdf-viewer {
background: url('./assets/img/bg.gif');
display: flex;
flex-flow: column nowrap;
}
</style>
<template>
<canvas
class="pdf-page"
ref="canvas"
:data-page="number" />
</template>
<script>
export default {
props: {
page: {
type: Object,
required: true,
},
number: {
type: Number,
required: true,
},
},
data() {
return {
scale: 4,
rendering: false,
};
},
computed: {
viewport() {
return this.page.getViewport(this.scale);
},
context() {
return this.$refs.canvas.getContext('2d');
},
renderContext() {
return {
canvasContext: this.context,
viewport: this.viewport,
};
},
},
mounted() {
this.$refs.canvas.height = this.viewport.height;
this.$refs.canvas.width = this.viewport.width;
this.rendering = true;
this.page.render(this.renderContext)
.then(() => { this.rendering = false; })
.catch(error => this.$emit('pdflaberror', error));
},
};
</script>
<style>
.pdf-page {
margin: 8px auto 0 auto;
border-top: 1px #ddd solid;
border-bottom: 1px #ddd solid;
width: 100%;
}
.pdf-page:first-child {
margin-top: 0px;
border-top: 0px;
}
.pdf-page:last-child {
margin-bottom: 0px;
border-bottom: 0px;
}
</style>
...@@ -227,8 +227,8 @@ ...@@ -227,8 +227,8 @@
.award-control-icon-positive, .award-control-icon-positive,
.award-control-icon-super-positive { .award-control-icon-super-positive {
position: absolute; position: absolute;
left: 7px; left: 11px;
bottom: 9px; bottom: 7px;
opacity: 0; opacity: 0;
@include transition(opacity, transform); @include transition(opacity, transform);
} }
......
...@@ -254,6 +254,63 @@ ...@@ -254,6 +254,63 @@
padding: 10px 0; padding: 10px 0;
} }
.landing {
margin-bottom: $gl-padding;
overflow: hidden;
display: flex;
position: relative;
border: 1px solid $blue-300;
border-radius: $border-radius-default;
background-color: $blue-25;
justify-content: center;
.dismiss-button {
position: absolute;
right: 6px;
top: 6px;
cursor: pointer;
color: $blue-300;
z-index: 1;
border: none;
background-color: transparent;
&:hover,
&:focus {
border: none;
color: $blue-400;
}
}
.svg-container {
align-self: center;
}
.inner-content {
text-align: left;
white-space: nowrap;
h4 {
color: $gl-text-color;
font-size: 17px;
}
p {
color: $gl-text-color;
margin-bottom: $gl-padding;
}
}
@media (max-width: $screen-sm-min) {
flex-direction: column;
.inner-content {
white-space: normal;
padding: 0 28px;
text-align: center;
}
}
}
.empty-state { .empty-state {
margin: 100px 0 0; margin: 100px 0 0;
......
...@@ -428,6 +428,11 @@ table { ...@@ -428,6 +428,11 @@ table {
} }
} }
.bordered-box {
border: 1px solid $border-color;
border-radius: $border-radius-default;
}
.str-truncated { .str-truncated {
&-60 { &-60 {
@include str-truncated(60%); @include str-truncated(60%);
......
...@@ -61,11 +61,13 @@ ...@@ -61,11 +61,13 @@
.file-content { .file-content {
background: $white-light; background: $white-light;
&.image_file { &.image_file,
&.video {
background: $file-image-bg; background: $file-image-bg;
text-align: center; text-align: center;
img { img,
video {
padding: 20px; padding: 20px;
max-width: 80%; max-width: 80%;
} }
......
...@@ -120,6 +120,10 @@ ...@@ -120,6 +120,10 @@
// Ensure that image does not exceed viewport // Ensure that image does not exceed viewport
max-height: calc(100vh - 100px); max-height: calc(100vh - 100px);
} }
table {
@include markdown-table;
}
} }
.toolbar-group { .toolbar-group {
......
...@@ -12,6 +12,13 @@ ...@@ -12,6 +12,13 @@
max-width: $max_width; max-width: $max_width;
} }
/*
* Mixin for markdown tables
*/
@mixin markdown-table {
width: auto;
}
/* /*
* Base mixin for lists in GitLab * Base mixin for lists in GitLab
*/ */
......
...@@ -200,6 +200,7 @@ ...@@ -200,6 +200,7 @@
.header-content { .header-content {
flex: 1; flex: 1;
line-height: 1.8;
a { a {
color: $gl-text-color; color: $gl-text-color;
......
...@@ -93,11 +93,6 @@ ...@@ -93,11 +93,6 @@
top: $gl-padding-top; top: $gl-padding-top;
} }
.bordered-box {
border: 1px solid $border-color;
border-radius: $border-radius-default;
}
.content-list { .content-list {
li { li {
padding: 18px $gl-padding $gl-padding; padding: 18px $gl-padding $gl-padding;
...@@ -139,43 +134,10 @@ ...@@ -139,43 +134,10 @@
} }
} }
.landing { .landing svg {
margin-bottom: $gl-padding;
overflow: hidden;
.dismiss-icon {
position: absolute;
right: $cycle-analytics-box-padding;
cursor: pointer;
color: $cycle-analytics-dismiss-icon-color;
}
.svg-container {
text-align: center;
svg {
width: 136px; width: 136px;
height: 136px; height: 136px;
} }
}
.inner-content {
@media (max-width: $screen-xs-max) {
padding: 0 28px;
text-align: center;
}
h4 {
color: $gl-text-color;
font-size: 17px;
}
p {
color: $cycle-analytics-box-text-color;
margin-bottom: $gl-padding;
}
}
}
.fa-spinner { .fa-spinner {
font-size: 28px; font-size: 28px;
......
...@@ -136,3 +136,26 @@ table.pipeline-project-metrics tr td { ...@@ -136,3 +136,26 @@ table.pipeline-project-metrics tr td {
color: $gl-text-color-secondary; color: $gl-text-color-secondary;
margin-top: 10px; margin-top: 10px;
} }
.explore-groups.landing {
margin-top: 10px;
.inner-content {
padding: 0;
p {
margin: 7px 0 0;
max-width: 480px;
padding: 0 $gl-padding;
@media (max-width: $screen-sm-min) {
margin: 0 auto;
}
}
}
svg {
width: 62px;
height: 50px;
}
}
...@@ -101,11 +101,16 @@ ul.related-merge-requests > li { ...@@ -101,11 +101,16 @@ ul.related-merge-requests > li {
} }
} }
.merge-request-ci-status { .merge-request-ci-status,
.related-merge-requests {
.ci-status-link {
display: block;
margin-top: 3px;
margin-right: 5px;
}
svg { svg {
margin-right: 4px; display: block;
position: relative;
top: 1px;
} }
} }
......
...@@ -97,6 +97,10 @@ ul.notes { ...@@ -97,6 +97,10 @@ ul.notes {
padding-left: 1.3em; padding-left: 1.3em;
} }
} }
table {
@include markdown-table;
}
} }
} }
......
...@@ -159,3 +159,9 @@ ul.wiki-pages-list.content-list { ...@@ -159,3 +159,9 @@ ul.wiki-pages-list.content-list {
padding: 5px 0; padding: 5px 0;
} }
} }
.wiki {
table {
@include markdown-table;
}
}
class Admin::HooksController < Admin::ApplicationController class Admin::HooksController < Admin::ApplicationController
before_action :hook, only: :edit
def index def index
@hooks = SystemHook.all @hooks = SystemHook.all
@hook = SystemHook.new @hook = SystemHook.new
...@@ -15,15 +17,25 @@ class Admin::HooksController < Admin::ApplicationController ...@@ -15,15 +17,25 @@ class Admin::HooksController < Admin::ApplicationController
end end
end end
def edit
end
def update
if hook.update_attributes(hook_params)
flash[:notice] = 'System hook was successfully updated.'
redirect_to admin_hooks_path
else
render 'edit'
end
end
def destroy def destroy
@hook = SystemHook.find(params[:id]) hook.destroy
@hook.destroy
redirect_to admin_hooks_path redirect_to admin_hooks_path
end end
def test def test
@hook = SystemHook.find(params[:hook_id])
data = { data = {
event_name: "project_create", event_name: "project_create",
name: "Ruby", name: "Ruby",
...@@ -32,11 +44,17 @@ class Admin::HooksController < Admin::ApplicationController ...@@ -32,11 +44,17 @@ class Admin::HooksController < Admin::ApplicationController
owner_name: "Someone", owner_name: "Someone",
owner_email: "example@gitlabhq.com" owner_email: "example@gitlabhq.com"
} }
@hook.execute(data, 'system_hooks') hook.execute(data, 'system_hooks')
redirect_back_or_default redirect_back_or_default
end end
private
def hook
@hook ||= SystemHook.find(params[:id])
end
def hook_params def hook_params
params.require(:hook).permit( params.require(:hook).permit(
:enable_ssl_verification, :enable_ssl_verification,
......
...@@ -122,6 +122,10 @@ class ApplicationController < ActionController::Base ...@@ -122,6 +122,10 @@ class ApplicationController < ActionController::Base
end end
end end
def respond_422
head :unprocessable_entity
end
def no_cache_headers def no_cache_headers
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate" response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache" response.headers["Pragma"] = "no-cache"
......
...@@ -14,4 +14,11 @@ module RendersBlob ...@@ -14,4 +14,11 @@ module RendersBlob
html: view_to_html_string("projects/blob/_viewer", viewer: viewer, load_asynchronously: false) html: view_to_html_string("projects/blob/_viewer", viewer: viewer, load_asynchronously: false)
} }
end end
<<<<<<< HEAD
=======
def override_max_blob_size(blob)
blob.override_max_size! if params[:override_max_size] == 'true'
end
>>>>>>> ce-com/master
end end
...@@ -38,6 +38,7 @@ module ServiceParams ...@@ -38,6 +38,7 @@ module ServiceParams
:new_issue_url, :new_issue_url,
:notify, :notify,
:notify_only_broken_pipelines, :notify_only_broken_pipelines,
:notify_only_default_branch,
:password, :password,
:priority, :priority,
:project_key, :project_key,
......
...@@ -35,7 +35,11 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -35,7 +35,11 @@ class Projects::BlobController < Projects::ApplicationController
end end
def show def show
<<<<<<< HEAD
@blob.override_max_size! if params[:override_max_size] == 'true' @blob.override_max_size! if params[:override_max_size] == 'true'
=======
override_max_blob_size(@blob)
>>>>>>> ce-com/master
respond_to do |format| respond_to do |format|
format.html do format.html do
......
class Projects::BuildsController < Projects::ApplicationController class Projects::BuildsController < Projects::ApplicationController
before_action :build, except: [:index, :cancel_all] before_action :build, except: [:index, :cancel_all]
before_action :authorize_read_build!, except: [:cancel, :cancel_all, :retry, :play] before_action :authorize_read_build!, only: [:index, :show, :status, :raw, :trace]
before_action :authorize_update_build!, except: [:index, :show, :status, :raw, :trace] before_action :authorize_update_build!, except: [:index, :show, :status, :raw, :trace]
layout 'project' layout 'project'
...@@ -60,20 +60,22 @@ class Projects::BuildsController < Projects::ApplicationController ...@@ -60,20 +60,22 @@ class Projects::BuildsController < Projects::ApplicationController
end end
def retry def retry
return render_404 unless @build.retryable? return respond_422 unless @build.retryable?
build = Ci::Build.retry(@build, current_user) build = Ci::Build.retry(@build, current_user)
redirect_to build_path(build) redirect_to build_path(build)
end end
def play def play
return render_404 unless @build.playable? return respond_422 unless @build.playable?
build = @build.play(current_user) build = @build.play(current_user)
redirect_to build_path(build) redirect_to build_path(build)
end end
def cancel def cancel
return respond_422 unless @build.cancelable?
@build.cancel @build.cancel
redirect_to build_path(@build) redirect_to build_path(@build)
end end
...@@ -85,9 +87,12 @@ class Projects::BuildsController < Projects::ApplicationController ...@@ -85,9 +87,12 @@ class Projects::BuildsController < Projects::ApplicationController
end end
def erase def erase
@build.erase(erased_by: current_user) if @build.erase(erased_by: current_user)
redirect_to namespace_project_build_path(project.namespace, project, @build), redirect_to namespace_project_build_path(project.namespace, project, @build),
notice: "Build has been successfully erased!" notice: "Build has been successfully erased!"
else
respond_422
end
end end
def raw def raw
......
class Projects::HooksController < Projects::ApplicationController class Projects::HooksController < Projects::ApplicationController
# Authorize # Authorize
before_action :authorize_admin_project! before_action :authorize_admin_project!
before_action :hook, only: :edit
respond_to :html respond_to :html
...@@ -17,6 +18,18 @@ class Projects::HooksController < Projects::ApplicationController ...@@ -17,6 +18,18 @@ class Projects::HooksController < Projects::ApplicationController
redirect_to namespace_project_settings_integrations_path(@project.namespace, @project) redirect_to namespace_project_settings_integrations_path(@project.namespace, @project)
end end
def edit
end
def update
if hook.update_attributes(hook_params)
flash[:notice] = 'Hook was successfully updated.'
redirect_to namespace_project_settings_integrations_path(@project.namespace, @project)
else
render 'edit'
end
end
def test def test
if !@project.empty_repo? if !@project.empty_repo?
status, message = TestHookService.new.execute(hook, current_user) status, message = TestHookService.new.execute(hook, current_user)
......
...@@ -3,6 +3,7 @@ class Projects::SnippetsController < Projects::ApplicationController ...@@ -3,6 +3,7 @@ class Projects::SnippetsController < Projects::ApplicationController
include ToggleAwardEmoji include ToggleAwardEmoji
include SpammableActions include SpammableActions
include SnippetsActions include SnippetsActions
include RendersBlob
before_action :module_enabled before_action :module_enabled
before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :toggle_award_emoji, :mark_as_spam] before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :toggle_award_emoji, :mark_as_spam]
...@@ -55,11 +56,23 @@ class Projects::SnippetsController < Projects::ApplicationController ...@@ -55,11 +56,23 @@ class Projects::SnippetsController < Projects::ApplicationController
end end
def show def show
blob = @snippet.blob
override_max_blob_size(blob)
respond_to do |format|
format.html do
@note = @project.notes.new(noteable: @snippet) @note = @project.notes.new(noteable: @snippet)
@noteable = @snippet @noteable = @snippet
@discussions = @snippet.discussions @discussions = @snippet.discussions
@notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes)) @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes))
render 'show'
end
format.json do
render_blob_json(blob)
end
end
end end
def destroy def destroy
......
...@@ -3,6 +3,7 @@ class SnippetsController < ApplicationController ...@@ -3,6 +3,7 @@ class SnippetsController < ApplicationController
include SpammableActions include SpammableActions
include SnippetsActions include SnippetsActions
include MarkdownPreview include MarkdownPreview
include RendersBlob
before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :download] before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :download]
...@@ -60,6 +61,18 @@ class SnippetsController < ApplicationController ...@@ -60,6 +61,18 @@ class SnippetsController < ApplicationController
end end
def show def show
blob = @snippet.blob
override_max_blob_size(blob)
respond_to do |format|
format.html do
render 'show'
end
format.json do
render_blob_json(blob)
end
end
end end
def destroy def destroy
......
if Rails.env.test?
class UnicornTestController < ActionController::Base
def pid
render plain: Process.pid.to_s
end
def kill
Process.kill(params[:signal], Process.pid)
render plain: 'Bye!'
end
end
end
...@@ -119,8 +119,20 @@ module BlobHelper ...@@ -119,8 +119,20 @@ module BlobHelper
end end
def blob_raw_url def blob_raw_url
<<<<<<< HEAD
namespace_project_raw_path(@project.namespace, @project, @id)
=======
if @snippet
if @snippet.project_id
raw_namespace_project_snippet_path(@project.namespace, @project, @snippet)
else
raw_snippet_path(@snippet)
end
elsif @blob
namespace_project_raw_path(@project.namespace, @project, @id) namespace_project_raw_path(@project.namespace, @project, @id)
end end
>>>>>>> ce-com/master
end
# SVGs can contain malicious JavaScript; only include whitelisted # SVGs can contain malicious JavaScript; only include whitelisted
# elements and attributes. Note that this whitelist is by no means complete # elements and attributes. Note that this whitelist is by no means complete
...@@ -209,11 +221,55 @@ module BlobHelper ...@@ -209,11 +221,55 @@ module BlobHelper
end end
def copy_blob_source_button(blob) def copy_blob_source_button(blob)
<<<<<<< HEAD
=======
return unless blob.rendered_as_text?(ignore_errors: false)
>>>>>>> ce-com/master
clipboard_button(target: ".blob-content[data-blob-id='#{blob.id}']", class: "btn btn-sm js-copy-blob-source-btn", title: "Copy source to clipboard") clipboard_button(target: ".blob-content[data-blob-id='#{blob.id}']", class: "btn btn-sm js-copy-blob-source-btn", title: "Copy source to clipboard")
end end
def open_raw_file_button(path) def open_raw_blob_button(blob)
link_to icon('file-code-o'), path, class: 'btn btn-sm has-tooltip', target: '_blank', rel: 'noopener noreferrer', title: 'Open raw', data: { container: 'body' } if blob.raw_binary?
icon = icon('download')
title = 'Download'
else
icon = icon('file-code-o')
title = 'Open raw'
end
link_to icon, blob_raw_url, class: 'btn btn-sm has-tooltip', target: '_blank', rel: 'noopener noreferrer', title: title, data: { container: 'body' }
end
def blob_render_error_reason(viewer)
case viewer.render_error
when :too_large
max_size =
if viewer.absolutely_too_large?
viewer.absolute_max_size
elsif viewer.too_large?
viewer.max_size
end
"it is larger than #{number_to_human_size(max_size)}"
when :server_side_but_stored_in_lfs
"it is stored in LFS"
end
end
def blob_render_error_options(viewer)
options = []
if viewer.render_error == :too_large && viewer.can_override_max_size?
options << link_to('load it anyway', url_for(params.merge(viewer: viewer.type, override_max_size: true, format: nil)))
end
if viewer.rich? && viewer.blob.rendered_as_text?
options << link_to('view the source', '#', class: 'js-blob-viewer-switch-btn', data: { viewer: 'simple' })
end
options << link_to('download it', blob_raw_url, target: '_blank', rel: 'noopener noreferrer')
options
end end
def blob_render_error_reason(viewer) def blob_render_error_reason(viewer)
......
...@@ -10,11 +10,12 @@ module EventsHelper ...@@ -10,11 +10,12 @@ module EventsHelper
'deleted' => 'icon_trash_o' 'deleted' => 'icon_trash_o'
}.freeze }.freeze
def link_to_author(event) def link_to_author(event, self_added: false)
author = event.author author = event.author
if author if author
link_to author.name, user_path(author.username), title: author.name name = self_added ? 'You' : author.name
link_to name, user_path(author.username), title: name
else else
event.author_name event.author_name
end end
......
...@@ -74,7 +74,7 @@ module MarkupHelper ...@@ -74,7 +74,7 @@ module MarkupHelper
context[:project] ||= @project context[:project] ||= @project
html = markdown_unsafe(text, context) html = markdown_unsafe(text, context)
banzai_postprocess(html, context) prepare_for_rendering(html, context)
end end
def markdown_field(object, field) def markdown_field(object, field)
...@@ -82,13 +82,13 @@ module MarkupHelper ...@@ -82,13 +82,13 @@ module MarkupHelper
return '' unless object.present? return '' unless object.present?
html = Banzai.render_field(object, field) html = Banzai.render_field(object, field)
banzai_postprocess(html, object.banzai_render_context(field)) prepare_for_rendering(html, object.banzai_render_context(field))
end end
def markup(file_name, text, context = {}) def markup(file_name, text, context = {})
context[:project] ||= @project context[:project] ||= @project
html = context.delete(:rendered) || markup_unsafe(file_name, text, context) html = context.delete(:rendered) || markup_unsafe(file_name, text, context)
banzai_postprocess(html, context) prepare_for_rendering(html, context)
end end
def render_wiki_content(wiki_page) def render_wiki_content(wiki_page)
...@@ -107,14 +107,14 @@ module MarkupHelper ...@@ -107,14 +107,14 @@ module MarkupHelper
wiki_page.formatted_content.html_safe wiki_page.formatted_content.html_safe
end end
banzai_postprocess(html, context) prepare_for_rendering(html, context)
end end
def markup_unsafe(file_name, text, context = {}) def markup_unsafe(file_name, text, context = {})
return '' unless text.present? return '' unless text.present?
if gitlab_markdown?(file_name) if gitlab_markdown?(file_name)
Hamlit::RailsHelpers.preserve(markdown_unsafe(text, context)) markdown_unsafe(text, context)
elsif asciidoc?(file_name) elsif asciidoc?(file_name)
asciidoc_unsafe(text) asciidoc_unsafe(text)
elsif plain?(file_name) elsif plain?(file_name)
...@@ -225,8 +225,7 @@ module MarkupHelper ...@@ -225,8 +225,7 @@ module MarkupHelper
Gitlab::OtherMarkup.render(file_name, text) Gitlab::OtherMarkup.render(file_name, text)
end end
# Calls Banzai.post_process with some common context options def prepare_for_rendering(html, context = {})
def banzai_postprocess(html, context = {})
return '' unless html.present? return '' unless html.present?
context.merge!( context.merge!(
...@@ -239,7 +238,9 @@ module MarkupHelper ...@@ -239,7 +238,9 @@ module MarkupHelper
requested_path: @path requested_path: @path
) )
Banzai.post_process(html, context) html = Banzai.post_process(html, context)
Hamlit::RailsHelpers.preserve(html)
end end
extend self extend self
......
module MergeRequestsHelper module MergeRequestsHelper
def new_mr_path_from_push_event(event) def new_mr_path_from_push_event(event)
target_project = event.project.forked_from_project || event.project target_project = event.project.default_merge_request_target
new_namespace_project_merge_request_path( new_namespace_project_merge_request_path(
event.project.namespace, event.project.namespace,
event.project, event.project,
...@@ -141,6 +141,10 @@ module MergeRequestsHelper ...@@ -141,6 +141,10 @@ module MergeRequestsHelper
end end
end end
def target_projects(project)
[project, project.default_merge_request_target].uniq
end
def merge_request_button_visibility(merge_request, closed) def merge_request_button_visibility(merge_request, closed)
return 'hidden' if merge_request.closed? == closed || (merge_request.merged? == closed && !merge_request.closed?) || merge_request.closed_without_fork? return 'hidden' if merge_request.closed? == closed || (merge_request.merged? == closed && !merge_request.closed?) || merge_request.closed_without_fork?
end end
......
...@@ -13,13 +13,13 @@ module TodosHelper ...@@ -13,13 +13,13 @@ module TodosHelper
def todo_action_name(todo) def todo_action_name(todo)
case todo.action case todo.action
when Todo::ASSIGNED then 'assigned you' when Todo::ASSIGNED then todo.self_added? ? 'assigned' : 'assigned you'
when Todo::MENTIONED then 'mentioned you on' when Todo::MENTIONED then "mentioned #{todo_action_subject(todo)} on"
when Todo::BUILD_FAILED then 'The build failed for' when Todo::BUILD_FAILED then 'The build failed for'
when Todo::MARKED then 'added a todo for' when Todo::MARKED then 'added a todo for'
when Todo::APPROVAL_REQUIRED then 'set you as an approver for' when Todo::APPROVAL_REQUIRED then "set #{todo_action_subject(todo)} as an approver for"
when Todo::UNMERGEABLE then 'Could not merge' when Todo::UNMERGEABLE then 'Could not merge'
when Todo::DIRECTLY_ADDRESSED then 'directly addressed you on' when Todo::DIRECTLY_ADDRESSED then "directly addressed #{todo_action_subject(todo)} on"
end end
end end
...@@ -148,6 +148,10 @@ module TodosHelper ...@@ -148,6 +148,10 @@ module TodosHelper
private private
def todo_action_subject(todo)
todo.self_added? ? 'yourself' : 'you'
end
def show_todo_state?(todo) def show_todo_state?(todo)
(todo.target.is_a?(MergeRequest) || todo.target.is_a?(Issue)) && %w(closed merged).include?(todo.target.state) (todo.target.is_a?(MergeRequest) || todo.target.is_a?(Issue)) && %w(closed merged).include?(todo.target.state)
end end
......
...@@ -27,6 +27,11 @@ class Blob < SimpleDelegator ...@@ -27,6 +27,11 @@ class Blob < SimpleDelegator
BlobViewer::Image, BlobViewer::Image,
BlobViewer::Sketch, BlobViewer::Sketch,
<<<<<<< HEAD
=======
BlobViewer::Video,
>>>>>>> ce-com/master
BlobViewer::PDF, BlobViewer::PDF,
BlobViewer::BinarySTL, BlobViewer::BinarySTL,
......
module BlobViewer
class Video < Base
include Rich
include ClientSide
self.partial_name = 'video'
self.extensions = UploaderHelper::VIDEO_EXT
self.binary = true
self.switcher_icon = 'film'
self.switcher_title = 'video'
end
end
...@@ -34,6 +34,7 @@ class Label < ActiveRecord::Base ...@@ -34,6 +34,7 @@ class Label < ActiveRecord::Base
scope :templates, -> { where(template: true) } scope :templates, -> { where(template: true) }
scope :with_title, ->(title) { where(title: title) } scope :with_title, ->(title) { where(title: title) }
scope :on_project_boards, ->(project_id) { joins(lists: :board).merge(List.movable).where(boards: { project_id: project_id }) }
def self.prioritized(project) def self.prioritized(project)
joins(:priorities) joins(:priorities)
......
...@@ -157,6 +157,11 @@ class Member < ActiveRecord::Base ...@@ -157,6 +157,11 @@ class Member < ActiveRecord::Base
def add_users(source, users, access_level, current_user: nil, expires_at: nil) def add_users(source, users, access_level, current_user: nil, expires_at: nil)
return [] unless users.present? return [] unless users.present?
# Collect all user ids into separate array
# so we can use single sql query to get user objects
user_ids = users.select { |user| user =~ /\A\d+\Z/ }
users = users - user_ids + User.where(id: user_ids)
self.transaction do self.transaction do
users.map do |user| users.map do |user|
add_user( add_user(
......
...@@ -105,7 +105,11 @@ class MergeRequest < ActiveRecord::Base ...@@ -105,7 +105,11 @@ class MergeRequest < ActiveRecord::Base
validates :merge_user, presence: true, if: :merge_when_pipeline_succeeds?, unless: :importing? validates :merge_user, presence: true, if: :merge_when_pipeline_succeeds?, unless: :importing?
validate :validate_branches, unless: [:allow_broken, :importing?, :closed_without_fork?] validate :validate_branches, unless: [:allow_broken, :importing?, :closed_without_fork?]
validate :validate_fork, unless: :closed_without_fork? validate :validate_fork, unless: :closed_without_fork?
<<<<<<< HEAD
validate :validate_approvals_before_merge validate :validate_approvals_before_merge
=======
validate :validate_target_project, on: :create
>>>>>>> ce-com/master
scope :by_source_or_target_branch, ->(branch_name) do scope :by_source_or_target_branch, ->(branch_name) do
where("source_branch = :branch OR target_branch = :branch", branch: branch_name) where("source_branch = :branch OR target_branch = :branch", branch: branch_name)
...@@ -337,6 +341,12 @@ class MergeRequest < ActiveRecord::Base ...@@ -337,6 +341,12 @@ class MergeRequest < ActiveRecord::Base
end end
end end
def validate_target_project
return true if target_project.merge_requests_enabled?
errors.add :base, 'Target project has disabled merge requests'
end
def validate_fork def validate_fork
return true unless target_project && source_project return true unless target_project && source_project
return true if target_project == source_project return true if target_project == source_project
......
...@@ -1559,6 +1559,14 @@ class Project < ActiveRecord::Base ...@@ -1559,6 +1559,14 @@ class Project < ActiveRecord::Base
namespace_id_changed? namespace_id_changed?
end end
def default_merge_request_target
if forked_from_project&.merge_requests_enabled?
forked_from_project
else
self
end
end
alias_method :name_with_namespace, :full_name alias_method :name_with_namespace, :full_name
alias_method :human_name, :full_name alias_method :human_name, :full_name
alias_method :path_with_namespace, :full_path alias_method :path_with_namespace, :full_path
......
...@@ -22,7 +22,7 @@ class ChatNotificationService < Service ...@@ -22,7 +22,7 @@ class ChatNotificationService < Service
end end
def can_test? def can_test?
super && valid? valid?
end end
def self.supported_events def self.supported_events
......
...@@ -1035,15 +1035,13 @@ class Repository ...@@ -1035,15 +1035,13 @@ class Repository
end end
def is_ancestor?(ancestor_id, descendant_id) def is_ancestor?(ancestor_id, descendant_id)
# NOTE: This feature is intentionally disabled until Gitlab::GitalyClient.migrate(:is_ancestor) do |is_enabled|
# https://gitlab.com/gitlab-org/gitlab-ce/issues/30586 is resolved if is_enabled
# Gitlab::GitalyClient.migrate(:is_ancestor) do |is_enabled| raw_repository.is_ancestor?(ancestor_id, descendant_id)
# if is_enabled else
# raw_repository.is_ancestor?(ancestor_id, descendant_id)
# else
merge_base_commit(ancestor_id, descendant_id) == ancestor_id merge_base_commit(ancestor_id, descendant_id) == ancestor_id
# end end
# end end
end end
def empty_repo? def empty_repo?
......
...@@ -132,7 +132,7 @@ class Service < ActiveRecord::Base ...@@ -132,7 +132,7 @@ class Service < ActiveRecord::Base
end end
def can_test? def can_test?
!project.empty_repo? true
end end
# reason why service cannot be tested # reason why service cannot be tested
......
class Snippet < ActiveRecord::Base class Snippet < ActiveRecord::Base
include Gitlab::VisibilityLevel include Gitlab::VisibilityLevel
include Linguist::BlobHelper
include CacheMarkdownField include CacheMarkdownField
include Noteable include Noteable
include Participable include Participable
...@@ -88,47 +87,26 @@ class Snippet < ActiveRecord::Base ...@@ -88,47 +87,26 @@ class Snippet < ActiveRecord::Base
] ]
end end
def data def blob
content @blob ||= Blob.decorate(SnippetBlob.new(self), nil)
end end
def hook_attrs def hook_attrs
attributes attributes
end end
def size
0
end
def file_name def file_name
super.to_s super.to_s
end end
# alias for compatibility with blobs and highlighting
def path
file_name
end
def name
file_name
end
def sanitized_file_name def sanitized_file_name
file_name.gsub(/[^a-zA-Z0-9_\-\.]+/, '') file_name.gsub(/[^a-zA-Z0-9_\-\.]+/, '')
end end
def mode
nil
end
def visibility_level_field def visibility_level_field
:visibility_level :visibility_level
end end
def no_highlighting?
content.lines.count > 1000
end
def notes_with_associations def notes_with_associations
notes.includes(:author) notes.includes(:author)
end end
......
class SnippetBlob
include Linguist::BlobHelper
attr_reader :snippet
def initialize(snippet)
@snippet = snippet
end
delegate :id, to: :snippet
def name
snippet.file_name
end
alias_method :path, :name
def size
data.bytesize
end
def data
snippet.content
end
def rendered_markup
return unless Gitlab::MarkupHelper.gitlab_markdown?(name)
Banzai.render_field(snippet, :content)
end
def mode
nil
end
def binary?
false
end
def load_all_data!(repository)
# No-op
end
def lfs_pointer?
false
end
def lfs_oid
nil
end
def lfs_size
nil
end
def truncated?
false
end
end
...@@ -84,6 +84,10 @@ class Todo < ActiveRecord::Base ...@@ -84,6 +84,10 @@ class Todo < ActiveRecord::Base
action == BUILD_FAILED action == BUILD_FAILED
end end
def assigned?
action == ASSIGNED
end
def action_name def action_name
ACTION_NAMES[action] ACTION_NAMES[action]
end end
...@@ -117,6 +121,14 @@ class Todo < ActiveRecord::Base ...@@ -117,6 +121,14 @@ class Todo < ActiveRecord::Base
end end
end end
def self_added?
author == user
end
def self_assigned?
assigned? && self_added?
end
private private
def keep_around_commit def keep_around_commit
......
...@@ -1101,11 +1101,13 @@ class User < ActiveRecord::Base ...@@ -1101,11 +1101,13 @@ class User < ActiveRecord::Base
User.find_by_email(s) User.find_by_email(s)
end end
scope.create( user = scope.build(
username: username, username: username,
email: email, email: email,
&creation_block &creation_block
) )
user.save(validate: false)
user
ensure ensure
Gitlab::ExclusiveLease.cancel(lease_key, uuid) Gitlab::ExclusiveLease.cancel(lease_key, uuid)
end end
......
...@@ -7,6 +7,9 @@ class StatusEntity < Grape::Entity ...@@ -7,6 +7,9 @@ class StatusEntity < Grape::Entity
expose :details_path expose :details_path
expose :favicon do |status| expose :favicon do |status|
ActionController::Base.helpers.image_path(File.join('ci_favicons', "#{status.favicon}.ico")) dir = 'ci_favicons'
dir = File.join(dir, 'dev') if Rails.env.development?
ActionController::Base.helpers.image_path(File.join(dir, "#{status.favicon}.ico"))
end end
end end
...@@ -61,7 +61,7 @@ module Boards ...@@ -61,7 +61,7 @@ module Boards
if moving_to_list.movable? if moving_to_list.movable?
moving_from_list.label_id moving_from_list.label_id
else else
project.boards.joins(:lists).merge(List.movable).pluck(:label_id) Label.on_project_boards(project.id).pluck(:label_id)
end end
Array(label_ids).compact Array(label_ids).compact
......
...@@ -28,7 +28,7 @@ module MergeRequests ...@@ -28,7 +28,7 @@ module MergeRequests
def find_target_project def find_target_project
return target_project if target_project.present? && can?(current_user, :read_project, target_project) return target_project if target_project.present? && can?(current_user, :read_project, target_project)
project.forked_from_project || project project.default_merge_request_target
end end
def find_target_branch def find_target_branch
......
...@@ -330,6 +330,7 @@ module SlashCommands ...@@ -330,6 +330,7 @@ module SlashCommands
@updates[:target_branch] = branch_name if project.repository.branch_names.include?(branch_name) @updates[:target_branch] = branch_name if project.repository.branch_names.include?(branch_name)
end end
<<<<<<< HEAD
desc 'Set weight' desc 'Set weight'
params Issue::WEIGHT_RANGE.to_s.squeeze('.').tr('.', '-') params Issue::WEIGHT_RANGE.to_s.squeeze('.').tr('.', '-')
condition do condition do
...@@ -351,6 +352,28 @@ module SlashCommands ...@@ -351,6 +352,28 @@ module SlashCommands
end end
command :clear_weight do command :clear_weight do
@updates[:weight] = nil @updates[:weight] = nil
=======
desc 'Move issue from one column of the board to another'
params '~"Target column"'
condition do
issuable.is_a?(Issue) &&
current_user.can?(:"update_#{issuable.to_ability_name}", issuable) &&
issuable.project.boards.count == 1
end
command :board_move do |target_list_name|
label_ids = find_label_ids(target_list_name)
if label_ids.size == 1
label_id = label_ids.first
# Ensure this label corresponds to a list on the board
next unless Label.on_project_boards(issuable.project_id).where(id: label_id).exists?
@updates[:remove_label_ids] =
issuable.labels.on_project_boards(issuable.project_id).where.not(id: label_id).pluck(:id)
@updates[:add_label_ids] = [label_id]
end
>>>>>>> ce-com/master
end end
def find_label_ids(labels_param) def find_label_ids(labels_param)
......
...@@ -86,6 +86,12 @@ ...@@ -86,6 +86,12 @@
= container_reg = container_reg
%span.light.pull-right %span.light.pull-right
= boolean_to_icon Gitlab.config.registry.enabled = boolean_to_icon Gitlab.config.registry.enabled
- gitlab_pages = 'GitLab Pages'
- gitlab_pages_enabled = Gitlab.config.pages.enabled
%p{ "aria-label" => "#{gitlab_pages}: status " + (gitlab_pages_enabled ? "on" : "off") }
= gitlab_pages
%span.light.pull-right
= boolean_to_icon gitlab_pages_enabled
.col-md-4 .col-md-4
%h4 %h4
......
= form_errors(hook)
.form-group
= form.label :url, 'URL', class: 'control-label'
.col-sm-10
= form.text_field :url, class: 'form-control'
.form-group
= form.label :token, 'Secret Token', class: 'control-label'
.col-sm-10
= form.text_field :token, class: 'form-control'
%p.help-block
Use this token to validate received payloads
.form-group
= form.label :url, 'Trigger', class: 'control-label'
.col-sm-10.prepend-top-10
%div
System hook will be triggered on set of events like creating project
or adding ssh key. But you can also enable extra triggers like Push events.
.prepend-top-default
= form.check_box :push_events, class: 'pull-left'
.prepend-left-20
= form.label :push_events, class: 'list-label' do
%strong Push events
%p.light
This url will be triggered by a push to the repository
%div
= form.check_box :tag_push_events, class: 'pull-left'
.prepend-left-20
= form.label :tag_push_events, class: 'list-label' do
%strong Tag push events
%p.light
This url will be triggered when a new tag is pushed to the repository
.form-group
= form.label :enable_ssl_verification, 'SSL verification', class: 'control-label checkbox'
.col-sm-10
.checkbox
= form.label :enable_ssl_verification do
= form.check_box :enable_ssl_verification
%strong Enable SSL verification
- page_title 'Edit System Hook'
%h3.page-title
Edit System Hook
%p.light
#{link_to 'System hooks ', help_page_path('system_hooks/system_hooks'), class: 'vlink'} can be
used for binding events when GitLab creates a User or Project.
%hr
= form_for @hook, as: :hook, url: admin_hook_path, html: { class: 'form-horizontal' } do |f|
= render partial: 'form', locals: { form: f, hook: @hook }
.form-actions
= f.submit 'Save changes', class: 'btn btn-create'
- page_title "System Hooks" - page_title 'System Hooks'
%h3.page-title %h3.page-title
System hooks System hooks
%p.light %p.light
#{link_to "System hooks ", help_page_path("system_hooks/system_hooks"), class: "vlink"} can be #{link_to 'System hooks ', help_page_path('system_hooks/system_hooks'), class: 'vlink'} can be
used for binding events when GitLab creates a User or Project. used for binding events when GitLab creates a User or Project.
%hr %hr
= form_for @hook, as: :hook, url: admin_hooks_path, html: { class: 'form-horizontal' } do |f| = form_for @hook, as: :hook, url: admin_hooks_path, html: { class: 'form-horizontal' } do |f|
= form_errors(@hook) = render partial: 'form', locals: { form: f, hook: @hook }
.form-group
= f.label :url, 'URL', class: 'control-label'
.col-sm-10
= f.text_field :url, class: 'form-control'
.form-group
= f.label :token, 'Secret Token', class: 'control-label'
.col-sm-10
= f.text_field :token, class: 'form-control'
%p.help-block
Use this token to validate received payloads
.form-group
= f.label :url, "Trigger", class: 'control-label'
.col-sm-10.prepend-top-10
%div
System hook will be triggered on set of events like creating project
or adding ssh key. But you can also enable extra triggers like Push events.
.prepend-top-default
= f.check_box :push_events, class: 'pull-left'
.prepend-left-20
= f.label :push_events, class: 'list-label' do
%strong Push events
%p.light
This url will be triggered by a push to the repository
%div
= f.check_box :tag_push_events, class: 'pull-left'
.prepend-left-20
= f.label :tag_push_events, class: 'list-label' do
%strong Tag push events
%p.light
This url will be triggered when a new tag is pushed to the repository
.form-group
= f.label :enable_ssl_verification, "SSL verification", class: 'control-label checkbox'
.col-sm-10
.checkbox
= f.label :enable_ssl_verification do
= f.check_box :enable_ssl_verification
%strong Enable SSL verification
.form-actions .form-actions
= f.submit "Add system hook", class: "btn btn-create" = f.submit 'Add system hook', class: 'btn btn-create'
%hr %hr
- if @hooks.any? - if @hooks.any?
...@@ -62,11 +22,12 @@ ...@@ -62,11 +22,12 @@
- @hooks.each do |hook| - @hooks.each do |hook|
%li %li
.controls .controls
= link_to 'Test hook', admin_hook_test_path(hook), class: "btn btn-sm" = link_to 'Test hook', test_admin_hook_path(hook), class: 'btn btn-sm'
= link_to 'Remove', admin_hook_path(hook), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-remove btn-sm" = link_to 'Edit', edit_admin_hook_path(hook), class: 'btn btn-sm'
= link_to 'Remove', admin_hook_path(hook), data: { confirm: 'Are you sure?' }, method: :delete, class: 'btn btn-remove btn-sm'
.monospace= hook.url .monospace= hook.url
%div %div
- %w(push_events tag_push_events issues_events note_events merge_requests_events build_events).each do |trigger| - %w(push_events tag_push_events issues_events note_events merge_requests_events build_events).each do |trigger|
- if hook.send(trigger) - if hook.send(trigger)
%span.label.label-gray= trigger.titleize %span.label.label-gray= trigger.titleize
%span.label.label-gray SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"} %span.label.label-gray SSL Verification: #{hook.enable_ssl_verification ? 'enabled' : 'disabled'}
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
%ul.nav-links %ul.nav-links
= nav_link(page: dashboard_groups_path) do = nav_link(page: dashboard_groups_path) do
= link_to dashboard_groups_path, title: 'Your groups' do = link_to dashboard_groups_path, title: 'Your groups' do
Your Groups Your groups
= nav_link(page: explore_groups_path) do = nav_link(page: explore_groups_path) do
= link_to explore_groups_path, title: 'Explore groups' do = link_to explore_groups_path, title: 'Explore public groups' do
Explore Groups Explore public groups
.nav-controls .nav-controls
= render 'shared/groups/search_form' = render 'shared/groups/search_form'
= render 'shared/groups/dropdown' = render 'shared/groups/dropdown'
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
.title-item.author-name .title-item.author-name
- if todo.author - if todo.author
= link_to_author(todo) = link_to_author(todo, self_added: todo.self_added?)
- else - else
(removed) (removed)
...@@ -22,6 +22,10 @@ ...@@ -22,6 +22,10 @@
- else - else
(removed) (removed)
- if todo.self_assigned?
.title-item.action-name
to yourself
.title-item .title-item
&middot; &middot;
......
...@@ -7,6 +7,15 @@ ...@@ -7,6 +7,15 @@
= render 'explore/head' = render 'explore/head'
= render 'nav' = render 'nav'
- if cookies[:explore_groups_landing_dismissed] != 'true'
.explore-groups.landing.content-block.js-explore-groups-landing.hidden
%button.dismiss-button{ type: 'button', 'aria-label' => 'Dismiss' }= icon('times')
.svg-container
= custom_icon('icon_explore_groups_splash')
.inner-content
%p Below you will find all the groups that are public.
%p You can easily contribute to them by requesting to join these groups.
- if @groups.present? - if @groups.present?
= render 'groups' = render 'groups'
- else - else
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
.row .row
.col-md-8 .col-md-8
.documentation-index .documentation-index
= preserve do
= markdown(@help_index) = markdown(@help_index)
.col-md-4 .col-md-4
.panel.panel-default .panel.panel-default
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
%div{ class: container_class } %div{ class: container_class }
.wiki-holder.prepend-top-default.append-bottom-default .wiki-holder.prepend-top-default.append-bottom-default
.wiki .wiki
= preserve do
= render_wiki_content(@wiki_home) = render_wiki_content(@wiki_home)
- else - else
- can_create_wiki = can?(current_user, :create_wiki, @project) - can_create_wiki = can?(current_user, :create_wiki, @project)
......
...@@ -15,8 +15,13 @@ ...@@ -15,8 +15,13 @@
= render 'projects/blob/viewer_switcher', blob: blob unless blame = render 'projects/blob/viewer_switcher', blob: blob unless blame
.btn-group{ role: "group" }< .btn-group{ role: "group" }<
<<<<<<< HEAD
= copy_blob_source_button(blob) if !blame && blob.rendered_as_text?(ignore_errors: false) = copy_blob_source_button(blob) if !blame && blob.rendered_as_text?(ignore_errors: false)
= open_raw_file_button(namespace_project_raw_path(@project.namespace, @project, @id)) = open_raw_file_button(namespace_project_raw_path(@project.namespace, @project, @id))
=======
= copy_blob_source_button(blob) unless blame
= open_raw_blob_button(blob)
>>>>>>> ce-com/master
= view_on_environment_button(@commit.sha, @path, @environment) if @environment = view_on_environment_button(@commit.sha, @path, @environment) if @environment
.btn-group{ role: "group" }< .btn-group{ role: "group" }<
...@@ -36,9 +41,12 @@ ...@@ -36,9 +41,12 @@
tree_join(@commit.sha, @path)), class: 'btn btn-sm js-data-file-blob-permalink-url' tree_join(@commit.sha, @path)), class: 'btn btn-sm js-data-file-blob-permalink-url'
.btn-group{ role: "group" }< .btn-group{ role: "group" }<
<<<<<<< HEAD
- if current_user - if current_user
= lock_file_link(html_options: {class: 'btn btn-sm path-lock'}) = lock_file_link(html_options: {class: 'btn btn-sm path-lock'})
=======
>>>>>>> ce-com/master
= edit_blob_link if blob.readable_text? = edit_blob_link if blob.readable_text?
- if current_user - if current_user
= replace_blob_link = replace_blob_link
......
- blob = viewer.blob - blob = viewer.blob
<<<<<<< HEAD
.file-content.wiki .file-content.wiki
= markup(blob.name, blob.data) = markup(blob.name, blob.data)
=======
- rendered_markup = blob.rendered_markup if blob.respond_to?(:rendered_markup)
.file-content.wiki
= markup(blob.name, blob.data, rendered: rendered_markup)
>>>>>>> ce-com/master
.file-content.video
%video{ src: blob_raw_url, controls: true, data: { setup: '{}' } }
= render 'shared/web_hooks/form', hook: @hook, hooks: @hooks, url_components: [@project.namespace.becomes(Namespace), @project] .row.prepend-top-default
.col-lg-3
%h4.prepend-top-0
= page_title
%p
#{link_to 'Webhooks', help_page_path('user/project/integrations/webhooks')} can be
used for binding events when something is happening within the project.
.col-lg-9.append-bottom-default
= form_for @hook, as: :hook, url: polymorphic_path([@project.namespace.becomes(Namespace), @project, :hooks]) do |f|
= render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
= f.submit 'Add webhook', class: 'btn btn-create'
%hr
%h5.prepend-top-default
Webhooks (#{@hooks.count})
- if @hooks.any?
%ul.well-list
- @hooks.each do |hook|
= render 'project_hook', hook: hook
- else
%p.settings-message.text-center.append-bottom-0
No webhooks found, add one in the form above.
= render 'projects/settings/head'
.row.prepend-top-default
.col-lg-3
%h4.prepend-top-0
= page_title
%p
#{link_to 'Webhooks', help_page_path('user/project/integrations/webhooks')} can be
used for binding events when something is happening within the project.
.col-lg-9.append-bottom-default
= form_for [@project.namespace.becomes(Namespace), @project, @hook], as: :hook, url: namespace_project_hook_path do |f|
= render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
= f.submit 'Save changes', class: 'btn btn-create'
...@@ -58,7 +58,6 @@ ...@@ -58,7 +58,6 @@
- if @issue.description.present? - if @issue.description.present?
.description{ class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : '' } .description{ class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : '' }
.wiki .wiki
= preserve do
= markdown_field(@issue, :description) = markdown_field(@issue, :description)
%textarea.hidden.js-task-list-field %textarea.hidden.js-task-list-field
= @issue.description = @issue.description
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
.panel-heading .panel-heading
Target branch Target branch
.panel-body.clearfix .panel-body.clearfix
- projects = @project.forked_from_project.nil? ? [@project] : [@project, @project.forked_from_project] - projects = target_projects(@project)
.merge-request-select.dropdown .merge-request-select.dropdown
= f.hidden_field :target_project_id = f.hidden_field :target_project_id
= dropdown_toggle f.object.target_project.path_with_namespace, { toggle: "dropdown", field_name: "#{f.object_name}[target_project_id]", disabled: @merge_request.persisted? }, { toggle_class: "js-compare-dropdown js-target-project" } = dropdown_toggle f.object.target_project.path_with_namespace, { toggle: "dropdown", field_name: "#{f.object_name}[target_project_id]", disabled: @merge_request.persisted? }, { toggle_class: "js-compare-dropdown js-target-project" }
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
- if @merge_request.description.present? - if @merge_request.description.present?
.description{ class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : '' } .description{ class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : '' }
.wiki .wiki
= preserve do
= markdown_field(@merge_request, :description) = markdown_field(@merge_request, :description)
%textarea.hidden.js-task-list-field %textarea.hidden.js-task-list-field
= @merge_request.description = @merge_request.description
......
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
- if @milestone.description.present? - if @milestone.description.present?
.description .description
.wiki .wiki
= preserve do
= markdown_field(@milestone, :description) = markdown_field(@milestone, :description)
= render 'shared/milestones/burndown', milestone: @milestone, project: @project, burndown: @burndown = render 'shared/milestones/burndown', milestone: @milestone, project: @project, burndown: @burndown
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment