Merge branch 'master' into per-project-pipeline-iid
This commit is contained in:
commit
f61666c0d7
|
@ -10,3 +10,7 @@ lib/gitlab/background_migration/*
|
|||
app/models/project_services/kubernetes_service.rb
|
||||
lib/gitlab/workhorse.rb
|
||||
lib/gitlab/ci/trace/chunked_io.rb
|
||||
lib/gitlab/gitaly_client/ref_service.rb
|
||||
lib/gitlab/gitaly_client/commit_service.rb
|
||||
lib/gitlab/git/commit.rb
|
||||
lib/gitlab/git/tag.rb
|
||||
|
|
|
@ -126,6 +126,23 @@ stages:
|
|||
<<: *dedicated-no-docs-pull-cache-job
|
||||
<<: *except-docs-and-qa
|
||||
|
||||
.single-script-job: &single-script-job
|
||||
image: ruby:2.4-alpine
|
||||
before_script: []
|
||||
stage: build
|
||||
cache: {}
|
||||
dependencies: []
|
||||
variables: &single-script-job-variables
|
||||
GIT_STRATEGY: none
|
||||
before_script:
|
||||
# We need to download the script rather than clone the repo since the
|
||||
# package-and-qa job will not be able to run when the branch gets
|
||||
# deleted (when merging the MR).
|
||||
- export SCRIPT_NAME="${SCRIPT_NAME:-$CI_JOB_NAME}"
|
||||
- apk add --update openssl
|
||||
- wget $CI_PROJECT_URL/raw/$CI_COMMIT_SHA/scripts/$SCRIPT_NAME
|
||||
- chmod 755 $SCRIPT_NAME
|
||||
|
||||
.rake-exec: &rake-exec
|
||||
<<: *dedicated-no-docs-no-db-pull-cache-job
|
||||
script:
|
||||
|
@ -189,7 +206,7 @@ stages:
|
|||
<<: *dedicated-no-docs-and-no-qa-pull-cache-job
|
||||
<<: *use-pg
|
||||
variables:
|
||||
CREATE_DB_USER: "true"
|
||||
SETUP_DB: "false"
|
||||
script:
|
||||
# Manually clone gitlab-test and only seed this project in
|
||||
# db/fixtures/development/04_project.rb thanks to SIZE=1 below
|
||||
|
@ -207,19 +224,10 @@ stages:
|
|||
.review-docs: &review-docs
|
||||
<<: *dedicated-runner
|
||||
<<: *except-qa
|
||||
image: ruby:2.4-alpine
|
||||
before_script:
|
||||
- gem install gitlab --no-doc
|
||||
# We need to download the script rather than clone the repo since the
|
||||
# review-docs-cleanup job will not be able to run when the branch gets
|
||||
# deleted (when merging the MR).
|
||||
- apk add --update openssl
|
||||
- wget https://gitlab.com/gitlab-org/gitlab-ce/raw/master/scripts/trigger-build-docs
|
||||
- chmod 755 trigger-build-docs
|
||||
cache: {}
|
||||
dependencies: []
|
||||
<<: *single-script-job
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
<<: *single-script-job-variables
|
||||
SCRIPT_NAME: trigger-build-docs
|
||||
when: manual
|
||||
only:
|
||||
- branches
|
||||
|
@ -233,7 +241,7 @@ stages:
|
|||
.migration-paths: &migration-paths
|
||||
<<: *dedicated-no-docs-and-no-qa-pull-cache-job
|
||||
variables:
|
||||
CREATE_DB_USER: "true"
|
||||
SETUP_DB: "false"
|
||||
script:
|
||||
- git fetch https://gitlab.com/gitlab-org/gitlab-ce.git v9.3.0
|
||||
- git checkout -f FETCH_HEAD
|
||||
|
@ -242,7 +250,7 @@ stages:
|
|||
- cp config/gitlab.yml.example config/gitlab.yml
|
||||
- bundle exec rake db:drop db:create db:schema:load db:seed_fu
|
||||
- date
|
||||
- git checkout $CI_COMMIT_SHA
|
||||
- git checkout -f $CI_COMMIT_SHA
|
||||
- bundle install $BUNDLE_INSTALL_FLAGS
|
||||
- date
|
||||
- . scripts/prepare_build.sh
|
||||
|
@ -253,23 +261,14 @@ stages:
|
|||
# Trigger a package build in omnibus-gitlab repository
|
||||
#
|
||||
package-and-qa:
|
||||
image: ruby:2.4-alpine
|
||||
before_script: []
|
||||
stage: build
|
||||
cache: {}
|
||||
when: manual
|
||||
<<: *single-script-job
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
<<: *single-script-job-variables
|
||||
SCRIPT_NAME: trigger-build-omnibus
|
||||
retry: 0
|
||||
before_script:
|
||||
# We need to download the script rather than clone the repo since the
|
||||
# package-and-qa job will not be able to run when the branch gets
|
||||
# deleted (when merging the MR).
|
||||
- apk add --update openssl
|
||||
- wget https://gitlab.com/$CI_PROJECT_PATH/raw/$CI_COMMIT_SHA/scripts/trigger-build-omnibus
|
||||
- chmod 755 trigger-build-omnibus
|
||||
script:
|
||||
- ./trigger-build-omnibus
|
||||
- ./$SCRIPT_NAME
|
||||
when: manual
|
||||
only:
|
||||
- //@gitlab-org/gitlab-ce
|
||||
- //@gitlab-org/gitlab-ee
|
||||
|
@ -286,7 +285,8 @@ review-docs-deploy:
|
|||
url: http://$DOCS_GITLAB_REPO_SUFFIX-$CI_COMMIT_REF_SLUG.$DOCS_REVIEW_APPS_DOMAIN/$DOCS_GITLAB_REPO_SUFFIX
|
||||
on_stop: review-docs-cleanup
|
||||
script:
|
||||
- ./trigger-build-docs deploy
|
||||
- gem install gitlab --no-ri --no-rdoc
|
||||
- ./$SCRIPT_NAME deploy
|
||||
|
||||
# Cleanup remote environment of gitlab-docs
|
||||
review-docs-cleanup:
|
||||
|
@ -296,7 +296,26 @@ review-docs-cleanup:
|
|||
name: review-docs/$CI_COMMIT_REF_NAME
|
||||
action: stop
|
||||
script:
|
||||
- ./trigger-build-docs cleanup
|
||||
- gem install gitlab --no-ri --no-rdoc
|
||||
- ./SCRIPT_NAME cleanup
|
||||
|
||||
##
|
||||
# Trigger a docker image build in CNG (Cloud Native GitLab) repository
|
||||
#
|
||||
cloud-native-image:
|
||||
image: ruby:2.4-alpine
|
||||
before_script: []
|
||||
stage: build
|
||||
allow_failure: true
|
||||
cache: {}
|
||||
before_script:
|
||||
- gem install gitlab --no-rdoc --no-ri
|
||||
- chmod 755 ./scripts/trigger-build-cloud-native
|
||||
script:
|
||||
- ./scripts/trigger-build-cloud-native
|
||||
only:
|
||||
- tags@gitlab-org/gitlab-ce
|
||||
- tags@gitlab-org/gitlab-ee
|
||||
|
||||
# Retrieve knapsack and rspec_flaky reports
|
||||
retrieve-tests-metadata:
|
||||
|
@ -325,7 +344,7 @@ update-tests-metadata:
|
|||
- rspec_flaky/
|
||||
policy: push
|
||||
script:
|
||||
- retry gem install fog-aws mime-types activesupport
|
||||
- retry gem install fog-aws mime-types activesupport --no-ri --no-rdoc
|
||||
- scripts/merge-reports ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/rspec-pg_node_*.json
|
||||
- scripts/merge-reports ${FLAKY_RSPEC_SUITE_REPORT_PATH} rspec_flaky/all_*_*.json
|
||||
- FLAKY_RSPEC_GENERATE_REPORT=1 scripts/prune-old-flaky-specs ${FLAKY_RSPEC_SUITE_REPORT_PATH}
|
||||
|
|
183
CHANGELOG.md
183
CHANGELOG.md
|
@ -2,6 +2,189 @@
|
|||
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||
entry.
|
||||
|
||||
## 10.8.0 (2018-05-22)
|
||||
|
||||
### Security (3 changes, 1 of them is from the community)
|
||||
|
||||
- Update faraday_middlewar to 0.12.2. !18397 (Takuya Noguchi)
|
||||
- Serve archive requests with the correct file in all cases.
|
||||
- Sanitizes user name to avoid XSS attacks.
|
||||
|
||||
### Fixed (47 changes, 11 of them are from the community)
|
||||
|
||||
- Refactor CSS to eliminate vertical misalignment of login nav. !16275 (Takuya Noguchi)
|
||||
- Fix pipeline status in branch/tag tree page. !17995
|
||||
- Allow group owner to enable runners from subgroups (#41981). !18009
|
||||
- Fix template selector menu visibility when toggling preview mode in file edit view. !18118 (Fabian Schneider)
|
||||
- Fix confirmation modal for deleting a protected branch. !18176 (Paul Bonaud @PaulRbR)
|
||||
- Triggering custom hooks by Wiki UI edit. !18251
|
||||
- Now `rake cache:clear` will also clear pipeline status cache. !18257
|
||||
- Fix `joined` information on project members page. !18290 (Fabian Schneider)
|
||||
- Fix missing namespace for some internal users. !18357
|
||||
- Show shared projects on group page. !18390
|
||||
- Restore label underline color. !18407 (George Tsiolis)
|
||||
- Fix undefined `html_escape` method during markdown rendering. !18418
|
||||
- Fix unassign slash command preview. !18447
|
||||
- Correct text and functionality for delete user / delete user and contributions modal. !18463 (Marc Schwede)
|
||||
- Fix discussions API setting created_at for notable in a group or notable in a project in a group with owners. !18464
|
||||
- Don't include lfs_file_locks data in export bundle. !18495
|
||||
- Reset milestone filter when clicking "Any Milestone" in dashboard. !18531
|
||||
- Ensure member notifications are sent after the member actual creation/update in the DB. !18538
|
||||
- Update links to /ci/lint with ones to project ci/lint. !18539 (Takuya Noguchi)
|
||||
- Fix tabs container styles to make RSS button clickable. !18559
|
||||
- Raise NoRepository error for non-valid repositories when calculating repository checksum. !18594
|
||||
- Don't automatically remove artifacts for pages jobs after pages:deploy has run. !18628
|
||||
- Increase new issue metadata form margin. !18630 (George Tsiolis)
|
||||
- Add loading icon padding for pipeline environments. !18631 (George Tsiolis)
|
||||
- ShaAttribute no longer stops startup if database is missing. !18726
|
||||
- Fix close keyboard shortcuts dialog using the keyboard shortcut. !18783 (Lars Greiss)
|
||||
- Fixes database inconsistencies between Community and Enterprise Edition on import state. !18811
|
||||
- Add database foreign key constraint between pipelines and build. !18822
|
||||
- Fix finding wiki pages when they have invalidly-encoded content. !18856
|
||||
- Fix outdated Web IDE welcome copy. !18861
|
||||
- fixed copy to blipboard button in embed bar of snippets. !18923 (haseebeqx)
|
||||
- Disables RBAC on nginx-ingress. !18947
|
||||
- Correct skewed Kubernetes popover illustration. !18949
|
||||
- Resolve Import/Export ci_cd_settings error updating the project. !46049
|
||||
- Fix project creation for user endpoint when jobs_enabled parameter supplied.
|
||||
- 46210 Display logo and user dropdown on mobile for terms page and fix styling.
|
||||
- Adds illustration for when job log was erased.
|
||||
- Ensure web hook 'blocked URL' errors are stored in web hook logs and properly surfaced to the user.
|
||||
- Make toggle markdown preview shortcut only toggle selected field.
|
||||
- Verifiy if pipeline has commit idetails and render information in MR widget when branch is deleted.
|
||||
- Fixed inconsistent protected branch pill baseline.
|
||||
- Fix setting Gitlab metrics content types.
|
||||
- Display only generic message on merge error to avoid exposing any potentially sensitive or user unfriendly backend messages.
|
||||
- Fix label links update on project transfer.
|
||||
- Breaks commit not found message in pipelines table.
|
||||
- Adjust issue boards list header label text color.
|
||||
- Prevent pipeline actions in dropdown to redirct to a new page.
|
||||
|
||||
### Changed (35 changes, 15 of them are from the community)
|
||||
|
||||
- Improve tooltips in collapsed right sidebar. !17714
|
||||
- Partition job_queue_duration_seconds with jobs_running_for_project. !17730
|
||||
- For group dashboard, we no longer show groups which the visitor is not a member of (this applies to admins and auditors). !17884 (Roger Rüttimann)
|
||||
- Use RFC 3676 mail signature delimiters. !17979 (Enrico Scholz)
|
||||
- Add sha filter to pipelines list API. !18125
|
||||
- New CI Job live-trace architecture. !18169
|
||||
- Make project deploy keys table more clearly structured. !18279
|
||||
- Remove green background from unlock button in admin area. !18288
|
||||
- Renamed Overview to Project in the contextual navigation at a project level. !18295 (Constance Okoghenun)
|
||||
- Load branches on new merge request page asynchronously. !18315
|
||||
- Create settings section for autodevops. !18321
|
||||
- Add a comma to the time estimate system notes. !18326
|
||||
- Enable specifying variables when executing a manual pipeline. !18440
|
||||
- Fix size and position for fork icon. !18449 (George Tsiolis)
|
||||
- Refactored activity calendar. !18469 (Enrico Scholz)
|
||||
- Small improvements to repository checks. !18484
|
||||
- Add 2FA filter to users API for admins only. !18503
|
||||
- Align project avatar on small viewports. !18513 (George Tsiolis)
|
||||
- Show group and project LFS settings in the interface to Owners and Masters. !18562
|
||||
- Update environment item action buttons icons. !18632 (George Tsiolis)
|
||||
- Update timeline icon for description edit. !18633 (George Tsiolis)
|
||||
- Revert discussion counter height. !18656 (George Tsiolis)
|
||||
- Improve quick actions summary preview. !18659 (George Tsiolis)
|
||||
- Change font for tables inside diff discussions. !18660 (George Tsiolis)
|
||||
- Add padding to profile description. !18663 (George Tsiolis)
|
||||
- Break issue title for board card title and issuable header text. !18674 (George Tsiolis)
|
||||
- Adds push mirrors to GitLab Community Edition. !18715
|
||||
- Inform the user when there are no project import options available. !18716 (George Tsiolis)
|
||||
- Improve commit message body rendering and fix responsive compare panels. !18725 (Constance Okoghenun)
|
||||
- Reconcile project templates with Auto DevOps. !18737
|
||||
- Remove branch name from the status bar of WebIDE.
|
||||
- Clean up WebIDE status bar and add useful info.
|
||||
- Improve interaction on WebIDE commit panel.
|
||||
- Keep current labels visible when editing them in the sidebar.
|
||||
- Use VueJS for rendering pipeline stages.
|
||||
|
||||
### Performance (26 changes, 11 of them are from the community)
|
||||
|
||||
- Move WorkInProgress vue component. !17536 (George Tsiolis)
|
||||
- Move ReadyToMerge vue component. !17545 (George Tsiolis)
|
||||
- Move BoardBlankState vue component. !17666 (George Tsiolis)
|
||||
- Improve DB performance of calculating total artifacts size. !17839
|
||||
- Add i18n and update specs for UnresolvedDiscussions vue component. !17866 (George Tsiolis)
|
||||
- Introduce new ProjectCiCdSetting model with group_runners_enabled. !18144
|
||||
- Move PipelineFailed vue component. !18277 (George Tsiolis)
|
||||
- Move TimeTrackingEstimateOnlyPane vue component. !18318 (George Tsiolis)
|
||||
- Move TimeTrackingHelpState vue component. !18319 (George Tsiolis)
|
||||
- Reduce queries on merge requests list page for merge requests from forks. !18561
|
||||
- Destroy build_chunks efficiently with FastDestroyAll module. !18575
|
||||
- Improve performance of a service responsible for creating a pipeline. !18582
|
||||
- Replace time_ago_in_words with JS-based one. !18607 (Takuya Noguchi)
|
||||
- Move TimeTrackingNoTrackingPane vue component. !18676 (George Tsiolis)
|
||||
- Move SidebarTimeTracking vue component. !18677 (George Tsiolis)
|
||||
- Move TimeTrackingSpentOnlyPane vue component. !18710 (George Tsiolis)
|
||||
- Detecting tags containing a commit uses Gitaly by default.
|
||||
- Increase cluster applications installer availability using alpine linux mirrors.
|
||||
- Compute notification recipients in background jobs.
|
||||
- Use persisted diff data instead fetching Git on discussions.
|
||||
- Detecting branchnames containing a commit uses Gitaly by default.
|
||||
- Detect repository license on Gitaly by default.
|
||||
- Finish NamespaceService migration to Gitaly.
|
||||
- Check if a ref exists is done by Gitaly by default.
|
||||
- Compute Gitlab::Git::Repository#checksum on Gitaly by default.
|
||||
- Repository#exists? is always executed through Gitaly.
|
||||
|
||||
### Added (22 changes, 10 of them are from the community)
|
||||
|
||||
- Allow group masters to configure runners for groups. !9646 (Alexis Reigel)
|
||||
- Adds Embedded Snippets Support. !15695 (haseebeqx)
|
||||
- Add Copy metadata quick action. !16473 (Mateusz Bajorski)
|
||||
- Show Runner's description on job's page. !17321
|
||||
- Add deprecation message to dynamic milestone pages. !17505
|
||||
- Show new branch/mr button even when branch exists. !17712 (Jacopo Beschi @jacopo-beschi)
|
||||
- API: add languages of project GET /projects/:id/languages. !17770 (Roger Rüttimann)
|
||||
- Display active sessions and allow the user to revoke any of it. !17867 (Alexis Reigel)
|
||||
- Add cron job to email users on issue due date. !17985 (Stuart Nelson)
|
||||
- Rubocop rule to avoid returning from a block. !18000 (Jacopo Beschi @jacopo-beschi)
|
||||
- Add the signature verfication badge to the compare view. !18245 (Marc Shaw)
|
||||
- Expose Deploy Token data as environment varialbes on CI/CD jobs. !18414
|
||||
- Show group id in group settings. !18482 (George Tsiolis)
|
||||
- Allow admins to enforce accepting Terms of Service on an instance. !18570
|
||||
- Add CI_COMMIT_MESSAGE, CI_COMMIT_TITLE and CI_COMMIT_DESCRIPTION predefined variables. !18672
|
||||
- Add GCP signup offer to cluster index / create pages. !18684
|
||||
- Output some useful information when running the rails console. !18697
|
||||
- Display merge commit SHA in merge widget after merge. !18722
|
||||
- git SHA is now displayed alongside the GitLab version on the Admin Dashboard.
|
||||
- Expose the target commit ID through the tag API.
|
||||
- Added fuzzy file finder to web IDE.
|
||||
- Add discussion API for merge requests and commits.
|
||||
|
||||
### Other (22 changes, 8 of them are from the community)
|
||||
|
||||
- Replace the `project/issues/milestones.feature` spinach test with an rspec analog. !18300 (@blackst0ne)
|
||||
- Replace the `project/commits/branches.feature` spinach test with an rspec analog. !18302 (@blackst0ne)
|
||||
- Replacing gollum libraries for gitlab custom libs. !18343
|
||||
- Replace the `project/commits/comments.feature` spinach test with an rspec analog. !18356 (@blackst0ne)
|
||||
- Replace "Click" with "Select" to be more inclusive of people with accessibility requirements. !18386 (Mark Lapierre)
|
||||
- Remove ahead/behind graphs on project branches on mobile. !18415 (Takuya Noguchi)
|
||||
- Replace the `project/source/markdown_render.feature` spinach test with an rspec analog. !18525 (@blackst0ne)
|
||||
- Add missing changelog type to docs. !18526 (@blackst0ne)
|
||||
- Added Webhook SSRF prevention to documentation. !18532
|
||||
- Upgrade underscore.js to 1.9.0. !18578
|
||||
- Add documentation about how to use variables to define deploy policies for staging/production environments. !18675
|
||||
- Replace the `project/builds/artifacts.feature` spinach test with an rspec analog. !18729 (@blackst0ne)
|
||||
- Block access to the API & git for users that did not accept enforced Terms of Service. !18816
|
||||
- Transition to atomic internal ids for all models. !44259
|
||||
- Removes modal boards store and mixins from global scope.
|
||||
- Replace GKE acronym with Google Kubernetes Engine.
|
||||
- Replace vue resource with axios for pipelines details page.
|
||||
- Enable prometheus monitoring by default.
|
||||
- Replace vue resource with axios in pipelines table.
|
||||
- Bump lograge to 0.10.0 and remove monkey patch.
|
||||
- Improves wording in new pipeline page.
|
||||
- Gitaly handles repository forks by default.
|
||||
|
||||
|
||||
## 10.7.4 (2018-05-21)
|
||||
|
||||
### Fixed (1 change)
|
||||
|
||||
- Fix error when deleting an empty list of refs.
|
||||
|
||||
|
||||
## 10.7.3 (2018-05-02)
|
||||
|
||||
### Fixed (8 changes)
|
||||
|
|
|
@ -168,7 +168,7 @@ hits. They are not always necessary, but very convenient.
|
|||
|
||||
If you are an expert in a particular area, it makes it easier to find issues to
|
||||
work on. You can also subscribe to those labels to receive an email each time an
|
||||
issue is labelled with a subject label corresponding to your expertise.
|
||||
issue is labeled with a subject label corresponding to your expertise.
|
||||
|
||||
Examples of subject labels are ~wiki, ~"container registry", ~ldap, ~api,
|
||||
~issues, ~"merge requests", ~labels, and ~"container registry".
|
||||
|
@ -296,7 +296,24 @@ any potential community contributor to @-mention per above.
|
|||
|
||||
## Implement design & UI elements
|
||||
|
||||
Please see the [UX Guide for GitLab].
|
||||
For guidance on UX implementation at GitLab, please refer to our [Design System](https://design.gitlab.com/).
|
||||
|
||||
The UX team uses labels to manage their workflow.
|
||||
|
||||
The ~"UX" label on an issue is a signal to the UX team that it will need UX attention.
|
||||
To better understand the priority by which UX tackles issues, see the [UX section](https://about.gitlab.com/handbook/ux/) of the handbook.
|
||||
|
||||
Once an issue has been worked on and is ready for development, a UXer applies the ~"UX ready" label to that issue.
|
||||
|
||||
The UX team has a special type label called ~"design artifact". This label indicates that the final output
|
||||
for an issue is a UX solution/design. The solution will be developed by frontend and/or backend in a subsequent milestone.
|
||||
Any issue labeled ~"design artifact" should not also be labeled ~"frontend" or ~"backend" since no development is
|
||||
needed until the solution has been decided.
|
||||
|
||||
~"design artifact" issues are like any other issue and should contain a milestone label, ~"Deliverable" or ~"Stretch", when scheduled in the current milestone.
|
||||
|
||||
Once the ~"design artifact" issue has been completed, the UXer removes the ~"design artifact" label and applies the ~"UX ready" label. The Product Manager can use the
|
||||
existing issue or decide to create a whole new issue for the purpose of development.
|
||||
|
||||
## Issue tracker
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.100.0
|
||||
0.102.0
|
||||
|
|
3
Gemfile
3
Gemfile
|
@ -174,6 +174,9 @@ gem 'httparty', '~> 0.13.3'
|
|||
# Colored output to console
|
||||
gem 'rainbow', '~> 2.2'
|
||||
|
||||
# Progress bar
|
||||
gem 'ruby-progressbar'
|
||||
|
||||
# GitLab settings
|
||||
gem 'settingslogic', '~> 2.0.9'
|
||||
|
||||
|
|
|
@ -1150,6 +1150,7 @@ DEPENDENCIES
|
|||
rubocop-rspec (~> 1.22.1)
|
||||
ruby-fogbugz (~> 0.2.1)
|
||||
ruby-prof (~> 0.17.0)
|
||||
ruby-progressbar
|
||||
ruby_parser (~> 3.8)
|
||||
rufus-scheduler (~> 3.4)
|
||||
rugged (~> 0.27)
|
||||
|
|
|
@ -68,8 +68,7 @@
|
|||
this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', showLoader);
|
||||
|
||||
this.service.getFolderContent(folder.folder_path)
|
||||
.then(resp => resp.json())
|
||||
.then(response => this.store.setfolderContent(folder, response.environments))
|
||||
.then(response => this.store.setfolderContent(folder, response.data.environments))
|
||||
.then(() => this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', false))
|
||||
.catch(() => {
|
||||
Flash(s__('Environments|An error occurred while fetching the environments.'));
|
||||
|
|
|
@ -6,7 +6,6 @@ import Visibility from 'visibilityjs';
|
|||
import Poll from '../../lib/utils/poll';
|
||||
import {
|
||||
getParameterByName,
|
||||
parseQueryStringIntoObject,
|
||||
} from '../../lib/utils/common_utils';
|
||||
import { s__ } from '../../locale';
|
||||
import Flash from '../../flash';
|
||||
|
@ -46,17 +45,14 @@ export default {
|
|||
|
||||
methods: {
|
||||
saveData(resp) {
|
||||
const headers = resp.headers;
|
||||
return resp.json().then((response) => {
|
||||
this.isLoading = false;
|
||||
this.isLoading = false;
|
||||
|
||||
if (_.isEqual(parseQueryStringIntoObject(resp.url.split('?')[1]), this.requestData)) {
|
||||
this.store.storeAvailableCount(response.available_count);
|
||||
this.store.storeStoppedCount(response.stopped_count);
|
||||
this.store.storeEnvironments(response.environments);
|
||||
this.store.setPagination(headers);
|
||||
}
|
||||
});
|
||||
if (_.isEqual(resp.config.params, this.requestData)) {
|
||||
this.store.storeAvailableCount(resp.data.available_count);
|
||||
this.store.storeStoppedCount(resp.data.stopped_count);
|
||||
this.store.storeEnvironments(resp.data.environments);
|
||||
this.store.setPagination(resp.headers);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -70,7 +66,7 @@ export default {
|
|||
updateContent(parameters) {
|
||||
this.updateInternalState(parameters);
|
||||
// fetch new data
|
||||
return this.service.get(this.requestData)
|
||||
return this.service.fetchEnvironments(this.requestData)
|
||||
.then(response => this.successCallback(response))
|
||||
.then(() => {
|
||||
// restart polling
|
||||
|
@ -105,7 +101,7 @@ export default {
|
|||
fetchEnvironments() {
|
||||
this.isLoading = true;
|
||||
|
||||
return this.service.get(this.requestData)
|
||||
return this.service.fetchEnvironments(this.requestData)
|
||||
.then(this.successCallback)
|
||||
.catch(this.errorCallback);
|
||||
},
|
||||
|
@ -141,7 +137,7 @@ export default {
|
|||
|
||||
this.poll = new Poll({
|
||||
resource: this.service,
|
||||
method: 'get',
|
||||
method: 'fetchEnvironments',
|
||||
data: this.requestData,
|
||||
successCallback: this.successCallback,
|
||||
errorCallback: this.errorCallback,
|
||||
|
|
|
@ -1,25 +1,22 @@
|
|||
/* eslint-disable class-methods-use-this */
|
||||
import Vue from 'vue';
|
||||
import VueResource from 'vue-resource';
|
||||
|
||||
Vue.use(VueResource);
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
|
||||
export default class EnvironmentsService {
|
||||
constructor(endpoint) {
|
||||
this.environments = Vue.resource(endpoint);
|
||||
this.environmentsEndpoint = endpoint;
|
||||
this.folderResults = 3;
|
||||
}
|
||||
|
||||
get(options = {}) {
|
||||
fetchEnvironments(options = {}) {
|
||||
const { scope, page } = options;
|
||||
return this.environments.get({ scope, page });
|
||||
return axios.get(this.environmentsEndpoint, { params: { scope, page } });
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
postAction(endpoint) {
|
||||
return Vue.http.post(endpoint, {}, { emulateJSON: true });
|
||||
return axios.post(endpoint, {}, { emulateJSON: true });
|
||||
}
|
||||
|
||||
getFolderContent(folderUrl) {
|
||||
return Vue.http.get(`${folderUrl}.json?per_page=${this.folderResults}`);
|
||||
return axios.get(`${folderUrl}.json?per_page=${this.folderResults}`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import LoadingButton from '~/vue_shared/components/loading_button.vue';
|
|||
import CommitMessageField from './message_field.vue';
|
||||
import Actions from './actions.vue';
|
||||
import SuccessMessage from './success_message.vue';
|
||||
import { activityBarViews, MAX_WINDOW_HEIGHT_COMPACT, COMMIT_ITEM_PADDING } from '../../constants';
|
||||
import { activityBarViews, MAX_WINDOW_HEIGHT_COMPACT } from '../../constants';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -70,7 +70,7 @@ export default {
|
|||
? this.$refs.formEl && this.$refs.formEl.offsetHeight
|
||||
: this.$refs.compactEl && this.$refs.compactEl.offsetHeight;
|
||||
|
||||
this.componentHeight = elHeight + COMMIT_ITEM_PADDING;
|
||||
this.componentHeight = elHeight;
|
||||
},
|
||||
enterTransition() {
|
||||
this.$nextTick(() => {
|
||||
|
@ -78,7 +78,7 @@ export default {
|
|||
? this.$refs.compactEl && this.$refs.compactEl.offsetHeight
|
||||
: this.$refs.formEl && this.$refs.formEl.offsetHeight;
|
||||
|
||||
this.componentHeight = elHeight + COMMIT_ITEM_PADDING;
|
||||
this.componentHeight = elHeight;
|
||||
});
|
||||
},
|
||||
afterEndTransition() {
|
||||
|
|
|
@ -122,11 +122,11 @@ export default {
|
|||
<div
|
||||
class="file"
|
||||
:class="fileClass"
|
||||
@click="clickFile"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="file-name"
|
||||
@click="clickFile"
|
||||
role="button"
|
||||
>
|
||||
<span
|
||||
class="ide-file-name str-truncated"
|
||||
|
|
|
@ -5,8 +5,6 @@ export const FILE_FINDER_EMPTY_ROW_HEIGHT = 33;
|
|||
|
||||
export const MAX_WINDOW_HEIGHT_COMPACT = 750;
|
||||
|
||||
export const COMMIT_ITEM_PADDING = 32;
|
||||
|
||||
// Commit message textarea
|
||||
export const MAX_TITLE_LENGTH = 50;
|
||||
export const MAX_BODY_LENGTH = 72;
|
||||
|
|
|
@ -93,10 +93,13 @@ export default {
|
|||
v-html="actionTextHtml"
|
||||
class="system-note-message">
|
||||
</span>
|
||||
<span class="system-note-separator">
|
||||
·
|
||||
</span>
|
||||
<a
|
||||
:href="noteTimestampLink"
|
||||
@click="updateTargetNoteHash"
|
||||
class="note-timestamp">
|
||||
class="note-timestamp system-note-separator">
|
||||
<time-ago-tooltip
|
||||
:time="createdAt"
|
||||
tooltip-placement="bottom"
|
||||
|
|
|
@ -1,11 +1,21 @@
|
|||
<script>
|
||||
import $ from 'jquery';
|
||||
import tooltip from '../../../vue_shared/directives/tooltip';
|
||||
import Icon from '../../../vue_shared/components/icon.vue';
|
||||
import { dasherize } from '../../../lib/utils/text_utility';
|
||||
import eventHub from '../../event_hub';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { dasherize } from '~/lib/utils/text_utility';
|
||||
import { __ } from '~/locale';
|
||||
import createFlash from '~/flash';
|
||||
import tooltip from '~/vue_shared/directives/tooltip';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
|
||||
/**
|
||||
* Renders either a cancel, retry or play icon pointing to the given path.
|
||||
* Renders either a cancel, retry or play icon button and handles the post request
|
||||
*
|
||||
* Used in:
|
||||
* - mr widget mini pipeline graph: `mr_widget_pipeline.vue`
|
||||
* - pipelines table
|
||||
* - pipelines table in merge request page
|
||||
* - pipelines table in commit page
|
||||
* - pipelines detail page in big graph
|
||||
*/
|
||||
export default {
|
||||
components: {
|
||||
|
@ -32,16 +42,10 @@ export default {
|
|||
required: true,
|
||||
},
|
||||
|
||||
requestFinishedFor: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isDisabled: false,
|
||||
linkRequested: '',
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -51,19 +55,28 @@ export default {
|
|||
return `${actionIconDash} js-icon-${actionIconDash}`;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
requestFinishedFor() {
|
||||
if (this.requestFinishedFor === this.linkRequested) {
|
||||
this.isDisabled = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* The request should not be handled here.
|
||||
* However due to this component being used in several
|
||||
* different apps it avoids repetition & complexity.
|
||||
*
|
||||
*/
|
||||
onClickAction() {
|
||||
$(this.$el).tooltip('hide');
|
||||
eventHub.$emit('postAction', this.link);
|
||||
this.linkRequested = this.link;
|
||||
|
||||
this.isDisabled = true;
|
||||
|
||||
axios.post(`${this.link}.json`)
|
||||
.then(() => {
|
||||
this.isDisabled = false;
|
||||
this.$emit('pipelineActionRequestComplete');
|
||||
})
|
||||
.catch(() => {
|
||||
this.isDisabled = false;
|
||||
|
||||
createFlash(__('An error occurred while making the request.'));
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -80,6 +93,6 @@ btn-transparent ci-action-icon-container ci-action-icon-wrapper"
|
|||
data-container="body"
|
||||
:disabled="isDisabled"
|
||||
>
|
||||
<icon :name="actionIcon" />
|
||||
<icon :name="actionIcon"/>
|
||||
</button>
|
||||
</template>
|
||||
|
|
|
@ -42,11 +42,6 @@ export default {
|
|||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
requestFinishedFor: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
@ -76,11 +71,15 @@ export default {
|
|||
e.stopPropagation();
|
||||
});
|
||||
},
|
||||
|
||||
pipelineActionRequestComplete() {
|
||||
this.$emit('pipelineActionRequestComplete');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="ci-job-dropdown-container">
|
||||
<div class="ci-job-dropdown-container dropdown">
|
||||
<button
|
||||
v-tooltip
|
||||
type="button"
|
||||
|
@ -110,7 +109,7 @@ export default {
|
|||
<job-component
|
||||
:job="item"
|
||||
css-class-job-name="mini-pipeline-graph-dropdown-item"
|
||||
:request-finished-for="requestFinishedFor"
|
||||
@pipelineActionRequestComplete="pipelineActionRequestComplete"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -16,11 +16,6 @@ export default {
|
|||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
requestFinishedFor: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
@ -51,6 +46,10 @@ export default {
|
|||
|
||||
return className;
|
||||
},
|
||||
|
||||
refreshPipelineGraph() {
|
||||
this.$emit('refreshPipelineGraph');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -74,7 +73,7 @@ export default {
|
|||
:key="stage.name"
|
||||
:stage-connector-class="stageConnectorClass(index, stage)"
|
||||
:is-first-column="isFirstColumn(index)"
|
||||
:request-finished-for="requestFinishedFor"
|
||||
@refreshPipelineGraph="refreshPipelineGraph"
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -46,11 +46,6 @@ export default {
|
|||
required: false,
|
||||
default: '',
|
||||
},
|
||||
requestFinishedFor: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
status() {
|
||||
|
@ -84,6 +79,11 @@ export default {
|
|||
return this.job.status && this.job.status.action && this.job.status.action.path;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
pipelineActionRequestComplete() {
|
||||
this.$emit('pipelineActionRequestComplete');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
|
@ -126,7 +126,7 @@ export default {
|
|||
:tooltip-text="status.action.title"
|
||||
:link="status.action.path"
|
||||
:action-icon="status.action.icon"
|
||||
:request-finished-for="requestFinishedFor"
|
||||
@pipelineActionRequestComplete="pipelineActionRequestComplete"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -29,12 +29,6 @@ export default {
|
|||
required: false,
|
||||
default: '',
|
||||
},
|
||||
|
||||
requestFinishedFor: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
@ -49,6 +43,10 @@ export default {
|
|||
buildConnnectorClass(index) {
|
||||
return index === 0 && !this.isFirstColumn ? 'left-connector' : '';
|
||||
},
|
||||
|
||||
pipelineActionRequestComplete() {
|
||||
this.$emit('refreshPipelineGraph');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -75,12 +73,13 @@ export default {
|
|||
v-if="job.size === 1"
|
||||
:job="job"
|
||||
css-class-job-name="build-content"
|
||||
@pipelineActionRequestComplete="pipelineActionRequestComplete"
|
||||
/>
|
||||
|
||||
<dropdown-job-component
|
||||
v-if="job.size > 1"
|
||||
:job="job"
|
||||
:request-finished-for="requestFinishedFor"
|
||||
@pipelineActionRequestComplete="pipelineActionRequestComplete"
|
||||
/>
|
||||
|
||||
</li>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import CommitComponent from '../../vue_shared/components/commit.vue';
|
||||
import LoadingButton from '../../vue_shared/components/loading_button.vue';
|
||||
import Icon from '../../vue_shared/components/icon.vue';
|
||||
import { PIPELINES_TABLE } from '../constants';
|
||||
|
||||
/**
|
||||
* Pipeline table row.
|
||||
|
@ -46,6 +47,7 @@
|
|||
required: true,
|
||||
},
|
||||
},
|
||||
pipelinesTable: PIPELINES_TABLE,
|
||||
data() {
|
||||
return {
|
||||
isRetrying: false,
|
||||
|
@ -297,6 +299,7 @@
|
|||
v-for="(stage, index) in pipeline.details.stages"
|
||||
:key="index">
|
||||
<pipeline-stage
|
||||
:type="$options.pipelinesTable"
|
||||
:stage="stage"
|
||||
:update-dropdown="updateGraphDropdown"
|
||||
/>
|
||||
|
|
|
@ -21,6 +21,7 @@ import Icon from '../../vue_shared/components/icon.vue';
|
|||
import LoadingIcon from '../../vue_shared/components/loading_icon.vue';
|
||||
import JobComponent from './graph/job_component.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
import { PIPELINES_TABLE } from '../constants';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -44,6 +45,12 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
|
||||
type: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
|
@ -133,6 +140,16 @@ export default {
|
|||
isDropdownOpen() {
|
||||
return this.$el.classList.contains('open');
|
||||
},
|
||||
|
||||
pipelineActionRequestComplete() {
|
||||
if (this.type === PIPELINES_TABLE) {
|
||||
// warn the table to update
|
||||
eventHub.$emit('refreshPipelinesTable');
|
||||
} else {
|
||||
// close the dropdown in mr widget
|
||||
$(this.$refs.dropdown).dropdown('toggle');
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -151,6 +168,7 @@ export default {
|
|||
id="stageDropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
ref="dropdown"
|
||||
>
|
||||
|
||||
<span
|
||||
|
@ -188,6 +206,7 @@ export default {
|
|||
<job-component
|
||||
:job="job"
|
||||
css-class-job-name="mini-pipeline-graph-dropdown-item"
|
||||
@pipelineActionRequestComplete="pipelineActionRequestComplete"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
// eslint-disable-next-line import/prefer-default-export
|
||||
export const CANCEL_REQUEST = 'CANCEL_REQUEST';
|
||||
export const PIPELINES_TABLE = 'PIPELINES_TABLE';
|
||||
|
|
|
@ -55,11 +55,13 @@ export default {
|
|||
eventHub.$on('postAction', this.postAction);
|
||||
eventHub.$on('retryPipeline', this.postAction);
|
||||
eventHub.$on('clickedDropdown', this.updateTable);
|
||||
eventHub.$on('refreshPipelinesTable', this.fetchPipelines);
|
||||
},
|
||||
beforeDestroy() {
|
||||
eventHub.$off('postAction', this.postAction);
|
||||
eventHub.$off('retryPipeline', this.postAction);
|
||||
eventHub.$off('clickedDropdown', this.updateTable);
|
||||
eventHub.$off('refreshPipelinesTable', this.fetchPipelines);
|
||||
},
|
||||
destroyed() {
|
||||
this.poll.stop();
|
||||
|
|
|
@ -25,30 +25,14 @@ export default () => {
|
|||
data() {
|
||||
return {
|
||||
mediator,
|
||||
requestFinishedFor: null,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
eventHub.$on('postAction', this.postAction);
|
||||
},
|
||||
beforeDestroy() {
|
||||
eventHub.$off('postAction', this.postAction);
|
||||
},
|
||||
methods: {
|
||||
postAction(action) {
|
||||
// Click was made, reset this variable
|
||||
this.requestFinishedFor = null;
|
||||
|
||||
this.mediator.service
|
||||
.postAction(action)
|
||||
.then(() => {
|
||||
this.mediator.refreshPipeline();
|
||||
this.requestFinishedFor = action;
|
||||
})
|
||||
.catch(() => {
|
||||
this.requestFinishedFor = action;
|
||||
Flash(__('An error occurred while making the request.'));
|
||||
});
|
||||
requestRefreshPipelineGraph() {
|
||||
// When an action is clicked
|
||||
// (wether in the dropdown or in the main nodes, we refresh the big graph)
|
||||
this.mediator.refreshPipeline()
|
||||
.catch(() => Flash(__('An error occurred while making the request.')));
|
||||
},
|
||||
},
|
||||
render(createElement) {
|
||||
|
@ -56,7 +40,9 @@ export default () => {
|
|||
props: {
|
||||
isLoading: this.mediator.state.isLoading,
|
||||
pipeline: this.mediator.store.state.pipeline,
|
||||
requestFinishedFor: this.requestFinishedFor,
|
||||
},
|
||||
on: {
|
||||
refreshPipelineGraph: this.requestRefreshPipelineGraph,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@ export default class ShortcutsNavigation extends Shortcuts {
|
|||
super();
|
||||
|
||||
Mousetrap.bind('g p', () => findAndFollowLink('.shortcuts-project'));
|
||||
Mousetrap.bind('g e', () => findAndFollowLink('.shortcuts-project-activity'));
|
||||
Mousetrap.bind('g v', () => findAndFollowLink('.shortcuts-project-activity'));
|
||||
Mousetrap.bind('g f', () => findAndFollowLink('.shortcuts-tree'));
|
||||
Mousetrap.bind('g c', () => findAndFollowLink('.shortcuts-commits'));
|
||||
Mousetrap.bind('g j', () => findAndFollowLink('.shortcuts-builds'));
|
||||
|
@ -16,9 +16,10 @@ export default class ShortcutsNavigation extends Shortcuts {
|
|||
Mousetrap.bind('g i', () => findAndFollowLink('.shortcuts-issues'));
|
||||
Mousetrap.bind('g b', () => findAndFollowLink('.shortcuts-issue-boards'));
|
||||
Mousetrap.bind('g m', () => findAndFollowLink('.shortcuts-merge_requests'));
|
||||
Mousetrap.bind('g t', () => findAndFollowLink('.shortcuts-todos'));
|
||||
Mousetrap.bind('g w', () => findAndFollowLink('.shortcuts-wiki'));
|
||||
Mousetrap.bind('g s', () => findAndFollowLink('.shortcuts-snippets'));
|
||||
Mousetrap.bind('g k', () => findAndFollowLink('.shortcuts-kubernetes'));
|
||||
Mousetrap.bind('g e', () => findAndFollowLink('.shortcuts-environments'));
|
||||
Mousetrap.bind('i', () => findAndFollowLink('.shortcuts-new-issue'));
|
||||
|
||||
this.enabledHelp.push('.hidden-shortcut.project');
|
||||
|
|
|
@ -40,7 +40,7 @@ export default {
|
|||
:class="cssClass"
|
||||
:title="tooltipTitle(time)"
|
||||
:data-placement="tooltipPlacement"
|
||||
data-container="body">
|
||||
{{ timeFormated(time) }}
|
||||
data-container="body"
|
||||
v-text="timeFormated(time)">
|
||||
</time>
|
||||
</template>
|
||||
|
|
|
@ -279,251 +279,14 @@ ul.indent-list {
|
|||
padding: 10px 0 0 30px;
|
||||
}
|
||||
|
||||
|
||||
// Specific styles for tree list
|
||||
@keyframes spin-avatar {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.groups-list-tree-container {
|
||||
.has-no-search-results {
|
||||
text-align: center;
|
||||
padding: $gl-padding;
|
||||
font-style: italic;
|
||||
color: $well-light-text-color;
|
||||
}
|
||||
|
||||
> .group-list-tree > .group-row.has-children:first-child {
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.group-list-tree {
|
||||
.avatar-container.content-loading {
|
||||
position: relative;
|
||||
|
||||
> a,
|
||||
> a .avatar {
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
> a {
|
||||
padding: 2px;
|
||||
|
||||
.avatar {
|
||||
border: 2px solid $white-normal;
|
||||
|
||||
&.identicon {
|
||||
line-height: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
border: 2px outset $kdb-border;
|
||||
border-radius: 50%;
|
||||
animation: spin-avatar 3s infinite linear;
|
||||
}
|
||||
}
|
||||
|
||||
.folder-toggle-wrap {
|
||||
float: left;
|
||||
line-height: $list-text-height;
|
||||
font-size: 0;
|
||||
|
||||
span {
|
||||
font-size: $gl-font-size;
|
||||
}
|
||||
}
|
||||
|
||||
.folder-caret,
|
||||
.item-type-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.folder-caret {
|
||||
width: 15px;
|
||||
|
||||
svg {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-type-icon {
|
||||
margin-top: 2px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
> .group-row:not(.has-children) {
|
||||
.folder-caret {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.content-list li:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.group-list-tree {
|
||||
margin-bottom: 0;
|
||||
margin-left: 30px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
bottom: 0;
|
||||
left: -16px;
|
||||
border-left: 2px solid $border-white-normal;
|
||||
}
|
||||
|
||||
.group-row {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 10px;
|
||||
height: 0;
|
||||
border-top: 2px solid $border-white-normal;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: -16px;
|
||||
}
|
||||
|
||||
&:last-child::before {
|
||||
background: $white-light;
|
||||
height: auto;
|
||||
top: 30px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
&.being-removed {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-row {
|
||||
padding: 0;
|
||||
|
||||
&.has-children {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top: 1px solid $white-normal;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
.group-row-contents:not(:hover) {
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-row-contents {
|
||||
padding: 10px 10px 8px;
|
||||
border-top: solid 1px transparent;
|
||||
border-bottom: solid 1px $white-normal;
|
||||
|
||||
&:hover {
|
||||
border-color: $row-hover-border;
|
||||
background-color: $row-hover;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.avatar-container > a {
|
||||
width: 100%;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.has-more-items {
|
||||
display: block;
|
||||
padding: 20px 10px;
|
||||
}
|
||||
|
||||
.stats {
|
||||
position: relative;
|
||||
line-height: 46px;
|
||||
|
||||
> span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
height: 16px;
|
||||
min-width: 30px;
|
||||
}
|
||||
|
||||
> span:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
margin: 2px 0 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.controls {
|
||||
margin-left: 5px;
|
||||
|
||||
> .btn {
|
||||
margin-right: $btn-xs-side-margin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.project-row-contents .stats {
|
||||
line-height: inherit;
|
||||
|
||||
> span:first-child {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.item-visibility {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.last-updated {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
min-width: 250px;
|
||||
text-align: right;
|
||||
color: $gl-text-color-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.namespace-title {
|
||||
.tooltip-inner {
|
||||
max-width: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
ul.group-list-tree {
|
||||
li.group-row {
|
||||
> .group-row-contents .title {
|
||||
line-height: $list-text-height;
|
||||
}
|
||||
|
||||
&.has-description > .group-row-contents .title {
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.js-groups-list-holder {
|
||||
.groups-list-loading {
|
||||
font-size: 34px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
@import './issues/issue_count_badge';
|
||||
|
||||
[v-cloak] {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
|
||||
.group-row {
|
||||
@include basic-list-stats;
|
||||
|
||||
.description p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ldap-group-links {
|
||||
|
@ -237,3 +241,231 @@
|
|||
overflow-y: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.groups-list-tree-container {
|
||||
.has-no-search-results {
|
||||
text-align: center;
|
||||
padding: $gl-padding;
|
||||
font-style: italic;
|
||||
color: $well-light-text-color;
|
||||
}
|
||||
|
||||
> .group-list-tree > .group-row.has-children:first-child {
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.group-list-tree {
|
||||
.avatar-container.content-loading {
|
||||
position: relative;
|
||||
|
||||
> a,
|
||||
> a .avatar {
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
> a {
|
||||
padding: 2px;
|
||||
|
||||
.avatar {
|
||||
border: 2px solid $white-normal;
|
||||
|
||||
&.identicon {
|
||||
line-height: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
border: 2px outset $kdb-border;
|
||||
border-radius: 50%;
|
||||
animation: spin-avatar 3s infinite linear;
|
||||
}
|
||||
}
|
||||
|
||||
.folder-toggle-wrap {
|
||||
float: left;
|
||||
line-height: $list-text-height;
|
||||
font-size: 0;
|
||||
|
||||
span {
|
||||
font-size: $gl-font-size;
|
||||
}
|
||||
}
|
||||
|
||||
.folder-caret,
|
||||
.item-type-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.folder-caret {
|
||||
width: 15px;
|
||||
|
||||
svg {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-type-icon {
|
||||
margin-top: 2px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
> .group-row:not(.has-children) {
|
||||
.folder-caret {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.content-list li:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.group-list-tree {
|
||||
margin-bottom: 0;
|
||||
margin-left: 30px;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
bottom: 0;
|
||||
left: -16px;
|
||||
border-left: 2px solid $border-white-normal;
|
||||
}
|
||||
|
||||
.group-row {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 10px;
|
||||
height: 0;
|
||||
border-top: 2px solid $border-white-normal;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: -16px;
|
||||
}
|
||||
|
||||
&:last-child::before {
|
||||
background: $white-light;
|
||||
height: auto;
|
||||
top: 30px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
&.being-removed {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-row {
|
||||
padding: 0;
|
||||
|
||||
&.has-children {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top: 1px solid $white-normal;
|
||||
}
|
||||
}
|
||||
|
||||
.group-row-contents {
|
||||
padding: $gl-padding-top;
|
||||
|
||||
&:hover {
|
||||
border-color: $row-hover-border;
|
||||
background-color: $row-hover;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.avatar-container > a {
|
||||
width: 100%;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.has-more-items {
|
||||
display: block;
|
||||
padding: 20px 10px;
|
||||
}
|
||||
|
||||
.stats {
|
||||
position: relative;
|
||||
line-height: 46px;
|
||||
|
||||
> span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
height: 16px;
|
||||
min-width: 30px;
|
||||
}
|
||||
|
||||
> span:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
margin: 2px 0 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.controls {
|
||||
margin-left: 5px;
|
||||
|
||||
> .btn {
|
||||
margin-right: $btn-xs-side-margin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.project-row-contents .stats {
|
||||
line-height: inherit;
|
||||
|
||||
> span:first-child {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.item-visibility {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.last-updated {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
min-width: 250px;
|
||||
text-align: right;
|
||||
color: $gl-text-color-secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul.group-list-tree {
|
||||
li.group-row {
|
||||
> .group-row-contents .title {
|
||||
line-height: $list-text-height;
|
||||
}
|
||||
|
||||
&.has-description > .group-row-contents .title {
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.js-groups-list-holder {
|
||||
.groups-list-loading {
|
||||
font-size: 34px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,9 +197,21 @@
|
|||
}
|
||||
|
||||
&.assignee {
|
||||
.author_link:hover {
|
||||
.author {
|
||||
text-decoration: underline;
|
||||
.author_link {
|
||||
display: block;
|
||||
padding-left: 42px;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
.author {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar {
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
@import "./issues/issue_count_badge";
|
||||
|
||||
.issues-list {
|
||||
.issue {
|
||||
padding: 10px 0 10px $gl-padding;
|
||||
|
|
|
@ -455,6 +455,10 @@ ul.notes {
|
|||
white-space: normal;
|
||||
}
|
||||
|
||||
.system-note-separator {
|
||||
color: $gl-text-color-disabled;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
|
|
@ -66,13 +66,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
&.open {
|
||||
.btn-default {
|
||||
background-color: $white-normal;
|
||||
border-color: $border-white-normal;
|
||||
}
|
||||
}
|
||||
.btn-group.open .btn-default {
|
||||
background-color: $white-normal;
|
||||
border-color: $border-white-normal;
|
||||
}
|
||||
|
||||
.btn .text-center {
|
||||
|
@ -361,16 +357,14 @@
|
|||
&:not(:first-child) {
|
||||
margin-left: 44px;
|
||||
|
||||
.left-connector {
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: -44px;
|
||||
border-top: 2px solid $border-color;
|
||||
width: 44px;
|
||||
height: 1px;
|
||||
}
|
||||
.left-connector::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: -44px;
|
||||
border-top: 2px solid $border-color;
|
||||
width: 44px;
|
||||
height: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -386,22 +380,16 @@
|
|||
&:last-child {
|
||||
.build {
|
||||
// Remove right connecting horizontal line from first build in last stage
|
||||
&:first-child {
|
||||
&::after {
|
||||
border: 0;
|
||||
}
|
||||
&:first-child::after {
|
||||
border: 0;
|
||||
}
|
||||
// Remove right curved connectors from all builds in last stage
|
||||
&:not(:first-child) {
|
||||
&::after {
|
||||
border: 0;
|
||||
}
|
||||
&:not(:first-child)::after {
|
||||
border: 0;
|
||||
}
|
||||
// Remove opposite curve
|
||||
.curve {
|
||||
&::before {
|
||||
display: none;
|
||||
}
|
||||
.curve::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -409,16 +397,12 @@
|
|||
&:first-child {
|
||||
.build {
|
||||
// Remove left curved connectors from all builds in first stage
|
||||
&:not(:first-child) {
|
||||
&::before {
|
||||
border: 0;
|
||||
}
|
||||
&:not(:first-child)::before {
|
||||
border: 0;
|
||||
}
|
||||
// Remove opposite curve
|
||||
.curve {
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
.curve::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,12 +39,15 @@
|
|||
|
||||
.ide-file-list {
|
||||
flex: 1;
|
||||
padding-left: $gl-padding;
|
||||
padding-right: $gl-padding;
|
||||
padding-bottom: $grid-size;
|
||||
|
||||
.file {
|
||||
cursor: pointer;
|
||||
|
||||
&.file-open {
|
||||
background: $link-active-background;
|
||||
background: $white-normal;
|
||||
}
|
||||
|
||||
&.file-active {
|
||||
|
@ -84,12 +87,11 @@
|
|||
|
||||
.ide-new-btn {
|
||||
display: none;
|
||||
margin-right: -8px;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: $link-active-background;
|
||||
background: $white-normal;
|
||||
|
||||
.ide-new-btn {
|
||||
display: block;
|
||||
|
@ -111,12 +113,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
.file-name,
|
||||
.file-col-commit-message {
|
||||
.file-name {
|
||||
display: flex;
|
||||
overflow: visible;
|
||||
align-items: center;
|
||||
padding: 6px 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.multi-file-loading-container {
|
||||
|
@ -306,8 +307,18 @@
|
|||
}
|
||||
|
||||
.preview-container {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
|
||||
.md-previewer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
padding: $gl-padding;
|
||||
}
|
||||
|
||||
.file-container {
|
||||
background-color: $gray-darker;
|
||||
|
@ -347,10 +358,6 @@
|
|||
color: $diff-image-info-color;
|
||||
}
|
||||
}
|
||||
|
||||
.md-previewer {
|
||||
padding: $gl-padding;
|
||||
}
|
||||
}
|
||||
|
||||
.ide-mode-tabs {
|
||||
|
@ -501,7 +508,7 @@
|
|||
align-items: center;
|
||||
margin-bottom: 0;
|
||||
border-bottom: 1px solid $white-dark;
|
||||
padding: $gl-btn-padding $gl-padding;
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.multi-file-commit-panel-header-title {
|
||||
|
@ -523,32 +530,31 @@
|
|||
.multi-file-commit-list {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: $gl-padding;
|
||||
padding: $grid-size 0;
|
||||
margin-left: -$grid-size;
|
||||
margin-right: -$grid-size;
|
||||
min-height: 60px;
|
||||
|
||||
.multi-file-commit-list-item {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&.help-block {
|
||||
margin-left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.multi-file-commit-list-item {
|
||||
display: flex;
|
||||
padding: 0;
|
||||
align-items: center;
|
||||
border-radius: $border-radius-default;
|
||||
|
||||
.multi-file-discard-btn {
|
||||
display: none;
|
||||
margin-top: -2px;
|
||||
margin-left: auto;
|
||||
margin-right: $grid-size;
|
||||
color: $gl-link-color;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $white-normal;
|
||||
|
||||
.multi-file-discard-btn {
|
||||
display: flex;
|
||||
}
|
||||
|
@ -584,25 +590,39 @@
|
|||
}
|
||||
}
|
||||
|
||||
.multi-file-commit-list-item,
|
||||
.ide-file-list .file {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: -$grid-size;
|
||||
margin-right: -$grid-size;
|
||||
padding: $grid-size / 2 $grid-size;
|
||||
border-radius: $border-radius-default;
|
||||
text-align: left;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: $white-normal;
|
||||
}
|
||||
}
|
||||
|
||||
.multi-file-commit-list-path {
|
||||
padding: $grid-size / 2;
|
||||
padding-left: $grid-size;
|
||||
padding: 0;
|
||||
background: none;
|
||||
border: 0;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
svg {
|
||||
min-width: 16px;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.multi-file-commit-list-file-path {
|
||||
|
@ -619,12 +639,18 @@
|
|||
|
||||
.multi-file-commit-form {
|
||||
position: relative;
|
||||
padding: $gl-padding;
|
||||
background-color: $white-light;
|
||||
border-top: 1px solid $white-dark;
|
||||
border-left: 1px solid $white-dark;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
> form,
|
||||
> .commit-form-compact {
|
||||
padding: $gl-padding 0;
|
||||
margin-left: $gl-padding;
|
||||
margin-right: $gl-padding;
|
||||
border-top: 1px solid $white-dark;
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-size: $gl-font-size;
|
||||
}
|
||||
|
@ -787,8 +813,9 @@
|
|||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-height: 140px;
|
||||
margin-left: $gl-padding;
|
||||
margin-right: $gl-padding;
|
||||
|
||||
&.is-first {
|
||||
border-bottom: 1px solid $white-dark;
|
||||
|
@ -979,9 +1006,8 @@
|
|||
.ide-tree-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 8px;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid $white-dark;
|
||||
|
||||
.ide-new-btn {
|
||||
|
@ -1012,9 +1038,9 @@
|
|||
.commit-form-slide-up-enter-active,
|
||||
.commit-form-slide-up-leave-active {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ module Boards
|
|||
|
||||
def serialize_as_json(resource)
|
||||
resource.as_json(
|
||||
only: [:id, :iid, :project_id, :title, :confidential, :due_date, :relative_position],
|
||||
only: [:id, :iid, :project_id, :title, :confidential, :due_date, :relative_position, :weight],
|
||||
labels: true,
|
||||
issue_endpoints: true,
|
||||
include_full_project_path: board.group_board?,
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
module AcceptsPendingInvitations
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def accept_pending_invitations
|
||||
return unless resource.active_for_authentication?
|
||||
|
||||
clear_stored_location_for_resource if resource.accept_pending_invitations!.any?
|
||||
end
|
||||
|
||||
def clear_stored_location_for_resource
|
||||
session_key = stored_location_key_for(resource)
|
||||
|
||||
session.delete(session_key)
|
||||
end
|
||||
end
|
|
@ -1,4 +1,6 @@
|
|||
class ConfirmationsController < Devise::ConfirmationsController
|
||||
include AcceptsPendingInvitations
|
||||
|
||||
def almost_there
|
||||
flash[:notice] = nil
|
||||
render layout: "devise_empty"
|
||||
|
@ -11,6 +13,8 @@ class ConfirmationsController < Devise::ConfirmationsController
|
|||
end
|
||||
|
||||
def after_confirmation_path_for(resource_name, resource)
|
||||
accept_pending_invitations
|
||||
|
||||
# incoming resource can either be a :user or an :email
|
||||
if signed_in?(:user)
|
||||
after_sign_in(resource)
|
||||
|
|
|
@ -23,7 +23,7 @@ class Profiles::KeysController < Profiles::ApplicationController
|
|||
|
||||
def destroy
|
||||
@key = current_user.keys.find(params[:id])
|
||||
@key.destroy
|
||||
Keys::DestroyService.new(current_user).execute(@key)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to profile_keys_url, status: 302 }
|
||||
|
|
|
@ -23,8 +23,12 @@ class Projects::CommitController < Projects::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html { render }
|
||||
format.diff { render text: @commit.to_diff }
|
||||
format.patch { render text: @commit.to_patch }
|
||||
format.diff do
|
||||
send_git_diff(@project.repository, @commit.diff_refs)
|
||||
end
|
||||
format.patch do
|
||||
send_git_patch(@project.repository, @commit.diff_refs)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -18,19 +18,12 @@ class Projects::PipelinesController < Projects::ApplicationController
|
|||
.page(params[:page])
|
||||
.per(30)
|
||||
|
||||
@running_count = PipelinesFinder
|
||||
.new(project, scope: 'running').execute.count
|
||||
@running_count = limited_pipelines_count(project, 'running')
|
||||
@pending_count = limited_pipelines_count(project, 'pending')
|
||||
@finished_count = limited_pipelines_count(project, 'finished')
|
||||
@pipelines_count = limited_pipelines_count(project)
|
||||
|
||||
@pending_count = PipelinesFinder
|
||||
.new(project, scope: 'pending').execute.count
|
||||
|
||||
@finished_count = PipelinesFinder
|
||||
.new(project, scope: 'finished').execute.count
|
||||
|
||||
@pipelines_count = PipelinesFinder
|
||||
.new(project).execute.count
|
||||
|
||||
@pipelines.map(&:commit) # List commits for batch loading
|
||||
Gitlab::Ci::Pipeline::Preloader.preload(@pipelines)
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
|
@ -41,7 +34,7 @@ class Projects::PipelinesController < Projects::ApplicationController
|
|||
pipelines: PipelineSerializer
|
||||
.new(project: @project, current_user: @current_user)
|
||||
.with_pagination(request, response)
|
||||
.represent(@pipelines),
|
||||
.represent(@pipelines, disable_coverage: true),
|
||||
count: {
|
||||
all: @pipelines_count,
|
||||
running: @running_count,
|
||||
|
@ -185,4 +178,10 @@ class Projects::PipelinesController < Projects::ApplicationController
|
|||
def authorize_update_pipeline!
|
||||
return access_denied! unless can?(current_user, :update_pipeline, @pipeline)
|
||||
end
|
||||
|
||||
def limited_pipelines_count(project, scope = nil)
|
||||
finder = PipelinesFinder.new(project, scope: scope)
|
||||
|
||||
view_context.limited_counter_with_delimiter(finder.execute)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,7 +11,14 @@ module Projects
|
|||
@hook = ProjectHook.new
|
||||
|
||||
# Services
|
||||
@services = @project.find_or_initialize_services
|
||||
@services = @project.find_or_initialize_services(exceptions: service_exceptions)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Returns a list of services that should be hidden from the list
|
||||
def service_exceptions
|
||||
@project.disabled_services.dup
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
class RegistrationsController < Devise::RegistrationsController
|
||||
include Recaptcha::Verify
|
||||
include AcceptsPendingInvitations
|
||||
|
||||
before_action :whitelist_query_limiting, only: [:destroy]
|
||||
|
||||
|
@ -16,6 +17,7 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
|
||||
if !Gitlab::Recaptcha.load_configurations! || verify_recaptcha
|
||||
accept_pending_invitations
|
||||
super
|
||||
else
|
||||
flash[:alert] = 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
|
||||
|
@ -60,7 +62,7 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
|
||||
def after_sign_up_path_for(user)
|
||||
Gitlab::AppLogger.info("User Created: username=#{user.username} email=#{user.email} ip=#{request.remote_ip} confirmed:#{user.confirmed?}")
|
||||
user.confirmed? ? dashboard_projects_path : users_almost_there_path
|
||||
user.confirmed? ? stored_location_for(user) || dashboard_projects_path : users_almost_there_path
|
||||
end
|
||||
|
||||
def after_inactive_sign_up_path_for(resource)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# klass - actual class like Issue or MergeRequest
|
||||
# current_user - which user use
|
||||
# params:
|
||||
# scope: 'created-by-me' or 'assigned-to-me' or 'all'
|
||||
# scope: 'created_by_me' or 'assigned_to_me' or 'all'
|
||||
# state: 'opened' or 'closed' or 'all'
|
||||
# group_id: integer
|
||||
# project_id: integer
|
||||
|
@ -282,9 +282,9 @@ class IssuableFinder
|
|||
return items.none if current_user_related? && !current_user
|
||||
|
||||
case params[:scope]
|
||||
when 'created-by-me', 'authored'
|
||||
when 'created_by_me', 'authored'
|
||||
items.where(author_id: current_user.id)
|
||||
when 'assigned-to-me'
|
||||
when 'assigned_to_me'
|
||||
items.assigned_to(current_user)
|
||||
else
|
||||
items
|
||||
|
@ -426,6 +426,7 @@ class IssuableFinder
|
|||
end
|
||||
|
||||
def current_user_related?
|
||||
params[:scope] == 'created-by-me' || params[:scope] == 'authored' || params[:scope] == 'assigned-to-me'
|
||||
scope = params[:scope]
|
||||
scope == 'created_by_me' || scope == 'authored' || scope == 'assigned_to_me'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# Arguments:
|
||||
# current_user - which user use
|
||||
# params:
|
||||
# scope: 'created-by-me' or 'assigned-to-me' or 'all'
|
||||
# scope: 'created_by_me' or 'assigned_to_me' or 'all'
|
||||
# state: 'open' or 'closed' or 'all'
|
||||
# group_id: integer
|
||||
# project_id: integer
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# Arguments:
|
||||
# current_user - which user use
|
||||
# params:
|
||||
# scope: 'created-by-me' or 'assigned-to-me' or 'all'
|
||||
# scope: 'created_by_me' or 'assigned_to_me' or 'all'
|
||||
# state: 'open', 'closed', 'merged', or 'all'
|
||||
# group_id: integer
|
||||
# project_id: integer
|
||||
|
|
|
@ -13,7 +13,7 @@ class PersonalProjectsFinder < UnionFinder
|
|||
def execute(current_user = nil)
|
||||
segments = all_projects(current_user)
|
||||
|
||||
find_union(segments, Project).includes(:namespace).order_id_desc
|
||||
find_union(segments, Project).includes(:namespace).order_updated_desc
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -184,7 +184,7 @@ module Ci
|
|||
end
|
||||
|
||||
def playable?
|
||||
action? && (manual? || complete?)
|
||||
action? && (manual? || retryable?)
|
||||
end
|
||||
|
||||
def action?
|
||||
|
@ -599,6 +599,7 @@ module Ci
|
|||
break variables unless persisted?
|
||||
|
||||
variables
|
||||
.concat(pipeline.persisted_variables)
|
||||
.append(key: 'CI_JOB_ID', value: id.to_s)
|
||||
.append(key: 'CI_JOB_TOKEN', value: token, public: false)
|
||||
.append(key: 'CI_BUILD_ID', value: id.to_s)
|
||||
|
@ -661,7 +662,7 @@ module Ci
|
|||
Gitlab::Ci::Variables::Collection.new.tap do |variables|
|
||||
break variables unless gitlab_deploy_token
|
||||
|
||||
variables.append(key: 'CI_DEPLOY_USER', value: gitlab_deploy_token.name)
|
||||
variables.append(key: 'CI_DEPLOY_USER', value: gitlab_deploy_token.username)
|
||||
variables.append(key: 'CI_DEPLOY_PASSWORD', value: gitlab_deploy_token.token, public: false)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -411,7 +411,18 @@ module Ci
|
|||
end
|
||||
|
||||
def has_warnings?
|
||||
builds.latest.failed_but_allowed.any?
|
||||
number_of_warnings.positive?
|
||||
end
|
||||
|
||||
def number_of_warnings
|
||||
BatchLoader.for(id).batch(default_value: 0) do |pipeline_ids, loader|
|
||||
Build.where(commit_id: pipeline_ids)
|
||||
.latest
|
||||
.failed_but_allowed
|
||||
.group(:commit_id)
|
||||
.count
|
||||
.each { |id, amount| loader.call(id, amount) }
|
||||
end
|
||||
end
|
||||
|
||||
def set_config_source
|
||||
|
@ -517,9 +528,14 @@ module Ci
|
|||
strong_memoize(:legacy_trigger) { trigger_requests.first }
|
||||
end
|
||||
|
||||
def persisted_variables
|
||||
Gitlab::Ci::Variables::Collection.new.tap do |variables|
|
||||
variables.append(key: 'CI_PIPELINE_ID', value: id.to_s) if persisted?
|
||||
end
|
||||
end
|
||||
|
||||
def predefined_variables
|
||||
Gitlab::Ci::Variables::Collection.new
|
||||
.append(key: 'CI_PIPELINE_ID', value: id.to_s)
|
||||
.append(key: 'CI_PIPELINE_IID', value: iid.to_s)
|
||||
.append(key: 'CI_CONFIG_PATH', value: ci_yaml_file_path)
|
||||
.append(key: 'CI_PIPELINE_SOURCE', value: source.to_s)
|
||||
|
|
|
@ -75,7 +75,7 @@ module Ci
|
|||
project_type: 3
|
||||
}
|
||||
|
||||
cached_attr_reader :version, :revision, :platform, :architecture, :contacted_at, :ip_address
|
||||
cached_attr_reader :version, :revision, :platform, :architecture, :ip_address, :contacted_at
|
||||
|
||||
chronic_duration_attr :maximum_timeout_human_readable, :maximum_timeout
|
||||
|
||||
|
|
|
@ -49,6 +49,11 @@ module Clusters
|
|||
# ensures headers containing auth data are appended to original k8s client options
|
||||
options = kube_client.rest_client.options.merge(headers: kube_client.headers)
|
||||
RestClient::Resource.new(proxy_url, options)
|
||||
rescue Kubeclient::HttpError
|
||||
# If users have mistakenly set parameters or removed the depended clusters,
|
||||
# `proxy_url` could raise an exception because gitlab can not communicate with the cluster.
|
||||
# Since `PrometheusAdapter#can_query?` is eargely loaded on environement pages in gitlab,
|
||||
# we need to silence the exceptions
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -224,8 +224,34 @@ class Commit
|
|||
Gitlab::ClosingIssueExtractor.new(project, current_user).closed_by_message(safe_message)
|
||||
end
|
||||
|
||||
def lazy_author
|
||||
BatchLoader.for(author_email.downcase).batch do |emails, loader|
|
||||
# A Hash that maps user Emails to the corresponding User objects. The
|
||||
# Emails at this point are the _primary_ Emails of the Users.
|
||||
users_for_emails = User
|
||||
.by_any_email(emails)
|
||||
.each_with_object({}) { |user, hash| hash[user.email] = user }
|
||||
|
||||
users_for_ids = users_for_emails
|
||||
.values
|
||||
.each_with_object({}) { |user, hash| hash[user.id] = user }
|
||||
|
||||
# Some commits may have used an alternative Email address. In this case we
|
||||
# need to query the "emails" table to map those addresses to User objects.
|
||||
Email
|
||||
.where(email: emails - users_for_emails.keys)
|
||||
.pluck(:email, :user_id)
|
||||
.each { |(email, id)| users_for_emails[email] = users_for_ids[id] }
|
||||
|
||||
users_for_emails.each { |email, user| loader.call(email, user) }
|
||||
end
|
||||
end
|
||||
|
||||
def author
|
||||
User.find_by_any_email(author_email.downcase)
|
||||
# We use __sync so that we get the actual objects back (including an actual
|
||||
# nil), instead of a wrapper, as returning a wrapped nil breaks a lot of
|
||||
# code.
|
||||
lazy_author.__sync
|
||||
end
|
||||
request_cache(:author) { author_email.downcase }
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ class CommitStatus < ActiveRecord::Base
|
|||
include HasStatus
|
||||
include Importable
|
||||
include AfterCommitQueue
|
||||
include Presentable
|
||||
|
||||
self.table_name = 'ci_builds'
|
||||
|
||||
|
|
|
@ -7,7 +7,11 @@ module RedisCacheable
|
|||
class_methods do
|
||||
def cached_attr_reader(*attributes)
|
||||
attributes.each do |attribute|
|
||||
define_method("#{attribute}") do
|
||||
define_method(attribute) do
|
||||
unless self.has_attribute?(attribute)
|
||||
raise ArgumentError, "`cached_attr_reader` requires the #{self.class.name}\##{attribute} attribute to have a database column"
|
||||
end
|
||||
|
||||
cached_attribute(attribute) || read_attribute(attribute)
|
||||
end
|
||||
end
|
||||
|
@ -15,13 +19,16 @@ module RedisCacheable
|
|||
end
|
||||
|
||||
def cached_attribute(attribute)
|
||||
(cached_attributes || {})[attribute]
|
||||
cached_value = (cached_attributes || {})[attribute]
|
||||
cast_value_from_cache(attribute, cached_value) if cached_value
|
||||
end
|
||||
|
||||
def cache_attributes(values)
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
redis.set(cache_attribute_key, values.to_json, ex: CACHED_ATTRIBUTES_EXPIRY_TIME)
|
||||
end
|
||||
|
||||
clear_memoization(:cached_attributes)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -38,4 +45,12 @@ module RedisCacheable
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cast_value_from_cache(attribute, value)
|
||||
if Gitlab.rails5?
|
||||
self.class.type_for_attribute(attribute).cast(value)
|
||||
else
|
||||
self.class.column_for_attribute(attribute).type_cast_from_database(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,8 +12,8 @@ module Sortable
|
|||
scope :order_created_asc, -> { reorder(created_at: :asc) }
|
||||
scope :order_updated_desc, -> { reorder(updated_at: :desc) }
|
||||
scope :order_updated_asc, -> { reorder(updated_at: :asc) }
|
||||
scope :order_name_asc, -> { reorder(name: :asc) }
|
||||
scope :order_name_desc, -> { reorder(name: :desc) }
|
||||
scope :order_name_asc, -> { reorder("lower(name) asc") }
|
||||
scope :order_name_desc, -> { reorder("lower(name) desc") }
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
|
|
@ -53,6 +53,10 @@ module TimeTrackable
|
|||
Gitlab::TimeTrackingFormatter.output(time_estimate)
|
||||
end
|
||||
|
||||
def time_estimate=(val)
|
||||
val.is_a?(Integer) ? super([val, Gitlab::Database::MAX_INT_VALUE].min) : super(val)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def touchable?
|
||||
|
|
|
@ -997,7 +997,7 @@ class Project < ActiveRecord::Base
|
|||
|
||||
available_services_names = Service.available_services_names - exceptions
|
||||
|
||||
available_services_names.map do |service_name|
|
||||
available_services = available_services_names.map do |service_name|
|
||||
service = find_service(services, service_name)
|
||||
|
||||
if service
|
||||
|
@ -1014,6 +1014,14 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
available_services.reject do |service|
|
||||
disabled_services.include?(service.to_param)
|
||||
end
|
||||
end
|
||||
|
||||
def disabled_services
|
||||
[]
|
||||
end
|
||||
|
||||
def find_or_initialize_service(name)
|
||||
|
|
|
@ -860,6 +860,16 @@ class User < ActiveRecord::Base
|
|||
confirmed? && !temp_oauth_email?
|
||||
end
|
||||
|
||||
def accept_pending_invitations!
|
||||
pending_invitations.select do |member|
|
||||
member.accept_invite!(self)
|
||||
end
|
||||
end
|
||||
|
||||
def pending_invitations
|
||||
Member.where(invite_email: verified_emails).invite
|
||||
end
|
||||
|
||||
def all_emails
|
||||
all_emails = []
|
||||
all_emails << email unless temp_oauth_email?
|
||||
|
|
|
@ -1,16 +1,5 @@
|
|||
module Ci
|
||||
class BuildPresenter < Gitlab::View::Presenter::Delegated
|
||||
CALLOUT_FAILURE_MESSAGES = {
|
||||
unknown_failure: 'There is an unknown failure, please try again',
|
||||
script_failure: 'There has been a script failure. Check the job log for more information',
|
||||
api_failure: 'There has been an API failure, please try again',
|
||||
stuck_or_timeout_failure: 'There has been a timeout failure or the job got stuck. Check your timeout limits or try again',
|
||||
runner_system_failure: 'There has been a runner system failure, please try again',
|
||||
missing_dependency_failure: 'There has been a missing dependency failure, check the job log for more information'
|
||||
}.freeze
|
||||
|
||||
presents :build
|
||||
|
||||
class BuildPresenter < CommitStatusPresenter
|
||||
def erased_by_user?
|
||||
# Build can be erased through API, therefore it does not have
|
||||
# `erased_by` user assigned in that case.
|
||||
|
@ -44,14 +33,6 @@ module Ci
|
|||
"#{subject.name} - #{detailed_status.status_tooltip}"
|
||||
end
|
||||
|
||||
def callout_failure_message
|
||||
CALLOUT_FAILURE_MESSAGES[failure_reason.to_sym]
|
||||
end
|
||||
|
||||
def recoverable?
|
||||
failed? && !unrecoverable?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def tooltip_for_badge
|
||||
|
@ -61,9 +42,5 @@ module Ci
|
|||
def detailed_status
|
||||
@detailed_status ||= subject.detailed_status(user)
|
||||
end
|
||||
|
||||
def unrecoverable?
|
||||
script_failure? || missing_dependency_failure?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
class CommitStatusPresenter < Gitlab::View::Presenter::Delegated
|
||||
CALLOUT_FAILURE_MESSAGES = {
|
||||
unknown_failure: 'There is an unknown failure, please try again',
|
||||
script_failure: 'There has been a script failure. Check the job log for more information',
|
||||
api_failure: 'There has been an API failure, please try again',
|
||||
stuck_or_timeout_failure: 'There has been a timeout failure or the job got stuck. Check your timeout limits or try again',
|
||||
runner_system_failure: 'There has been a runner system failure, please try again',
|
||||
missing_dependency_failure: 'There has been a missing dependency failure, check the job log for more information'
|
||||
}.freeze
|
||||
|
||||
presents :build
|
||||
|
||||
def callout_failure_message
|
||||
CALLOUT_FAILURE_MESSAGES[failure_reason.to_sym]
|
||||
end
|
||||
|
||||
def recoverable?
|
||||
failed? && !unrecoverable?
|
||||
end
|
||||
|
||||
def unrecoverable?
|
||||
script_failure? || missing_dependency_failure?
|
||||
end
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
class GenericCommitStatusPresenter < CommitStatusPresenter
|
||||
end
|
|
@ -4,7 +4,11 @@ class PipelineEntity < Grape::Entity
|
|||
expose :id
|
||||
expose :user, using: UserEntity
|
||||
expose :active?, as: :active
|
||||
expose :coverage
|
||||
|
||||
# Coverage isn't always necessary (e.g. when displaying project pipelines in
|
||||
# the UI). Instead of creating an entirely different entity we just allow the
|
||||
# disabling of this specific field whenever necessary.
|
||||
expose :coverage, unless: proc { options[:disable_coverage] }
|
||||
expose :source
|
||||
|
||||
expose :created_at, :updated_at
|
||||
|
|
|
@ -2,7 +2,7 @@ module Keys
|
|||
class BaseService
|
||||
attr_accessor :user, :params
|
||||
|
||||
def initialize(user, params)
|
||||
def initialize(user, params = {})
|
||||
@user, @params = user, params
|
||||
@ip_address = @params.delete(:ip_address)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
module Keys
|
||||
class DestroyService < ::Keys::BaseService
|
||||
def execute(key)
|
||||
key.destroy if destroy_possible?(key)
|
||||
end
|
||||
|
||||
# overriden in EE::Keys::DestroyService
|
||||
def destroy_possible?(key)
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,14 +2,14 @@ module Lfs
|
|||
class UnlockFileService < BaseService
|
||||
def execute
|
||||
unless can?(current_user, :push_code, project)
|
||||
raise Gitlab::GitAccess::UnauthorizedError, 'You have no permissions'
|
||||
raise Gitlab::GitAccess::UnauthorizedError, _('You have no permissions')
|
||||
end
|
||||
|
||||
unlock_file
|
||||
rescue Gitlab::GitAccess::UnauthorizedError => ex
|
||||
error(ex.message, 403)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
error('Lock not found', 404)
|
||||
error(_('Lock not found'), 404)
|
||||
rescue => ex
|
||||
error(ex.message, 500)
|
||||
end
|
||||
|
@ -24,9 +24,9 @@ module Lfs
|
|||
|
||||
success(lock: lock, http_status: :ok)
|
||||
elsif forced
|
||||
error('You must have master access to force delete a lock', 403)
|
||||
error(_('You must have master access to force delete a lock'), 403)
|
||||
else
|
||||
error("#{lock.path} is locked by GitLab User #{lock.user_id}", 403)
|
||||
error(_("%{lock_path} is locked by GitLab User %{lock_user_id}") % { lock_path: lock.path, lock_user_id: lock.user_id }, 403)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ module Milestones
|
|||
|
||||
def initialize(parent, user, params = {})
|
||||
@parent, @current_user, @params = parent, user, params.dup
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
.col-sm-10
|
||||
= f.color_field :font, class: "form-control"
|
||||
.form-group
|
||||
= f.label :starts_at, class: 'control-label'
|
||||
= f.label :starts_at, _("Starts at (UTC)"), class: 'control-label'
|
||||
.col-sm-10.datetime-controls
|
||||
= f.datetime_select :starts_at, {}, class: 'form-control form-control-inline'
|
||||
.form-group
|
||||
= f.label :ends_at, class: 'control-label'
|
||||
= f.label :ends_at, _("Ends at (UTC)"), class: 'control-label'
|
||||
.col-sm-10.datetime-controls
|
||||
= f.datetime_select :ends_at, {}, class: 'form-control form-control-inline'
|
||||
.form-actions
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
= tag
|
||||
%td
|
||||
- if runner.contacted_at
|
||||
#{time_ago_in_words(runner.contacted_at)} ago
|
||||
= time_ago_with_tooltip runner.contacted_at
|
||||
- else
|
||||
Never
|
||||
%td.admin-runner-btn-group-cell
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
%tr
|
||||
%td.shortcut
|
||||
.key g
|
||||
.key e
|
||||
.key v
|
||||
%td
|
||||
Go to the project's activity feed
|
||||
%tr
|
||||
|
@ -172,6 +172,18 @@
|
|||
.key m
|
||||
%td
|
||||
Go to merge requests
|
||||
%tr
|
||||
%td.shortcut
|
||||
.key g
|
||||
.key e
|
||||
%td
|
||||
Go to environments
|
||||
%tr
|
||||
%td.shortcut
|
||||
.key g
|
||||
.key k
|
||||
%td
|
||||
Go to kubernetes
|
||||
%tr
|
||||
%td.shortcut
|
||||
.key g
|
||||
|
@ -219,6 +231,17 @@
|
|||
%td.shortcut
|
||||
.key y
|
||||
%td Go to file permalink
|
||||
%tbody
|
||||
%tr
|
||||
%th
|
||||
%th Web IDE
|
||||
%tr
|
||||
%td.shortcut
|
||||
- if browser.platform.mac?
|
||||
.key ⌘ p
|
||||
- else
|
||||
.key ctrl p
|
||||
%td Go to file
|
||||
.col-lg-4
|
||||
%table.shortcut-mappings
|
||||
%tbody.hidden-shortcut.network{ style: 'display:none' }
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
= nav_link(path: 'projects#show', html_options: { class: "fly-out-top-item" } ) do
|
||||
= link_to project_path(@project) do
|
||||
%strong.fly-out-top-item-name
|
||||
= _('Overview')
|
||||
= _('Project')
|
||||
%li.divider.fly-out-top-item
|
||||
= nav_link(path: 'projects#show') do
|
||||
= link_to project_path(@project), title: _('Project details'), class: 'shortcuts-project' do
|
||||
|
@ -154,7 +154,7 @@
|
|||
= nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts]) do
|
||||
= link_to project_pipelines_path(@project), class: 'shortcuts-pipelines' do
|
||||
.nav-icon-container
|
||||
= sprite_icon('pipeline')
|
||||
= sprite_icon('rocket')
|
||||
%span.nav-item-name
|
||||
= _('CI / CD')
|
||||
|
||||
|
@ -212,7 +212,7 @@
|
|||
- if project_nav_tab? :clusters
|
||||
- show_cluster_hint = show_gke_cluster_integration_callout?(@project)
|
||||
= nav_link(controller: [:clusters, :user, :gcp]) do
|
||||
= link_to project_clusters_path(@project), title: _('Kubernetes'), class: 'shortcuts-cluster' do
|
||||
= link_to project_clusters_path(@project), title: _('Kubernetes'), class: 'shortcuts-kubernetes' do
|
||||
%span
|
||||
= _('Kubernetes')
|
||||
- if show_cluster_hint
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
by
|
||||
= link_to member.created_by.name, user_url(member.created_by)
|
||||
to join the
|
||||
= link_to member_source.human_name, member_source.web_url
|
||||
= link_to member_source.human_name, member_source.public? ? member_source.web_url : invite_url(@token)
|
||||
#{member_source.model_name.singular} as #{member.human_access}.
|
||||
|
||||
%p
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
%br
|
||||
%p
|
||||
- deploy_token = link_to(_('deploy token'), help_page_path('user/project/deploy_tokens/index', anchor: 'read-container-registry-images'), target: '_blank')
|
||||
= s_('ContainerRegistry|You can also %{deploy_token} for read-only access to the registry images.').html_safe % { deploy_token: deploy_token }
|
||||
= s_('ContainerRegistry|You can also use a %{deploy_token} for read-only access to the registry images.').html_safe % { deploy_token: deploy_token }
|
||||
%br
|
||||
%p
|
||||
= s_('ContainerRegistry|Once you log in, you’re free to create and upload a container image using the common %{build} and %{push} commands').html_safe % { build: "<code>build</code>".html_safe, push: "<code>push</code>".html_safe }
|
||||
|
|
|
@ -41,8 +41,9 @@
|
|||
- if note.system
|
||||
%span.system-note-message
|
||||
= markdown_field(note, :note)
|
||||
%a{ href: "##{dom_id(note)}" }
|
||||
= time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago')
|
||||
%span.system-note-separator
|
||||
·
|
||||
%a.system-note-separator{ href: "##{dom_id(note)}" }= time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago')
|
||||
- unless note.system?
|
||||
.note-actions
|
||||
- if note.for_personal_snippet?
|
||||
|
|
|
@ -66,6 +66,6 @@
|
|||
%td Last contact
|
||||
%td
|
||||
- if @runner.contacted_at
|
||||
#{time_ago_in_words(@runner.contacted_at)} ago
|
||||
= time_ago_with_tooltip @runner.contacted_at
|
||||
- else
|
||||
Never
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Introduce new ProjectCiCdSetting model with group_runners_enabled
|
||||
merge_request: 18144
|
||||
author:
|
||||
type: performance
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Add cron job to email users on issue due date
|
||||
merge_request: 17985
|
||||
author: Stuart Nelson
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix double-brackets being linkified in wiki markdown
|
||||
merge_request: 18524
|
||||
author: brewingcode
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add API endpoint to render markdown text
|
||||
merge_request: 18926
|
||||
author: "@blackst0ne"
|
||||
type: added
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Improves wording in new pipeline page
|
||||
merge_request:
|
||||
author:
|
||||
type: other
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Improve tooltips in collapsed right sidebar
|
||||
merge_request: 17714
|
||||
author:
|
||||
type: changed
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Fix `joined` information on project members page
|
||||
merge_request: 18290
|
||||
author: Fabian Schneider
|
||||
type: fixed
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
title: Fix template selector menu visibility when toggling preview mode in file edit
|
||||
view
|
||||
merge_request: 18118
|
||||
author: Fabian Schneider
|
||||
type: fixed
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Use VueJS for rendering pipeline stages
|
||||
merge_request:
|
||||
author:
|
||||
type: changed
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Prevent pipeline actions in dropdown to redirct to a new page
|
||||
merge_request:
|
||||
author:
|
||||
type: fixed
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Keep current labels visible when editing them in the sidebar
|
||||
merge_request:
|
||||
author:
|
||||
type: changed
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Reconcile project templates with Auto DevOps
|
||||
merge_request: 18737
|
||||
author:
|
||||
type: changed
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Adjust issue boards list header label text color
|
||||
merge_request:
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Apply NestingDepth (level 5) (pages/pipelines.scss)
|
||||
merge_request: 18830
|
||||
author: Takuya Noguchi
|
||||
type: other
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Add a comma to the time estimate system notes
|
||||
merge_request: 18326
|
||||
author:
|
||||
type: changed
|
|
@ -1,4 +0,0 @@
|
|||
title: Replace vue resource with axios in pipelines table
|
||||
merge_request:
|
||||
author:
|
||||
type: other
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Improve DB performance of calculating total artifacts size
|
||||
merge_request: 17839
|
||||
author:
|
||||
type: performance
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Make project deploy keys table more clearly structured
|
||||
merge_request: 18279
|
||||
author:
|
||||
type: changed
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Refactor CSS to eliminate vertical misalignment of login nav
|
||||
merge_request: 16275
|
||||
author: Takuya Noguchi
|
||||
type: fixed
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: 'Allow group owner to enable runners from subgroups (#41981)'
|
||||
merge_request: 18009
|
||||
author:
|
||||
type: fixed
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Adds push mirrors to GitLab Community Edition
|
||||
merge_request: 18715
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Automatically accepts project/group invite by email after user signup
|
||||
merge_request: 17634
|
||||
author: Jacopo Beschi @jacopo-beschi
|
||||
type: changed
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Remove ahead/behind graphs on project branches on mobile
|
||||
merge_request: 18415
|
||||
author: Takuya Noguchi
|
||||
type: other
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Show new branch/mr button even when branch exists
|
||||
merge_request: 17712
|
||||
author: Jacopo Beschi @jacopo-beschi
|
||||
type: added
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
title: Rubocop rule to avoid returning from a block
|
||||
merge_request: 18000
|
||||
author: Jacopo Beschi @jacopo-beschi
|
||||
type: added
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue