Merge branch 'master' into 48237-toggle-file-comments
* master: (38 commits) Update bitbucket.md to fix typo and small grammar touchups. Update time_helper.rb to fix output for exact minutes. Document update for GitLab Pages users. Support manually stopping any environment from the UI Fix link to frontend in handbook Shorten CHANGELOG filename to avoid breaking ecryptfs users Replace 48976-rails5-invalid-single-table-inheritance-type-group-is-not-a-subclass-of-gitlab-backgroundmigration-fixcrossprojectlabellinks-namespace.yml Fix mountComponent helper path in docs Fix #48537 - Update avatar only via the projects API Add additional headline for Adding SSH keys to GitLab Request to be a proofreader. Fix specs Fix search bar text input alignment Fix API docs on unauthenticated projects return Adds with_projects optional parameter to /groups/:id API endpoint Docs: make it clear that you need a completely separate domain for Pages Document that we don't want to wait in tests Removes unused store in diffs mr refactor Removes double export for actions in diffs module in mr refactor Remove useless return Use latest gitlab-styles ...
This commit is contained in:
commit
135ead1d83
|
@ -327,7 +327,7 @@ cloud-native-image:
|
|||
cache: {}
|
||||
script:
|
||||
- gem install gitlab --no-ri --no-rdoc
|
||||
- ./trigger-build cng
|
||||
- ./scripts/trigger-build cng
|
||||
only:
|
||||
- tags@gitlab-org/gitlab-ce
|
||||
- tags@gitlab-org/gitlab-ee
|
||||
|
|
|
@ -199,12 +199,6 @@ Naming/HeredocDelimiterCase:
|
|||
Naming/HeredocDelimiterNaming:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 27
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AutoCorrect.
|
||||
Performance/HashEachMethods:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 1
|
||||
Performance/UnfreezeString:
|
||||
Exclude:
|
||||
|
|
6
Gemfile
6
Gemfile
|
@ -104,7 +104,7 @@ gem 'hashie-forbidden_attributes'
|
|||
gem 'kaminari', '~> 1.0'
|
||||
|
||||
# HAML
|
||||
gem 'hamlit', '~> 2.6.1'
|
||||
gem 'hamlit', '~> 2.8.8'
|
||||
|
||||
# Files attachments
|
||||
gem 'carrierwave', '~> 1.2'
|
||||
|
@ -351,9 +351,9 @@ group :development, :test do
|
|||
gem 'spring', '~> 2.0.0'
|
||||
gem 'spring-commands-rspec', '~> 1.0.4'
|
||||
|
||||
gem 'gitlab-styles', '~> 2.3', require: false
|
||||
gem 'gitlab-styles', '~> 2.4', require: false
|
||||
# Pin these dependencies, otherwise a new rule could break the CI pipelines
|
||||
gem 'rubocop', '~> 0.52.1'
|
||||
gem 'rubocop', '~> 0.54.0'
|
||||
gem 'rubocop-rspec', '~> 1.22.1'
|
||||
|
||||
gem 'scss_lint', '~> 0.56.0', require: false
|
||||
|
|
24
Gemfile.lock
24
Gemfile.lock
|
@ -312,8 +312,8 @@ GEM
|
|||
mime-types (>= 1.16)
|
||||
posix-spawn (~> 0.3)
|
||||
gitlab-markup (1.6.4)
|
||||
gitlab-styles (2.3.2)
|
||||
rubocop (~> 0.51)
|
||||
gitlab-styles (2.4.1)
|
||||
rubocop (~> 0.54.0)
|
||||
rubocop-gitlab-security (~> 0.1.0)
|
||||
rubocop-rspec (~> 1.19)
|
||||
gitlab_omniauth-ldap (2.0.4)
|
||||
|
@ -381,8 +381,8 @@ GEM
|
|||
rake (>= 10, < 13)
|
||||
rubocop (>= 0.49.0)
|
||||
sysexits (~> 1.1)
|
||||
hamlit (2.6.1)
|
||||
temple (~> 0.7.6)
|
||||
hamlit (2.8.8)
|
||||
temple (>= 0.8.0)
|
||||
thor
|
||||
tilt
|
||||
hashdiff (0.3.4)
|
||||
|
@ -776,16 +776,16 @@ GEM
|
|||
pg
|
||||
rails
|
||||
sqlite3
|
||||
rubocop (0.52.1)
|
||||
rubocop (0.54.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.4.0.2, < 3.0)
|
||||
parser (>= 2.5)
|
||||
powerpack (~> 0.1)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
rubocop-gitlab-security (0.1.1)
|
||||
rubocop (>= 0.51)
|
||||
rubocop-rspec (1.22.1)
|
||||
rubocop-rspec (1.22.2)
|
||||
rubocop (>= 0.52.1)
|
||||
ruby-enum (0.7.2)
|
||||
i18n
|
||||
|
@ -889,7 +889,7 @@ GEM
|
|||
sys-filesystem (1.1.6)
|
||||
ffi
|
||||
sysexits (1.2.0)
|
||||
temple (0.7.7)
|
||||
temple (0.8.0)
|
||||
test-prof (0.2.5)
|
||||
test_after_commit (1.1.0)
|
||||
activerecord (>= 3.2)
|
||||
|
@ -900,7 +900,7 @@ GEM
|
|||
rack (>= 1, < 3)
|
||||
thor (0.19.4)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.6)
|
||||
tilt (2.0.8)
|
||||
timecop (0.8.1)
|
||||
timfel-krb5-auth (0.8.3)
|
||||
toml (0.1.2)
|
||||
|
@ -1043,7 +1043,7 @@ DEPENDENCIES
|
|||
gitlab-gollum-lib (~> 4.2)
|
||||
gitlab-gollum-rugged_adapter (~> 0.4.4)
|
||||
gitlab-markup (~> 1.6.4)
|
||||
gitlab-styles (~> 2.3)
|
||||
gitlab-styles (~> 2.4)
|
||||
gitlab_omniauth-ldap (~> 2.0.4)
|
||||
gon (~> 6.2)
|
||||
google-api-client (~> 0.19.8)
|
||||
|
@ -1057,7 +1057,7 @@ DEPENDENCIES
|
|||
graphql (~> 1.8.0)
|
||||
grpc (~> 1.11.0)
|
||||
haml_lint (~> 0.26.0)
|
||||
hamlit (~> 2.6.1)
|
||||
hamlit (~> 2.8.8)
|
||||
hashie-forbidden_attributes
|
||||
health_check (~> 2.6.0)
|
||||
hipchat (~> 1.5.0)
|
||||
|
@ -1143,7 +1143,7 @@ DEPENDENCIES
|
|||
rspec-retry (~> 0.4.5)
|
||||
rspec-set (~> 0.1.3)
|
||||
rspec_profiling (~> 0.0.5)
|
||||
rubocop (~> 0.52.1)
|
||||
rubocop (~> 0.54.0)
|
||||
rubocop-rspec (~> 1.22.1)
|
||||
ruby-fogbugz (~> 0.2.1)
|
||||
ruby-prof (~> 0.17.0)
|
||||
|
|
|
@ -79,7 +79,7 @@ GEM
|
|||
babosa (1.0.2)
|
||||
base32 (0.3.2)
|
||||
batch-loader (1.2.1)
|
||||
bcrypt (3.1.11)
|
||||
bcrypt (3.1.12)
|
||||
bcrypt_pbkdf (1.0.0)
|
||||
benchmark-ips (2.3.0)
|
||||
better_errors (2.1.1)
|
||||
|
@ -111,7 +111,7 @@ GEM
|
|||
capybara-screenshot (1.0.14)
|
||||
capybara (>= 1.0, < 3)
|
||||
launchy
|
||||
carrierwave (1.2.1)
|
||||
carrierwave (1.2.3)
|
||||
activemodel (>= 4.0.0)
|
||||
activesupport (>= 4.0.0)
|
||||
mime-types (>= 1.16)
|
||||
|
@ -315,8 +315,8 @@ GEM
|
|||
mime-types (>= 1.16)
|
||||
posix-spawn (~> 0.3)
|
||||
gitlab-markup (1.6.4)
|
||||
gitlab-styles (2.3.2)
|
||||
rubocop (~> 0.51)
|
||||
gitlab-styles (2.4.1)
|
||||
rubocop (~> 0.54.0)
|
||||
rubocop-gitlab-security (~> 0.1.0)
|
||||
rubocop-rspec (~> 1.19)
|
||||
gitlab_omniauth-ldap (2.0.4)
|
||||
|
@ -384,8 +384,8 @@ GEM
|
|||
rake (>= 10, < 13)
|
||||
rubocop (>= 0.49.0)
|
||||
sysexits (~> 1.1)
|
||||
hamlit (2.6.1)
|
||||
temple (~> 0.7.6)
|
||||
hamlit (2.8.8)
|
||||
temple (>= 0.8.0)
|
||||
thor
|
||||
tilt
|
||||
hashdiff (0.3.4)
|
||||
|
@ -514,7 +514,7 @@ GEM
|
|||
net-ssh (5.0.1)
|
||||
netrc (0.11.0)
|
||||
nio4r (2.3.1)
|
||||
nokogiri (1.8.2)
|
||||
nokogiri (1.8.3)
|
||||
mini_portile2 (~> 2.3.0)
|
||||
nokogumbo (1.5.0)
|
||||
nokogiri
|
||||
|
@ -785,16 +785,16 @@ GEM
|
|||
pg
|
||||
rails
|
||||
sqlite3
|
||||
rubocop (0.52.1)
|
||||
rubocop (0.54.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.4.0.2, < 3.0)
|
||||
parser (>= 2.5)
|
||||
powerpack (~> 0.1)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
rubocop-gitlab-security (0.1.1)
|
||||
rubocop (>= 0.51)
|
||||
rubocop-rspec (1.22.1)
|
||||
rubocop-rspec (1.22.2)
|
||||
rubocop (>= 0.52.1)
|
||||
ruby-enum (0.7.2)
|
||||
i18n
|
||||
|
@ -811,7 +811,7 @@ GEM
|
|||
rubyzip (1.2.1)
|
||||
rufus-scheduler (3.4.0)
|
||||
et-orbi (~> 1.0)
|
||||
rugged (0.27.1)
|
||||
rugged (0.27.2)
|
||||
safe_yaml (1.0.4)
|
||||
sanitize (4.6.5)
|
||||
crass (~> 1.0.2)
|
||||
|
@ -877,7 +877,7 @@ GEM
|
|||
activesupport (>= 4.2)
|
||||
spring-commands-rspec (1.0.4)
|
||||
spring (>= 0.9.1)
|
||||
sprockets (3.7.1)
|
||||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.2.1)
|
||||
|
@ -898,7 +898,7 @@ GEM
|
|||
sys-filesystem (1.1.6)
|
||||
ffi
|
||||
sysexits (1.2.0)
|
||||
temple (0.7.7)
|
||||
temple (0.8.0)
|
||||
test-prof (0.2.5)
|
||||
text (1.3.1)
|
||||
thin (1.7.0)
|
||||
|
@ -1053,7 +1053,7 @@ DEPENDENCIES
|
|||
gitlab-gollum-lib (~> 4.2)
|
||||
gitlab-gollum-rugged_adapter (~> 0.4.4)
|
||||
gitlab-markup (~> 1.6.4)
|
||||
gitlab-styles (~> 2.3)
|
||||
gitlab-styles (~> 2.4)
|
||||
gitlab_omniauth-ldap (~> 2.0.4)
|
||||
gon (~> 6.2)
|
||||
google-api-client (~> 0.19.8)
|
||||
|
@ -1067,7 +1067,7 @@ DEPENDENCIES
|
|||
graphql (~> 1.8.0)
|
||||
grpc (~> 1.11.0)
|
||||
haml_lint (~> 0.26.0)
|
||||
hamlit (~> 2.6.1)
|
||||
hamlit (~> 2.8.8)
|
||||
hashie-forbidden_attributes
|
||||
health_check (~> 2.6.0)
|
||||
hipchat (~> 1.5.0)
|
||||
|
@ -1154,7 +1154,7 @@ DEPENDENCIES
|
|||
rspec-retry (~> 0.4.5)
|
||||
rspec-set (~> 0.1.3)
|
||||
rspec_profiling (~> 0.0.5)
|
||||
rubocop (~> 0.52.1)
|
||||
rubocop (~> 0.54.0)
|
||||
rubocop-rspec (~> 1.22.1)
|
||||
ruby-fogbugz (~> 0.2.1)
|
||||
ruby-prof (~> 0.17.0)
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
# GitLab
|
||||
|
||||
[![Build status](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/build.svg)](https://gitlab.com/gitlab-org/gitlab-ce/commits/master)
|
||||
[![Overall test coverage](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg)](https://gitlab.com/gitlab-org/gitlab-ce/pipelines)
|
||||
[![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq)
|
||||
[![Core Infrastructure Initiative Best Practices](https://bestpractices.coreinfrastructure.org/projects/42/badge)](https://bestpractices.coreinfrastructure.org/projects/42)
|
||||
[![Gitter](https://badges.gitter.im/gitlabhq/gitlabhq.svg)](https://gitter.im/gitlabhq/gitlabhq?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
## Test coverage
|
||||
|
||||
- [![Ruby coverage](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg?job=coverage)](https://gitlab-org.gitlab.io/gitlab-ce/coverage-ruby) Ruby
|
||||
|
|
4
Rakefile
4
Rakefile
|
@ -2,9 +2,9 @@
|
|||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||
|
||||
require File.expand_path('../config/application', __FILE__)
|
||||
require File.expand_path('config/application', __dir__)
|
||||
|
||||
relative_url_conf = File.expand_path('../config/initializers/relative_url', __FILE__)
|
||||
relative_url_conf = File.expand_path('config/initializers/relative_url', __dir__)
|
||||
require relative_url_conf if File.exist?("#{relative_url_conf}.rb")
|
||||
|
||||
Gitlab::Application.load_tasks
|
||||
|
|
|
@ -39,11 +39,6 @@ export default {
|
|||
required: false,
|
||||
default: true,
|
||||
},
|
||||
discussionsExpanded: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
currentUser: {
|
||||
type: Object,
|
||||
required: true,
|
||||
|
@ -116,7 +111,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
...mapActions('diffs', ['toggleFileDiscussions']),
|
||||
handleToggle(e, checkTarget) {
|
||||
handleToggleFile(e, checkTarget) {
|
||||
if (
|
||||
!checkTarget ||
|
||||
e.target === this.$refs.header ||
|
||||
|
@ -128,7 +123,7 @@ export default {
|
|||
showForkMessage() {
|
||||
this.$emit('showForkMessage');
|
||||
},
|
||||
handleToggleDiscussions(){
|
||||
handleToggleDiscussions() {
|
||||
this.toggleFileDiscussions(this.diffFile);
|
||||
},
|
||||
},
|
||||
|
@ -139,7 +134,7 @@ export default {
|
|||
<div
|
||||
ref="header"
|
||||
class="js-file-title file-title file-title-flex-parent"
|
||||
@click="handleToggle($event, true)"
|
||||
@click="handleToggleFile($event, true)"
|
||||
>
|
||||
<div class="file-header-content">
|
||||
<icon
|
||||
|
@ -224,9 +219,9 @@ export default {
|
|||
<button
|
||||
:class="{ active: hasExpandedDiscussions }"
|
||||
:title="s__('MergeRequests|Toggle comments for this file')"
|
||||
@click="handleToggleDiscussions"
|
||||
class="btn"
|
||||
class="js-btn-vue-toggle-comments btn"
|
||||
type="button"
|
||||
@click="handleToggleDiscussions"
|
||||
>
|
||||
<icon name="comment" />
|
||||
</button>
|
||||
|
|
|
@ -112,15 +112,5 @@ export const toggleFileDiscussions = ({ getters, dispatch }, diff) => {
|
|||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
setBaseConfig,
|
||||
fetchDiffFiles,
|
||||
setInlineDiffViewType,
|
||||
setParallelDiffViewType,
|
||||
showCommentForm,
|
||||
cancelCommentForm,
|
||||
loadMoreLines,
|
||||
loadCollapsedDiff,
|
||||
expandAllFiles,
|
||||
toggleFileDiscussions,
|
||||
};
|
||||
// prevent babel-plugin-rewire from generating an invalid default during karma tests
|
||||
export default () => {};
|
||||
|
|
|
@ -31,6 +31,20 @@ export const diffHasAllCollpasedDiscussions = (state, getters) => diff => {
|
|||
return (discussions.length && discussions.every(discussion => !discussion.expanded)) || false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the diff has any open discussions
|
||||
* @param {Object} diff
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export const diffHasExpandedDiscussions = (state, getters) => diff => {
|
||||
const discussions = getters.getDiffFileDiscussions(diff);
|
||||
|
||||
return (
|
||||
(discussions.length && discussions.find(discussion => discussion.expanded) !== undefined) ||
|
||||
false
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array with the discussions of the given diff
|
||||
* @param {Object} diff
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import diffsModule from './modules';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
export default new Vuex.Store({
|
||||
modules: {
|
||||
diffs: diffsModule,
|
||||
},
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
import actions from '../actions';
|
||||
import * as actions from '../actions';
|
||||
import * as getters from '../getters';
|
||||
import mutations from '../mutations';
|
||||
import createState from './diff_state';
|
||||
|
|
|
@ -171,6 +171,8 @@ export default class DueDateSelectors {
|
|||
initMilestoneDatePicker() {
|
||||
$('.datepicker').each(function initPikadayMilestone() {
|
||||
const $datePicker = $(this);
|
||||
const datePickerVal = $datePicker.val();
|
||||
|
||||
const calendar = new Pikaday({
|
||||
field: $datePicker.get(0),
|
||||
theme: 'gitlab-theme animate-picker',
|
||||
|
@ -183,7 +185,7 @@ export default class DueDateSelectors {
|
|||
},
|
||||
});
|
||||
|
||||
calendar.setDate(parsePikadayDate($datePicker.val()));
|
||||
calendar.setDate(parsePikadayDate(datePickerVal));
|
||||
|
||||
$datePicker.data('pikaday', calendar);
|
||||
});
|
||||
|
|
|
@ -1,50 +1,50 @@
|
|||
<script>
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import eventHub from '../event_hub';
|
||||
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import eventHub from '../event_hub';
|
||||
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
|
||||
export default {
|
||||
directives: {
|
||||
tooltip,
|
||||
export default {
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
components: {
|
||||
loadingIcon,
|
||||
Icon,
|
||||
},
|
||||
props: {
|
||||
actions: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
},
|
||||
components: {
|
||||
loadingIcon,
|
||||
Icon,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return 'Deploy to...';
|
||||
},
|
||||
props: {
|
||||
actions: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return 'Deploy to...';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onClickAction(endpoint) {
|
||||
this.isLoading = true;
|
||||
},
|
||||
methods: {
|
||||
onClickAction(endpoint) {
|
||||
this.isLoading = true;
|
||||
|
||||
eventHub.$emit('postAction', endpoint);
|
||||
},
|
||||
|
||||
isActionDisabled(action) {
|
||||
if (action.playable === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !action.playable;
|
||||
},
|
||||
eventHub.$emit('postAction', { endpoint });
|
||||
},
|
||||
};
|
||||
|
||||
isActionDisabled(action) {
|
||||
if (action.playable === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !action.playable;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
|
@ -61,10 +61,7 @@
|
|||
data-toggle="dropdown"
|
||||
>
|
||||
<span>
|
||||
<icon
|
||||
:size="12"
|
||||
name="play"
|
||||
/>
|
||||
<icon name="play" />
|
||||
<i
|
||||
class="fa fa-caret-down"
|
||||
aria-hidden="true"
|
||||
|
@ -85,10 +82,6 @@
|
|||
class="js-manual-action-link no-btn btn"
|
||||
@click="onClickAction(action.play_path)"
|
||||
>
|
||||
<icon
|
||||
:size="12"
|
||||
name="play"
|
||||
/>
|
||||
<span>
|
||||
{{ action.name }}
|
||||
</span>
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
<script>
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
import { s__ } from '../../locale';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
import { s__ } from '../../locale';
|
||||
|
||||
/**
|
||||
* Renders the external url link in environments table.
|
||||
*/
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
/**
|
||||
* Renders the external url link in environments table.
|
||||
*/
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
props: {
|
||||
externalUrl: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return s__('Environments|Open live environment');
|
||||
},
|
||||
props: {
|
||||
externalUrl: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return s__('Environments|Open');
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<a
|
||||
|
@ -37,9 +37,6 @@
|
|||
target="_blank"
|
||||
rel="noopener noreferrer nofollow"
|
||||
>
|
||||
<icon
|
||||
:size="12"
|
||||
name="external-link"
|
||||
/>
|
||||
<icon name="external-link" />
|
||||
</a>
|
||||
</template>
|
||||
|
|
|
@ -1,429 +1,450 @@
|
|||
<script>
|
||||
import Timeago from 'timeago.js';
|
||||
import _ from 'underscore';
|
||||
import tooltip from '~/vue_shared/directives/tooltip';
|
||||
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||
import { humanize } from '~/lib/utils/text_utility';
|
||||
import ActionsComponent from './environment_actions.vue';
|
||||
import ExternalUrlComponent from './environment_external_url.vue';
|
||||
import StopComponent from './environment_stop.vue';
|
||||
import RollbackComponent from './environment_rollback.vue';
|
||||
import TerminalButtonComponent from './environment_terminal_button.vue';
|
||||
import MonitoringButtonComponent from './environment_monitoring.vue';
|
||||
import CommitComponent from '../../vue_shared/components/commit.vue';
|
||||
import eventHub from '../event_hub';
|
||||
import Timeago from 'timeago.js';
|
||||
import _ from 'underscore';
|
||||
import tooltip from '~/vue_shared/directives/tooltip';
|
||||
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||
import { humanize } from '~/lib/utils/text_utility';
|
||||
import ActionsComponent from './environment_actions.vue';
|
||||
import ExternalUrlComponent from './environment_external_url.vue';
|
||||
import StopComponent from './environment_stop.vue';
|
||||
import RollbackComponent from './environment_rollback.vue';
|
||||
import TerminalButtonComponent from './environment_terminal_button.vue';
|
||||
import MonitoringButtonComponent from './environment_monitoring.vue';
|
||||
import CommitComponent from '../../vue_shared/components/commit.vue';
|
||||
import eventHub from '../event_hub';
|
||||
|
||||
/**
|
||||
* Envrionment Item Component
|
||||
*
|
||||
* Renders a table row for each environment.
|
||||
*/
|
||||
const timeagoInstance = new Timeago();
|
||||
/**
|
||||
* Envrionment Item Component
|
||||
*
|
||||
* Renders a table row for each environment.
|
||||
*/
|
||||
const timeagoInstance = new Timeago();
|
||||
|
||||
export default {
|
||||
components: {
|
||||
UserAvatarLink,
|
||||
CommitComponent,
|
||||
ActionsComponent,
|
||||
ExternalUrlComponent,
|
||||
StopComponent,
|
||||
RollbackComponent,
|
||||
TerminalButtonComponent,
|
||||
MonitoringButtonComponent,
|
||||
export default {
|
||||
components: {
|
||||
UserAvatarLink,
|
||||
CommitComponent,
|
||||
ActionsComponent,
|
||||
ExternalUrlComponent,
|
||||
StopComponent,
|
||||
RollbackComponent,
|
||||
TerminalButtonComponent,
|
||||
MonitoringButtonComponent,
|
||||
},
|
||||
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
|
||||
directives: {
|
||||
tooltip,
|
||||
canCreateDeployment: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
canReadEnvironment: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
|
||||
canCreateDeployment: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
|
||||
canReadEnvironment: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
computed: {
|
||||
/**
|
||||
* Verifies if `last_deployment` key exists in the current Envrionment.
|
||||
* This key is required to render most of the html - this method works has
|
||||
* an helper.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasLastDeploymentKey() {
|
||||
if (this.model && this.model.last_deployment && !_.isEmpty(this.model.last_deployment)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
computed: {
|
||||
/**
|
||||
* Verifies if `last_deployment` key exists in the current Envrionment.
|
||||
* This key is required to render most of the html - this method works has
|
||||
* an helper.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasLastDeploymentKey() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
!_.isEmpty(this.model.last_deployment)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies is the given environment has manual actions.
|
||||
* Used to verify if we should render them or nor.
|
||||
*
|
||||
* @returns {Boolean|Undefined}
|
||||
*/
|
||||
hasManualActions() {
|
||||
return this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.manual_actions &&
|
||||
this.model.last_deployment.manual_actions.length > 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the value of the `stop_action?` key provided in the response.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasStopAction() {
|
||||
return this.model && this.model['stop_action?'];
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the `deployable` key is present in `last_deployment` key.
|
||||
* Used to verify whether we should or not render the rollback partial.
|
||||
*
|
||||
* @returns {Boolean|Undefined}
|
||||
*/
|
||||
canRetry() {
|
||||
return this.model &&
|
||||
this.hasLastDeploymentKey &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.deployable;
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the date to be shown is present.
|
||||
*
|
||||
* @returns {Boolean|Undefined}
|
||||
*/
|
||||
canShowDate() {
|
||||
return this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.deployable &&
|
||||
this.model.last_deployment.deployable !== undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Human readable date.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
createdDate() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.deployable &&
|
||||
this.model.last_deployment.deployable.created_at) {
|
||||
return timeagoInstance.format(this.model.last_deployment.deployable.created_at);
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the manual actions with the name parsed.
|
||||
*
|
||||
* @returns {Array.<Object>|Undefined}
|
||||
*/
|
||||
manualActions() {
|
||||
if (this.hasManualActions) {
|
||||
return this.model.last_deployment.manual_actions.map((action) => {
|
||||
const parsedAction = {
|
||||
name: humanize(action.name),
|
||||
play_path: action.play_path,
|
||||
playable: action.playable,
|
||||
};
|
||||
return parsedAction;
|
||||
});
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Builds the string used in the user image alt attribute.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
userImageAltDescription() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.user &&
|
||||
this.model.last_deployment.user.username) {
|
||||
return `${this.model.last_deployment.user.username}'s avatar'`;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit tag.
|
||||
*
|
||||
* @returns {String|Undefined}
|
||||
*/
|
||||
commitTag() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.tag) {
|
||||
return this.model.last_deployment.tag;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit ref.
|
||||
*
|
||||
* @returns {Object|Undefined}
|
||||
*/
|
||||
commitRef() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.ref) {
|
||||
return this.model.last_deployment.ref;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit url.
|
||||
*
|
||||
* @returns {String|Undefined}
|
||||
*/
|
||||
commitUrl() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.commit &&
|
||||
this.model.last_deployment.commit.commit_path) {
|
||||
return this.model.last_deployment.commit.commit_path;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit short sha.
|
||||
*
|
||||
* @returns {String|Undefined}
|
||||
*/
|
||||
commitShortSha() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.commit &&
|
||||
this.model.last_deployment.commit.short_id) {
|
||||
return this.model.last_deployment.commit.short_id;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit title.
|
||||
*
|
||||
* @returns {String|Undefined}
|
||||
*/
|
||||
commitTitle() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.commit &&
|
||||
this.model.last_deployment.commit.title) {
|
||||
return this.model.last_deployment.commit.title;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit tag.
|
||||
*
|
||||
* @returns {Object|Undefined}
|
||||
*/
|
||||
commitAuthor() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.commit &&
|
||||
this.model.last_deployment.commit.author) {
|
||||
return this.model.last_deployment.commit.author;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the `retry_path` key is present and returns its value.
|
||||
*
|
||||
* @returns {String|Undefined}
|
||||
*/
|
||||
retryUrl() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.deployable &&
|
||||
this.model.last_deployment.deployable.retry_path) {
|
||||
return this.model.last_deployment.deployable.retry_path;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the `last?` key is present and returns its value.
|
||||
*
|
||||
* @returns {Boolean|Undefined}
|
||||
*/
|
||||
isLastDeployment() {
|
||||
return this.model && this.model.last_deployment &&
|
||||
this.model.last_deployment['last?'];
|
||||
},
|
||||
|
||||
/**
|
||||
* Builds the name of the builds needed to display both the name and the id.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
buildName() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.deployable) {
|
||||
const { deployable } = this.model.last_deployment;
|
||||
return `${deployable.name} #${deployable.id}`;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Builds the needed string to show the internal id.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
deploymentInternalId() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.iid) {
|
||||
return `#${this.model.last_deployment.iid}`;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the user object is present under last_deployment object.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
deploymentHasUser() {
|
||||
return this.model &&
|
||||
!_.isEmpty(this.model.last_deployment) &&
|
||||
!_.isEmpty(this.model.last_deployment.user);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the user object nested with the last_deployment object.
|
||||
* Used to render the template.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
deploymentUser() {
|
||||
if (this.model &&
|
||||
!_.isEmpty(this.model.last_deployment) &&
|
||||
!_.isEmpty(this.model.last_deployment.user)) {
|
||||
return this.model.last_deployment.user;
|
||||
}
|
||||
return {};
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the build name column should be rendered by verifing
|
||||
* if all the information needed is present
|
||||
* and if the environment is not a folder.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
shouldRenderBuildName() {
|
||||
return !this.model.isFolder &&
|
||||
!_.isEmpty(this.model.last_deployment) &&
|
||||
!_.isEmpty(this.model.last_deployment.deployable);
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies the presence of all the keys needed to render the buil_path.
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
buildPath() {
|
||||
if (this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.deployable &&
|
||||
this.model.last_deployment.deployable.build_path) {
|
||||
return this.model.last_deployment.deployable.build_path;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies the presence of all the keys needed to render the external_url.
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
externalURL() {
|
||||
if (this.model && this.model.external_url) {
|
||||
return this.model.external_url;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if deplyment internal ID should be rendered by verifing
|
||||
* if all the information needed is present
|
||||
* and if the environment is not a folder.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
shouldRenderDeploymentID() {
|
||||
return !this.model.isFolder &&
|
||||
!_.isEmpty(this.model.last_deployment) &&
|
||||
this.model.last_deployment.iid !== undefined;
|
||||
},
|
||||
|
||||
environmentPath() {
|
||||
if (this.model && this.model.environment_path) {
|
||||
return this.model.environment_path;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
monitoringUrl() {
|
||||
if (this.model && this.model.metrics_path) {
|
||||
return this.model.metrics_path;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
displayEnvironmentActions() {
|
||||
return this.hasManualActions ||
|
||||
this.externalURL ||
|
||||
this.monitoringUrl ||
|
||||
this.hasStopAction ||
|
||||
this.canRetry;
|
||||
},
|
||||
/**
|
||||
* Verifies is the given environment has manual actions.
|
||||
* Used to verify if we should render them or nor.
|
||||
*
|
||||
* @returns {Boolean|Undefined}
|
||||
*/
|
||||
hasManualActions() {
|
||||
return (
|
||||
this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.manual_actions &&
|
||||
this.model.last_deployment.manual_actions.length > 0
|
||||
);
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClickFolder() {
|
||||
eventHub.$emit('toggleFolder', this.model);
|
||||
},
|
||||
/**
|
||||
* Returns whether the environment can be stopped.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
canStopEnvironment() {
|
||||
return this.model && this.model.can_stop;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Verifies if the `deployable` key is present in `last_deployment` key.
|
||||
* Used to verify whether we should or not render the rollback partial.
|
||||
*
|
||||
* @returns {Boolean|Undefined}
|
||||
*/
|
||||
canRetry() {
|
||||
return (
|
||||
this.model &&
|
||||
this.hasLastDeploymentKey &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.deployable
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the date to be shown is present.
|
||||
*
|
||||
* @returns {Boolean|Undefined}
|
||||
*/
|
||||
canShowDate() {
|
||||
return (
|
||||
this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.deployable &&
|
||||
this.model.last_deployment.deployable !== undefined
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Human readable date.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
createdDate() {
|
||||
if (
|
||||
this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.deployable &&
|
||||
this.model.last_deployment.deployable.created_at
|
||||
) {
|
||||
return timeagoInstance.format(this.model.last_deployment.deployable.created_at);
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the manual actions with the name parsed.
|
||||
*
|
||||
* @returns {Array.<Object>|Undefined}
|
||||
*/
|
||||
manualActions() {
|
||||
if (this.hasManualActions) {
|
||||
return this.model.last_deployment.manual_actions.map(action => {
|
||||
const parsedAction = {
|
||||
name: humanize(action.name),
|
||||
play_path: action.play_path,
|
||||
playable: action.playable,
|
||||
};
|
||||
return parsedAction;
|
||||
});
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Builds the string used in the user image alt attribute.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
userImageAltDescription() {
|
||||
if (
|
||||
this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.user &&
|
||||
this.model.last_deployment.user.username
|
||||
) {
|
||||
return `${this.model.last_deployment.user.username}'s avatar'`;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit tag.
|
||||
*
|
||||
* @returns {String|Undefined}
|
||||
*/
|
||||
commitTag() {
|
||||
if (this.model && this.model.last_deployment && this.model.last_deployment.tag) {
|
||||
return this.model.last_deployment.tag;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit ref.
|
||||
*
|
||||
* @returns {Object|Undefined}
|
||||
*/
|
||||
commitRef() {
|
||||
if (this.model && this.model.last_deployment && this.model.last_deployment.ref) {
|
||||
return this.model.last_deployment.ref;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit url.
|
||||
*
|
||||
* @returns {String|Undefined}
|
||||
*/
|
||||
commitUrl() {
|
||||
if (
|
||||
this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.commit &&
|
||||
this.model.last_deployment.commit.commit_path
|
||||
) {
|
||||
return this.model.last_deployment.commit.commit_path;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit short sha.
|
||||
*
|
||||
* @returns {String|Undefined}
|
||||
*/
|
||||
commitShortSha() {
|
||||
if (
|
||||
this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.commit &&
|
||||
this.model.last_deployment.commit.short_id
|
||||
) {
|
||||
return this.model.last_deployment.commit.short_id;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit title.
|
||||
*
|
||||
* @returns {String|Undefined}
|
||||
*/
|
||||
commitTitle() {
|
||||
if (
|
||||
this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.commit &&
|
||||
this.model.last_deployment.commit.title
|
||||
) {
|
||||
return this.model.last_deployment.commit.title;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* If provided, returns the commit tag.
|
||||
*
|
||||
* @returns {Object|Undefined}
|
||||
*/
|
||||
commitAuthor() {
|
||||
if (
|
||||
this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.commit &&
|
||||
this.model.last_deployment.commit.author
|
||||
) {
|
||||
return this.model.last_deployment.commit.author;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the `retry_path` key is present and returns its value.
|
||||
*
|
||||
* @returns {String|Undefined}
|
||||
*/
|
||||
retryUrl() {
|
||||
if (
|
||||
this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.deployable &&
|
||||
this.model.last_deployment.deployable.retry_path
|
||||
) {
|
||||
return this.model.last_deployment.deployable.retry_path;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the `last?` key is present and returns its value.
|
||||
*
|
||||
* @returns {Boolean|Undefined}
|
||||
*/
|
||||
isLastDeployment() {
|
||||
return this.model && this.model.last_deployment && this.model.last_deployment['last?'];
|
||||
},
|
||||
|
||||
/**
|
||||
* Builds the name of the builds needed to display both the name and the id.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
buildName() {
|
||||
if (this.model && this.model.last_deployment && this.model.last_deployment.deployable) {
|
||||
const { deployable } = this.model.last_deployment;
|
||||
return `${deployable.name} #${deployable.id}`;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Builds the needed string to show the internal id.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
deploymentInternalId() {
|
||||
if (this.model && this.model.last_deployment && this.model.last_deployment.iid) {
|
||||
return `#${this.model.last_deployment.iid}`;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the user object is present under last_deployment object.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
deploymentHasUser() {
|
||||
return (
|
||||
this.model &&
|
||||
!_.isEmpty(this.model.last_deployment) &&
|
||||
!_.isEmpty(this.model.last_deployment.user)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the user object nested with the last_deployment object.
|
||||
* Used to render the template.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
deploymentUser() {
|
||||
if (
|
||||
this.model &&
|
||||
!_.isEmpty(this.model.last_deployment) &&
|
||||
!_.isEmpty(this.model.last_deployment.user)
|
||||
) {
|
||||
return this.model.last_deployment.user;
|
||||
}
|
||||
return {};
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the build name column should be rendered by verifing
|
||||
* if all the information needed is present
|
||||
* and if the environment is not a folder.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
shouldRenderBuildName() {
|
||||
return (
|
||||
!this.model.isFolder &&
|
||||
!_.isEmpty(this.model.last_deployment) &&
|
||||
!_.isEmpty(this.model.last_deployment.deployable)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies the presence of all the keys needed to render the buil_path.
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
buildPath() {
|
||||
if (
|
||||
this.model &&
|
||||
this.model.last_deployment &&
|
||||
this.model.last_deployment.deployable &&
|
||||
this.model.last_deployment.deployable.build_path
|
||||
) {
|
||||
return this.model.last_deployment.deployable.build_path;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies the presence of all the keys needed to render the external_url.
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
externalURL() {
|
||||
if (this.model && this.model.external_url) {
|
||||
return this.model.external_url;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if deplyment internal ID should be rendered by verifing
|
||||
* if all the information needed is present
|
||||
* and if the environment is not a folder.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
shouldRenderDeploymentID() {
|
||||
return (
|
||||
!this.model.isFolder &&
|
||||
!_.isEmpty(this.model.last_deployment) &&
|
||||
this.model.last_deployment.iid !== undefined
|
||||
);
|
||||
},
|
||||
|
||||
environmentPath() {
|
||||
if (this.model && this.model.environment_path) {
|
||||
return this.model.environment_path;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
monitoringUrl() {
|
||||
if (this.model && this.model.metrics_path) {
|
||||
return this.model.metrics_path;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
displayEnvironmentActions() {
|
||||
return (
|
||||
this.hasManualActions ||
|
||||
this.externalURL ||
|
||||
this.monitoringUrl ||
|
||||
this.canStopEnvironment ||
|
||||
this.canRetry
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClickFolder() {
|
||||
eventHub.$emit('toggleFolder', this.model);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
|
@ -580,11 +601,6 @@
|
|||
class="btn-group table-action-buttons"
|
||||
role="group">
|
||||
|
||||
<actions-component
|
||||
v-if="hasManualActions && canCreateDeployment"
|
||||
:actions="manualActions"
|
||||
/>
|
||||
|
||||
<external-url-component
|
||||
v-if="externalURL && canReadEnvironment"
|
||||
:external-url="externalURL"
|
||||
|
@ -595,21 +611,26 @@
|
|||
:monitoring-url="monitoringUrl"
|
||||
/>
|
||||
|
||||
<actions-component
|
||||
v-if="hasManualActions && canCreateDeployment"
|
||||
:actions="manualActions"
|
||||
/>
|
||||
|
||||
<terminal-button-component
|
||||
v-if="model && model.terminal_path"
|
||||
:terminal-path="model.terminal_path"
|
||||
/>
|
||||
|
||||
<stop-component
|
||||
v-if="hasStopAction && canCreateDeployment"
|
||||
:stop-url="model.stop_path"
|
||||
/>
|
||||
|
||||
<rollback-component
|
||||
v-if="canRetry && canCreateDeployment"
|
||||
:is-last-deployment="isLastDeployment"
|
||||
:retry-url="retryUrl"
|
||||
/>
|
||||
|
||||
<stop-component
|
||||
v-if="canStopEnvironment"
|
||||
:environment="model"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
<script>
|
||||
/**
|
||||
* Renders the Monitoring (Metrics) link in environments table.
|
||||
*/
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
/**
|
||||
* Renders the Monitoring (Metrics) link in environments table.
|
||||
*/
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
props: {
|
||||
monitoringUrl: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return 'Monitoring';
|
||||
},
|
||||
props: {
|
||||
monitoringUrl: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return 'Monitoring';
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<a
|
||||
|
@ -35,9 +35,6 @@
|
|||
data-container="body"
|
||||
rel="noopener noreferrer nofollow"
|
||||
>
|
||||
<icon
|
||||
:size="12"
|
||||
name="chart"
|
||||
/>
|
||||
<icon name="chart" />
|
||||
</a>
|
||||
</template>
|
||||
|
|
|
@ -1,56 +1,74 @@
|
|||
<script>
|
||||
/**
|
||||
* Renders Rollback or Re deploy button in environments table depending
|
||||
* of the provided property `isLastDeployment`.
|
||||
*
|
||||
* Makes a post request when the button is clicked.
|
||||
*/
|
||||
import eventHub from '../event_hub';
|
||||
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
|
||||
/**
|
||||
* Renders Rollback or Re deploy button in environments table depending
|
||||
* of the provided property `isLastDeployment`.
|
||||
*
|
||||
* Makes a post request when the button is clicked.
|
||||
*/
|
||||
import { s__ } from '~/locale';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import tooltip from '~/vue_shared/directives/tooltip';
|
||||
import eventHub from '../event_hub';
|
||||
import LoadingIcon from '../../vue_shared/components/loading_icon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
loadingIcon,
|
||||
},
|
||||
props: {
|
||||
retryUrl: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
LoadingIcon,
|
||||
},
|
||||
|
||||
isLastDeployment: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
this.isLoading = true;
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
|
||||
eventHub.$emit('postAction', this.retryUrl);
|
||||
},
|
||||
props: {
|
||||
retryUrl: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
};
|
||||
|
||||
isLastDeployment: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
title() {
|
||||
return this.isLastDeployment ? s__('Environments|Re-deploy to environment') : s__('Environments|Rollback environment');
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClick() {
|
||||
this.isLoading = true;
|
||||
|
||||
eventHub.$emit('postAction', { endpoint: this.retryUrl });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<button
|
||||
v-tooltip
|
||||
:disabled="isLoading"
|
||||
:title="title"
|
||||
type="button"
|
||||
class="btn d-none d-sm-none d-md-block"
|
||||
@click="onClick"
|
||||
>
|
||||
|
||||
<span v-if="isLastDeployment">
|
||||
{{ s__("Environments|Re-deploy") }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ s__("Environments|Rollback") }}
|
||||
</span>
|
||||
<icon
|
||||
v-if="isLastDeployment"
|
||||
name="repeat" />
|
||||
<icon
|
||||
v-else
|
||||
name="redo"/>
|
||||
|
||||
<loading-icon v-if="isLoading" />
|
||||
</button>
|
||||
|
|
|
@ -1,72 +1,78 @@
|
|||
<script>
|
||||
/**
|
||||
* Renders the stop "button" that allows stop an environment.
|
||||
* Used in environments table.
|
||||
*/
|
||||
/**
|
||||
* Renders the stop "button" that allows stop an environment.
|
||||
* Used in environments table.
|
||||
*/
|
||||
|
||||
import $ from 'jquery';
|
||||
import eventHub from '../event_hub';
|
||||
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
import $ from 'jquery';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import { s__ } from '~/locale';
|
||||
import eventHub from '../event_hub';
|
||||
import LoadingButton from '../../vue_shared/components/loading_button.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
loadingIcon,
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
LoadingButton,
|
||||
},
|
||||
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
|
||||
props: {
|
||||
environment: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
directives: {
|
||||
tooltip,
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
title() {
|
||||
return s__('Environments|Stop environment');
|
||||
},
|
||||
},
|
||||
|
||||
props: {
|
||||
stopUrl: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
mounted() {
|
||||
eventHub.$on('stopEnvironment', this.onStopEnvironment);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
eventHub.$off('stopEnvironment', this.onStopEnvironment);
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClick() {
|
||||
$(this.$el).tooltip('dispose');
|
||||
eventHub.$emit('requestStopEnvironment', this.environment);
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
};
|
||||
onStopEnvironment(environment) {
|
||||
if (this.environment.id === environment.id) {
|
||||
this.isLoading = true;
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
title() {
|
||||
return 'Stop';
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClick() {
|
||||
// eslint-disable-next-line no-alert
|
||||
if (window.confirm('Are you sure you want to stop this environment?')) {
|
||||
this.isLoading = true;
|
||||
|
||||
$(this.$el).tooltip('dispose');
|
||||
|
||||
eventHub.$emit('postAction', this.stopUrl);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<button
|
||||
<loading-button
|
||||
v-tooltip
|
||||
:disabled="isLoading"
|
||||
:loading="isLoading"
|
||||
:title="title"
|
||||
:aria-label="title"
|
||||
type="button"
|
||||
class="btn stop-env-link d-none d-sm-none d-md-block"
|
||||
container-class="btn btn-danger d-none d-sm-none d-md-block"
|
||||
data-container="body"
|
||||
data-toggle="modal"
|
||||
data-target="#stop-environment-modal"
|
||||
@click="onClick"
|
||||
>
|
||||
<i
|
||||
class="fa fa-stop stop-env-icon"
|
||||
aria-hidden="true"
|
||||
>
|
||||
</i>
|
||||
<loading-icon v-if="isLoading" />
|
||||
</button>
|
||||
<icon name="stop"/>
|
||||
</loading-button>
|
||||
</template>
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
<script>
|
||||
/**
|
||||
* Renders a terminal button to open a web terminal.
|
||||
* Used in environments table.
|
||||
*/
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
/**
|
||||
* Renders a terminal button to open a web terminal.
|
||||
* Used in environments table.
|
||||
*/
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
props: {
|
||||
terminalPath: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return 'Terminal';
|
||||
},
|
||||
props: {
|
||||
terminalPath: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return 'Terminal';
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<a
|
||||
|
@ -36,9 +36,6 @@
|
|||
class="btn terminal-button d-none d-sm-none d-md-block"
|
||||
data-container="body"
|
||||
>
|
||||
<icon
|
||||
:size="12"
|
||||
name="terminal"
|
||||
/>
|
||||
<icon name="terminal" />
|
||||
</a>
|
||||
</template>
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
import eventHub from '../event_hub';
|
||||
import environmentsMixin from '../mixins/environments_mixin';
|
||||
import CIPaginationMixin from '../../vue_shared/mixins/ci_pagination_api_mixin';
|
||||
import StopEnvironmentModal from './stop_environment_modal.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
emptyState,
|
||||
StopEnvironmentModal,
|
||||
},
|
||||
|
||||
mixins: [
|
||||
|
@ -90,6 +92,8 @@
|
|||
</script>
|
||||
<template>
|
||||
<div :class="cssContainerClass">
|
||||
<stop-environment-modal :environment="environmentInStopModal" />
|
||||
|
||||
<div class="top-area">
|
||||
<tabs
|
||||
:tabs="tabs"
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
<script>
|
||||
import GlModal from '~/vue_shared/components/gl_modal.vue';
|
||||
import { s__, sprintf } from '~/locale';
|
||||
import tooltip from '~/vue_shared/directives/tooltip';
|
||||
import LoadingButton from '~/vue_shared/components/loading_button.vue';
|
||||
import eventHub from '../event_hub';
|
||||
|
||||
export default {
|
||||
id: 'stop-environment-modal',
|
||||
name: 'StopEnvironmentModal',
|
||||
|
||||
components: {
|
||||
GlModal,
|
||||
LoadingButton,
|
||||
},
|
||||
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
|
||||
props: {
|
||||
environment: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
noStopActionMessage() {
|
||||
return sprintf(
|
||||
s__(
|
||||
`Environments|Note that this action will stop the environment,
|
||||
but it will %{emphasisStart}not%{emphasisEnd} have an effect on any existing deployment
|
||||
due to no “stop environment action” being defined
|
||||
in the %{ciConfigLinkStart}.gitlab-ci.yml%{ciConfigLinkEnd} file.`,
|
||||
),
|
||||
{
|
||||
emphasisStart: '<strong>',
|
||||
emphasisEnd: '</strong>',
|
||||
ciConfigLinkStart:
|
||||
'<a href="https://docs.gitlab.com/ee/ci/yaml/" target="_blank" rel="noopener noreferrer">',
|
||||
ciConfigLinkEnd: '</a>',
|
||||
},
|
||||
false,
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
onSubmit() {
|
||||
eventHub.$emit('stopEnvironment', this.environment);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<gl-modal
|
||||
:id="$options.id"
|
||||
:footer-primary-button-text="s__('Environments|Stop environment')"
|
||||
footer-primary-button-variant="danger"
|
||||
@submit="onSubmit"
|
||||
>
|
||||
<template slot="header">
|
||||
<h4
|
||||
class="modal-title d-flex mw-100"
|
||||
>
|
||||
Stopping
|
||||
<span
|
||||
v-tooltip
|
||||
:title="environment.name"
|
||||
class="text-truncate ml-1 mr-1 flex-fill"
|
||||
>{{ environment.name }}</span>
|
||||
?
|
||||
</h4>
|
||||
</template>
|
||||
|
||||
<p>{{ s__('Environments|Are you sure you want to stop this environment?') }}</p>
|
||||
|
||||
<div
|
||||
v-if="!environment.has_stop_action"
|
||||
class="warning_message"
|
||||
>
|
||||
<p v-html="noStopActionMessage"></p>
|
||||
<a
|
||||
href="https://docs.gitlab.com/ee/ci/environments.html#stopping-an-environment"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>{{ s__('Environments|Learn more about stopping environments') }}</a>
|
||||
</div>
|
||||
</gl-modal>
|
||||
</template>
|
|
@ -1,12 +1,18 @@
|
|||
<script>
|
||||
import environmentsMixin from '../mixins/environments_mixin';
|
||||
import CIPaginationMixin from '../../vue_shared/mixins/ci_pagination_api_mixin';
|
||||
import StopEnvironmentModal from '../components/stop_environment_modal.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
StopEnvironmentModal,
|
||||
},
|
||||
|
||||
mixins: [
|
||||
environmentsMixin,
|
||||
CIPaginationMixin,
|
||||
],
|
||||
|
||||
props: {
|
||||
endpoint: {
|
||||
type: String,
|
||||
|
@ -38,6 +44,8 @@
|
|||
</script>
|
||||
<template>
|
||||
<div :class="cssContainerClass">
|
||||
<stop-environment-modal :environment="environmentInStopModal" />
|
||||
|
||||
<div
|
||||
v-if="!isLoading"
|
||||
class="top-area"
|
||||
|
|
|
@ -40,6 +40,7 @@ export default {
|
|||
scope: getParameterByName('scope') || 'available',
|
||||
page: getParameterByName('page') || '1',
|
||||
requestData: {},
|
||||
environmentInStopModal: {},
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -85,7 +86,7 @@ export default {
|
|||
Flash(s__('Environments|An error occurred while fetching the environments.'));
|
||||
},
|
||||
|
||||
postAction(endpoint) {
|
||||
postAction({ endpoint, errorMessage }) {
|
||||
if (!this.isMakingRequest) {
|
||||
this.isLoading = true;
|
||||
|
||||
|
@ -93,7 +94,7 @@ export default {
|
|||
.then(() => this.fetchEnvironments())
|
||||
.catch(() => {
|
||||
this.isLoading = false;
|
||||
Flash(s__('Environments|An error occurred while making the request.'));
|
||||
Flash(errorMessage || s__('Environments|An error occurred while making the request.'));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -106,6 +107,15 @@ export default {
|
|||
.catch(this.errorCallback);
|
||||
},
|
||||
|
||||
updateStopModal(environment) {
|
||||
this.environmentInStopModal = environment;
|
||||
},
|
||||
|
||||
stopEnvironment(environment) {
|
||||
const endpoint = environment.stop_path;
|
||||
const errorMessage = s__('Environments|An error occurred while stopping the environment, please try again');
|
||||
this.postAction({ endpoint, errorMessage });
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
@ -162,9 +172,13 @@ export default {
|
|||
});
|
||||
|
||||
eventHub.$on('postAction', this.postAction);
|
||||
eventHub.$on('requestStopEnvironment', this.updateStopModal);
|
||||
eventHub.$on('stopEnvironment', this.stopEnvironment);
|
||||
},
|
||||
|
||||
beforeDestroyed() {
|
||||
eventHub.$off('postAction');
|
||||
beforeDestroy() {
|
||||
eventHub.$off('postAction', this.postAction);
|
||||
eventHub.$off('requestStopEnvironment', this.updateStopModal);
|
||||
eventHub.$off('stopEnvironment', this.stopEnvironment);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@ export default class EnvironmentsService {
|
|||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
postAction(endpoint) {
|
||||
return axios.post(endpoint, {}, { emulateJSON: true });
|
||||
return axios.post(endpoint, {});
|
||||
}
|
||||
|
||||
getFolderContent(folderUrl) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
export const ADD_NEW_NOTE = 'ADD_NEW_NOTE';
|
||||
export const ADD_NEW_REPLY_TO_DISCUSSION = 'ADD_NEW_REPLY_TO_DISCUSSION';
|
||||
export const DELETE_NOTE = 'DELETE_NOTE';
|
||||
export const EXPAND_DISCUSSION = 'EXPAND_DISCUSSION';
|
||||
export const REMOVE_PLACEHOLDER_NOTES = 'REMOVE_PLACEHOLDER_NOTES';
|
||||
export const SET_NOTES_DATA = 'SET_NOTES_DATA';
|
||||
export const SET_NOTEABLE_DATA = 'SET_NOTEABLE_DATA';
|
||||
|
@ -11,15 +10,15 @@ export const SET_LAST_FETCHED_AT = 'SET_LAST_FETCHED_AT';
|
|||
export const SET_TARGET_NOTE_HASH = 'SET_TARGET_NOTE_HASH';
|
||||
export const SHOW_PLACEHOLDER_NOTE = 'SHOW_PLACEHOLDER_NOTE';
|
||||
export const TOGGLE_AWARD = 'TOGGLE_AWARD';
|
||||
export const TOGGLE_DISCUSSION = 'TOGGLE_DISCUSSION';
|
||||
export const UPDATE_NOTE = 'UPDATE_NOTE';
|
||||
export const UPDATE_DISCUSSION = 'UPDATE_DISCUSSION';
|
||||
export const SET_DISCUSSION_DIFF_LINES = 'SET_DISCUSSION_DIFF_LINES';
|
||||
export const SET_NOTES_FETCHED_STATE = 'SET_NOTES_FETCHED_STATE';
|
||||
|
||||
// DISCUSSION
|
||||
|
||||
export const COLLAPSE_DISCUSSION = 'COLLAPSE_DISCUSSION';
|
||||
export const EXPAND_DISCUSSION = 'EXPAND_DISCUSSION';
|
||||
export const TOGGLE_DISCUSSION = 'TOGGLE_DISCUSSION';
|
||||
|
||||
// Issue
|
||||
export const CLOSE_ISSUE = 'CLOSE_ISSUE';
|
||||
|
|
|
@ -224,7 +224,10 @@
|
|||
.form-control {
|
||||
position: relative;
|
||||
min-width: 200px;
|
||||
padding: 5px 25px 6px 0;
|
||||
padding-right: 25px;
|
||||
padding-left: 0;
|
||||
height: $input-height;
|
||||
line-height: inherit;
|
||||
border-color: transparent;
|
||||
|
||||
&:focus,
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
}
|
||||
|
||||
.btn-group {
|
||||
> a {
|
||||
> .btn:not(.btn-danger) {
|
||||
color: $gl-text-color-secondary;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class Admin::DeployKeysController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
if deploy_key.update_attributes(update_params)
|
||||
if deploy_key.update(update_params)
|
||||
flash[:notice] = 'Deploy key was successfully updated.'
|
||||
redirect_to admin_deploy_keys_path
|
||||
else
|
||||
|
@ -34,7 +34,7 @@ class Admin::DeployKeysController < Admin::ApplicationController
|
|||
deploy_key.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to admin_deploy_keys_path, status: 302 }
|
||||
format.html { redirect_to admin_deploy_keys_path, status: :found }
|
||||
format.json { head :ok }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -39,7 +39,7 @@ class Admin::GroupsController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
if @group.update_attributes(group_params)
|
||||
if @group.update(group_params)
|
||||
redirect_to [:admin, @group], notice: 'Group was successfully updated.'
|
||||
else
|
||||
render "edit"
|
||||
|
|
|
@ -23,7 +23,7 @@ class Admin::HooksController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
if hook.update_attributes(hook_params)
|
||||
if hook.update(hook_params)
|
||||
flash[:notice] = 'System hook was successfully updated.'
|
||||
redirect_to admin_hooks_path
|
||||
else
|
||||
|
@ -34,7 +34,7 @@ class Admin::HooksController < Admin::ApplicationController
|
|||
def destroy
|
||||
hook.destroy
|
||||
|
||||
redirect_to admin_hooks_path, status: 302
|
||||
redirect_to admin_hooks_path, status: :found
|
||||
end
|
||||
|
||||
def test
|
||||
|
|
|
@ -25,7 +25,7 @@ class Admin::IdentitiesController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
if @identity.update_attributes(identity_params)
|
||||
if @identity.update(identity_params)
|
||||
RepairLdapBlockedUserService.new(@user).execute
|
||||
redirect_to admin_user_identities_path(@user), notice: 'User identity was successfully updated.'
|
||||
else
|
||||
|
|
|
@ -11,7 +11,7 @@ class Admin::ImpersonationsController < Admin::ApplicationController
|
|||
|
||||
session[:impersonator_id] = nil
|
||||
|
||||
redirect_to admin_user_path(original_user), status: 302
|
||||
redirect_to admin_user_path(original_user), status: :found
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -20,6 +20,6 @@ class Admin::JobsController < Admin::ApplicationController
|
|||
def cancel_all
|
||||
Ci::Build.running_or_pending.each(&:cancel)
|
||||
|
||||
redirect_to admin_jobs_path, status: 303
|
||||
redirect_to admin_jobs_path, status: :see_other
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ class Admin::RunnerProjectsController < Admin::ApplicationController
|
|||
runner = rp.runner
|
||||
rp.destroy
|
||||
|
||||
redirect_to admin_runner_path(runner), status: 302
|
||||
redirect_to admin_runner_path(runner), status: :found
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -28,7 +28,7 @@ class Admin::RunnersController < Admin::ApplicationController
|
|||
def destroy
|
||||
@runner.destroy
|
||||
|
||||
redirect_to admin_runners_path, status: 302
|
||||
redirect_to admin_runners_path, status: :found
|
||||
end
|
||||
|
||||
def resume
|
||||
|
|
|
@ -16,7 +16,7 @@ class Admin::ServicesController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
if service.update_attributes(service_params[:service])
|
||||
if service.update(service_params[:service])
|
||||
PropagateServiceTemplateWorker.perform_async(service.id) if service.active?
|
||||
|
||||
redirect_to admin_application_settings_services_path,
|
||||
|
|
|
@ -163,7 +163,7 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
format.json { head :ok }
|
||||
else
|
||||
format.html { redirect_back_or_admin_user(alert: 'There was an error removing the e-mail.') }
|
||||
format.json { render json: 'There was an error removing the e-mail.', status: 400 }
|
||||
format.json { render json: 'There was an error removing the e-mail.', status: :bad_request }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -127,7 +127,7 @@ module IssuableActions
|
|||
errors: [
|
||||
"Someone edited this #{issuable.human_class_name} at the same time you did. Please refresh your browser and make sure your changes will not unintentionally remove theirs."
|
||||
]
|
||||
}, status: 409
|
||||
}, status: :conflict
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,7 +27,7 @@ module LfsRequest
|
|||
message: 'Git LFS is not enabled on this GitLab server, contact your admin.',
|
||||
documentation_url: help_url
|
||||
},
|
||||
status: 501
|
||||
status: :not_implemented
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -7,6 +7,6 @@ class Groups::AvatarsController < Groups::ApplicationController
|
|||
@group.remove_avatar!
|
||||
@group.save
|
||||
|
||||
redirect_to edit_group_path(@group), status: 302
|
||||
redirect_to edit_group_path(@group), status: :found
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ class Groups::RunnersController < Groups::ApplicationController
|
|||
def destroy
|
||||
@runner.destroy
|
||||
|
||||
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: 302
|
||||
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: :found
|
||||
end
|
||||
|
||||
def resume
|
||||
|
|
|
@ -41,7 +41,7 @@ class JwtController < ApplicationController
|
|||
"You must use a personal access token with 'api' scope for Git over HTTP.\n" \
|
||||
"You can generate one at #{profile_personal_access_tokens_url}" }
|
||||
]
|
||||
}, status: 401
|
||||
}, status: :unauthorized
|
||||
end
|
||||
|
||||
def render_unauthorized
|
||||
|
@ -50,7 +50,7 @@ class JwtController < ApplicationController
|
|||
{ code: 'UNAUTHORIZED',
|
||||
message: 'HTTP Basic: Access denied' }
|
||||
]
|
||||
}, status: 401
|
||||
}, status: :unauthorized
|
||||
end
|
||||
|
||||
def auth_params
|
||||
|
|
|
@ -5,14 +5,14 @@ class NotificationSettingsController < ApplicationController
|
|||
return render_404 unless can_read?(resource)
|
||||
|
||||
@notification_setting = current_user.notification_settings_for(resource)
|
||||
@saved = @notification_setting.update_attributes(notification_setting_params)
|
||||
@saved = @notification_setting.update(notification_setting_params)
|
||||
|
||||
render_response
|
||||
end
|
||||
|
||||
def update
|
||||
@notification_setting = current_user.notification_settings.find(params[:id])
|
||||
@saved = @notification_setting.update_attributes(notification_setting_params)
|
||||
@saved = @notification_setting.update(notification_setting_params)
|
||||
|
||||
render_response
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ class Profiles::ActiveSessionsController < Profiles::ApplicationController
|
|||
ActiveSession.destroy(current_user, params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to profile_active_sessions_url, status: 302 }
|
||||
format.html { redirect_to profile_active_sessions_url, status: :found }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,6 @@ class Profiles::AvatarsController < Profiles::ApplicationController
|
|||
|
||||
Users::UpdateService.new(current_user, user: @user).execute { |user| user.remove_avatar! }
|
||||
|
||||
redirect_to profile_path, status: 302
|
||||
redirect_to profile_path, status: :found
|
||||
end
|
||||
end
|
||||
|
|
|
@ -39,7 +39,7 @@ class Profiles::ChatNamesController < Profiles::ApplicationController
|
|||
flash[:alert] = "Could not delete chat nickname #{@chat_name.chat_name}."
|
||||
end
|
||||
|
||||
redirect_to profile_chat_names_path, status: 302
|
||||
redirect_to profile_chat_names_path, status: :found
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -19,7 +19,7 @@ class Profiles::EmailsController < Profiles::ApplicationController
|
|||
Emails::DestroyService.new(current_user, user: current_user).execute(@email)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to profile_emails_url, status: 302 }
|
||||
format.html { redirect_to profile_emails_url, status: :found }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,7 +21,7 @@ class Profiles::GpgKeysController < Profiles::ApplicationController
|
|||
@gpg_key.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to profile_gpg_keys_url, status: 302 }
|
||||
format.html { redirect_to profile_gpg_keys_url, status: :found }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
@ -30,7 +30,7 @@ class Profiles::GpgKeysController < Profiles::ApplicationController
|
|||
@gpg_key.revoke
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to profile_gpg_keys_url, status: 302 }
|
||||
format.html { redirect_to profile_gpg_keys_url, status: :found }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ class Profiles::KeysController < Profiles::ApplicationController
|
|||
Keys::DestroyService.new(current_user).execute(@key)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to profile_keys_url, status: 302 }
|
||||
format.html { redirect_to profile_keys_url, status: :found }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -78,7 +78,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
|
|||
def destroy
|
||||
current_user.disable_two_factor!
|
||||
|
||||
redirect_to profile_account_path, status: 302
|
||||
redirect_to profile_account_path, status: :found
|
||||
end
|
||||
|
||||
def skip
|
||||
|
|
|
@ -61,7 +61,7 @@ class Projects::ApplicationController < ApplicationController
|
|||
def require_non_empty_project
|
||||
# Be sure to return status code 303 to avoid a double DELETE:
|
||||
# http://api.rubyonrails.org/classes/ActionController/Redirecting.html
|
||||
redirect_to project_path(@project), status: 303 if @project.empty_repo?
|
||||
redirect_to project_path(@project), status: :see_other if @project.empty_repo?
|
||||
end
|
||||
|
||||
def require_branch_head
|
||||
|
|
|
@ -21,6 +21,6 @@ class Projects::AvatarsController < Projects::ApplicationController
|
|||
|
||||
@project.save
|
||||
|
||||
redirect_to edit_project_path(@project), status: 302
|
||||
redirect_to edit_project_path(@project), status: :found
|
||||
end
|
||||
end
|
||||
|
|
|
@ -98,7 +98,7 @@ class Projects::BranchesController < Projects::ApplicationController
|
|||
flash_type = result[:status] == :error ? :alert : :notice
|
||||
flash[flash_type] = result[:message]
|
||||
|
||||
redirect_to project_branches_path(@project), status: 303
|
||||
redirect_to project_branches_path(@project), status: :see_other
|
||||
end
|
||||
|
||||
format.js { render nothing: true, status: result[:return_code] }
|
||||
|
|
|
@ -62,7 +62,7 @@ class Projects::ClustersController < Projects::ApplicationController
|
|||
def destroy
|
||||
if cluster.destroy
|
||||
flash[:notice] = _('Kubernetes cluster integration was successfully removed.')
|
||||
redirect_to project_clusters_path(project), status: 302
|
||||
redirect_to project_clusters_path(project), status: :found
|
||||
else
|
||||
flash[:notice] = _('Kubernetes cluster integration was not removed.')
|
||||
render :show
|
||||
|
|
|
@ -35,7 +35,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
if deploy_key.update_attributes(update_params)
|
||||
if deploy_key.update(update_params)
|
||||
flash[:notice] = 'Deploy key was successfully updated.'
|
||||
redirect_to_repository_settings(@project)
|
||||
else
|
||||
|
|
|
@ -2,7 +2,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
|||
layout 'project'
|
||||
before_action :authorize_read_environment!
|
||||
before_action :authorize_create_environment!, only: [:new, :create]
|
||||
before_action :authorize_create_deployment!, only: [:stop]
|
||||
before_action :authorize_stop_environment!, only: [:stop]
|
||||
before_action :authorize_update_environment!, only: [:edit, :update]
|
||||
before_action :authorize_admin_environment!, only: [:terminal, :terminal_websocket_authorize]
|
||||
before_action :environment, only: [:show, :edit, :update, :stop, :terminal, :terminal_websocket_authorize, :metrics]
|
||||
|
@ -116,7 +116,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
|||
set_workhorse_internal_api_content_type
|
||||
render json: Gitlab::Workhorse.terminal_websocket(terminal)
|
||||
else
|
||||
render text: 'Not found', status: 404
|
||||
render text: 'Not found', status: :not_found
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -175,4 +175,8 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
|||
def environment
|
||||
@environment ||= project.environments.find(params[:id])
|
||||
end
|
||||
|
||||
def authorize_stop_environment!
|
||||
access_denied! unless can?(current_user, :stop_environment, environment)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -53,7 +53,7 @@ class Projects::GitHttpClientController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
send_challenges
|
||||
render plain: "HTTP Basic: Access denied\n", status: 401
|
||||
render plain: "HTTP Basic: Access denied\n", status: :unauthorized
|
||||
rescue Gitlab::Auth::MissingPersonalAccessTokenError
|
||||
render_missing_personal_access_token
|
||||
end
|
||||
|
@ -83,7 +83,7 @@ class Projects::GitHttpClientController < Projects::ApplicationController
|
|||
render plain: "HTTP Basic: Access denied\n" \
|
||||
"You must use a personal access token with 'api' scope for Git over HTTP.\n" \
|
||||
"You can generate one at #{profile_personal_access_tokens_url}",
|
||||
status: 401
|
||||
status: :unauthorized
|
||||
end
|
||||
|
||||
def repository
|
||||
|
|
|
@ -24,7 +24,7 @@ class Projects::GroupLinksController < Projects::ApplicationController
|
|||
def update
|
||||
@group_link = @project.project_group_links.find(params[:id])
|
||||
|
||||
@group_link.update_attributes(group_link_params)
|
||||
@group_link.update(group_link_params)
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
@ -34,7 +34,7 @@ class Projects::GroupLinksController < Projects::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to project_project_members_path(project), status: 302
|
||||
redirect_to project_project_members_path(project), status: :found
|
||||
end
|
||||
format.js { head :ok }
|
||||
end
|
||||
|
|
|
@ -29,7 +29,7 @@ class Projects::HooksController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
if hook.update_attributes(hook_params)
|
||||
if hook.update(hook_params)
|
||||
flash[:notice] = 'Hook was successfully updated.'
|
||||
redirect_to project_settings_integrations_path(@project)
|
||||
else
|
||||
|
@ -48,7 +48,7 @@ class Projects::HooksController < Projects::ApplicationController
|
|||
def destroy
|
||||
hook.destroy
|
||||
|
||||
redirect_to project_settings_integrations_path(@project), status: 302
|
||||
redirect_to project_settings_integrations_path(@project), status: :found
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -39,7 +39,7 @@ class Projects::LabelsController < Projects::ApplicationController
|
|||
else
|
||||
respond_to do |format|
|
||||
format.html { render :new }
|
||||
format.json { render json: { message: @label.errors.messages }, status: 400 }
|
||||
format.json { render json: { message: @label.errors.messages }, status: :bad_request }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -115,7 +115,7 @@ class Projects::LabelsController < Projects::ApplicationController
|
|||
flash[:notice] = "#{@label.title} promoted to <a href=\"#{group_labels_path(@project.group)}\">group label</a>.".html_safe
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to(project_labels_path(@project), status: 303)
|
||||
redirect_to(project_labels_path(@project), status: :see_other)
|
||||
end
|
||||
format.json do
|
||||
render json: { url: project_labels_path(@project) }
|
||||
|
|
|
@ -25,7 +25,7 @@ class Projects::LfsApiController < Projects::GitHttpClientController
|
|||
message: 'Server supports batch API only, please update your Git LFS client to version 1.0.1 and up.',
|
||||
documentation_url: "#{Gitlab.config.gitlab.url}/help"
|
||||
},
|
||||
status: 501
|
||||
status: :not_implemented
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class Projects::LfsStorageController < Projects::GitHttpClientController
|
|||
if store_file!(oid, size)
|
||||
head 200
|
||||
else
|
||||
render plain: 'Unprocessable entity', status: 422
|
||||
render plain: 'Unprocessable entity', status: :unprocessable_entity
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
render_lfs_forbidden
|
||||
|
|
|
@ -192,7 +192,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
|||
deployment = environment.first_deployment_for(@merge_request.diff_head_sha)
|
||||
|
||||
stop_url =
|
||||
if environment.stop_action? && can?(current_user, :create_deployment, environment)
|
||||
if can?(current_user, :stop_environment, environment)
|
||||
stop_project_environment_path(project, environment)
|
||||
end
|
||||
|
||||
|
@ -227,7 +227,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
|||
def rebase
|
||||
RebaseWorker.perform_async(@merge_request.id, current_user.id)
|
||||
|
||||
render nothing: true, status: 200
|
||||
render nothing: true, status: :ok
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -96,7 +96,7 @@ class Projects::MilestonesController < Projects::ApplicationController
|
|||
Milestones::DestroyService.new(project, current_user).execute(milestone)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to namespace_project_milestones_path, status: 303 }
|
||||
format.html { redirect_to namespace_project_milestones_path, status: :see_other }
|
||||
format.js { head :ok }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ class Projects::MirrorsController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
if project.update_attributes(mirror_params)
|
||||
if project.update(mirror_params)
|
||||
flash[:notice] = 'Mirroring settings were successfully updated.'
|
||||
else
|
||||
flash[:alert] = project.errors.full_messages.join(', ').html_safe
|
||||
|
|
|
@ -64,7 +64,7 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
|
|||
|
||||
def destroy
|
||||
if schedule.destroy
|
||||
redirect_to pipeline_schedules_path(@project), status: 302
|
||||
redirect_to pipeline_schedules_path(@project), status: :found
|
||||
else
|
||||
redirect_to pipeline_schedules_path(@project),
|
||||
status: :forbidden,
|
||||
|
|
|
@ -14,7 +14,7 @@ class Projects::ReleasesController < Projects::ApplicationController
|
|||
# it exists only to save a description to each Tag.
|
||||
# If description is empty we should destroy the existing record.
|
||||
if release_params[:description].present?
|
||||
release.update_attributes(release_params)
|
||||
release.update(release_params)
|
||||
else
|
||||
release.destroy
|
||||
end
|
||||
|
|
|
@ -24,7 +24,7 @@ class Projects::RepositoriesController < Projects::ApplicationController
|
|||
send_git_archive @repository, ref: @ref, format: params[:format], append_sha: append_sha
|
||||
rescue => ex
|
||||
logger.error("#{self.class.name}: #{ex}")
|
||||
return git_not_found!
|
||||
git_not_found!
|
||||
end
|
||||
|
||||
def assign_archive_vars
|
||||
|
|
|
@ -21,6 +21,6 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
|
|||
runner_project = project.runner_projects.find(params[:id])
|
||||
runner_project.destroy
|
||||
|
||||
redirect_to project_runners_path(project), status: 302
|
||||
redirect_to project_runners_path(project), status: :found
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,7 +24,7 @@ class Projects::RunnersController < Projects::ApplicationController
|
|||
@runner.destroy
|
||||
end
|
||||
|
||||
redirect_to project_runners_path(@project), status: 302
|
||||
redirect_to project_runners_path(@project), status: :found
|
||||
end
|
||||
|
||||
def resume
|
||||
|
|
|
@ -34,7 +34,7 @@ class Projects::ServicesController < Projects::ApplicationController
|
|||
private
|
||||
|
||||
def service_test_response
|
||||
if @service.update_attributes(service_params[:service])
|
||||
if @service.update(service_params[:service])
|
||||
data = @service.test_data(project, current_user)
|
||||
outcome = @service.test(data)
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ class Projects::SnippetsController < Projects::ApplicationController
|
|||
|
||||
@snippet.destroy
|
||||
|
||||
redirect_to project_snippets_path(@project), status: 302
|
||||
redirect_to project_snippets_path(@project), status: :found
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -50,7 +50,7 @@ class Projects::TagsController < Projects::ApplicationController
|
|||
respond_to do |format|
|
||||
if result[:status] == :success
|
||||
format.html do
|
||||
redirect_to project_tags_path(@project), status: 303
|
||||
redirect_to project_tags_path(@project), status: :see_other
|
||||
end
|
||||
|
||||
format.js
|
||||
|
|
|
@ -14,6 +14,6 @@ class Projects::TemplatesController < Projects::ApplicationController
|
|||
def get_template_class
|
||||
template_types = { issue: Gitlab::Template::IssueTemplate, merge_request: Gitlab::Template::MergeRequestTemplate }.with_indifferent_access
|
||||
@template_type = template_types[params[:template_type]]
|
||||
render json: [], status: 404 unless @template_type
|
||||
render json: [], status: :not_found unless @template_type
|
||||
end
|
||||
end
|
||||
|
|
|
@ -50,7 +50,7 @@ class Projects::TriggersController < Projects::ApplicationController
|
|||
flash[:alert] = "Could not remove the trigger."
|
||||
end
|
||||
|
||||
redirect_to project_settings_ci_cd_path(@project), status: 302
|
||||
redirect_to project_settings_ci_cd_path(@project), status: :found
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -120,7 +120,7 @@ class Projects::WikisController < Projects::ApplicationController
|
|||
rescue ProjectWiki::CouldNotCreateWikiError
|
||||
flash[:notice] = "Could not create Wiki Repository at this time. Please try again later."
|
||||
redirect_to project_path(@project)
|
||||
return false
|
||||
false
|
||||
end
|
||||
|
||||
def wiki_params
|
||||
|
@ -129,7 +129,7 @@ class Projects::WikisController < Projects::ApplicationController
|
|||
|
||||
def build_page(args)
|
||||
WikiPage.new(@project_wiki).tap do |page|
|
||||
page.update_attributes(args)
|
||||
page.update_attributes(args) # rubocop:disable Rails/ActiveRecordAliases
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -133,7 +133,7 @@ class ProjectsController < Projects::ApplicationController
|
|||
::Projects::DestroyService.new(@project, current_user, {}).async_execute
|
||||
flash[:notice] = _("Project '%{project_name}' is in the process of being deleted.") % { project_name: @project.full_name }
|
||||
|
||||
redirect_to dashboard_projects_path, status: 302
|
||||
redirect_to dashboard_projects_path, status: :found
|
||||
rescue Projects::DestroyService::DestroyError => ex
|
||||
redirect_to edit_project_path(@project), status: 302, alert: ex.message
|
||||
end
|
||||
|
|
|
@ -32,8 +32,8 @@ class SessionsController < Devise::SessionsController
|
|||
super do |resource|
|
||||
# User has successfully signed in, so clear any unused reset token
|
||||
if resource.reset_password_token.present?
|
||||
resource.update_attributes(reset_password_token: nil,
|
||||
reset_password_sent_at: nil)
|
||||
resource.update(reset_password_token: nil,
|
||||
reset_password_sent_at: nil)
|
||||
end
|
||||
|
||||
# hide the signed-in notification
|
||||
|
|
|
@ -13,7 +13,7 @@ module Sherlock
|
|||
def destroy_all
|
||||
Gitlab::Sherlock.collection.clear
|
||||
|
||||
redirect_to :back, status: 302
|
||||
redirect_to :back, status: :found
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -89,7 +89,7 @@ class SnippetsController < ApplicationController
|
|||
|
||||
@snippet.destroy
|
||||
|
||||
redirect_to snippets_path, status: 302
|
||||
redirect_to snippets_path, status: :found
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -5,9 +5,13 @@ module TimeHelper
|
|||
seconds = interval_in_seconds - minutes * 60
|
||||
|
||||
if minutes >= 1
|
||||
"#{pluralize(minutes, "minute")} #{pluralize(seconds, "second")}"
|
||||
if seconds % 60 == 0
|
||||
pluralize(minutes, "minute")
|
||||
else
|
||||
[pluralize(minutes, "minute"), pluralize(seconds, "second")].to_sentence
|
||||
end
|
||||
else
|
||||
"#{pluralize(seconds, "second")}"
|
||||
pluralize(seconds, "second")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ module Ci
|
|||
|
||||
def update_coverage
|
||||
coverage = trace.extract_coverage(coverage_regex)
|
||||
update_attributes(coverage: coverage) if coverage.present?
|
||||
update(coverage: coverage) if coverage.present?
|
||||
end
|
||||
|
||||
def parse_trace_sections!
|
||||
|
@ -437,9 +437,9 @@ module Ci
|
|||
end
|
||||
|
||||
def artifacts_metadata_entry(path, **options)
|
||||
artifacts_metadata.use_file do |metadata_path|
|
||||
artifacts_metadata.open do |metadata_stream|
|
||||
metadata = Gitlab::Ci::Build::Artifacts::Metadata.new(
|
||||
metadata_path,
|
||||
metadata_stream,
|
||||
path,
|
||||
**options)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ module ProtectedRef
|
|||
# If we don't `protected_branch` or `protected_tag` would be empty and
|
||||
# `project` cannot be delegated to it, which in turn would cause validations
|
||||
# to fail.
|
||||
has_many :"#{type}_access_levels", inverse_of: self.model_name.singular # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :"#{type}_access_levels", inverse_of: self.model_name.singular
|
||||
|
||||
validates :"#{type}_access_levels", length: { is: 1, message: "are restricted to a single instance per #{self.model_name.human}." }
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ module Network
|
|||
@parent_spaces = []
|
||||
end
|
||||
|
||||
def method_missing(m, *args, &block)
|
||||
@commit.__send__(m, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
|
||||
def method_missing(msg, *args, &block)
|
||||
@commit.__send__(msg, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def space
|
||||
|
|
|
@ -107,7 +107,7 @@ class ProjectWiki
|
|||
update_project_activity
|
||||
rescue Gitlab::Git::Wiki::DuplicatePageError => e
|
||||
@error_message = "Duplicate page: #{e.message}"
|
||||
return false
|
||||
false
|
||||
end
|
||||
|
||||
def update_page(page, content:, title: nil, format: :markdown, message: nil)
|
||||
|
|
|
@ -57,7 +57,7 @@ class RemoteMirror < ActiveRecord::Base
|
|||
Gitlab::Metrics.add_event(:remote_mirrors_finished, path: remote_mirror.project.full_path)
|
||||
|
||||
timestamp = Time.now
|
||||
remote_mirror.update_attributes!(
|
||||
remote_mirror.update!(
|
||||
last_update_at: timestamp, last_successful_update_at: timestamp, last_error: nil
|
||||
)
|
||||
end
|
||||
|
|
|
@ -462,12 +462,12 @@ class Repository
|
|||
expire_branches_cache
|
||||
end
|
||||
|
||||
def method_missing(m, *args, &block)
|
||||
if m == :lookup && !block_given?
|
||||
lookup_cache[m] ||= {}
|
||||
lookup_cache[m][args.join(":")] ||= raw_repository.__send__(m, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
|
||||
def method_missing(msg, *args, &block)
|
||||
if msg == :lookup && !block_given?
|
||||
lookup_cache[msg] ||= {}
|
||||
lookup_cache[msg][args.join(":")] ||= raw_repository.__send__(msg, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
|
||||
else
|
||||
raw_repository.__send__(m, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
|
||||
raw_repository.__send__(msg, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -496,7 +496,7 @@ class User < ActiveRecord::Base
|
|||
|
||||
def disable_two_factor!
|
||||
transaction do
|
||||
update_attributes(
|
||||
update(
|
||||
otp_required_for_login: false,
|
||||
encrypted_otp_secret: nil,
|
||||
encrypted_otp_secret_iv: nil,
|
||||
|
@ -1053,7 +1053,7 @@ class User < ActiveRecord::Base
|
|||
return @global_notification_setting if defined?(@global_notification_setting)
|
||||
|
||||
@global_notification_setting = notification_settings.find_or_initialize_by(source: nil)
|
||||
@global_notification_setting.update_attributes(level: NotificationSetting.levels[DEFAULT_NOTIFICATION_LEVEL]) unless @global_notification_setting.persisted?
|
||||
@global_notification_setting.update(level: NotificationSetting.levels[DEFAULT_NOTIFICATION_LEVEL]) unless @global_notification_setting.persisted?
|
||||
|
||||
@global_notification_setting
|
||||
end
|
||||
|
@ -1333,8 +1333,8 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def self.unique_internal(scope, username, email_pattern, &b)
|
||||
scope.first || create_unique_internal(scope, username, email_pattern, &b)
|
||||
def self.unique_internal(scope, username, email_pattern, &block)
|
||||
scope.first || create_unique_internal(scope, username, email_pattern, &block)
|
||||
end
|
||||
|
||||
def self.create_unique_internal(scope, username, email_pattern, &creation_block)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# rubocop:disable Rails/ActiveRecordAliases
|
||||
class WikiPage
|
||||
PageChangedError = Class.new(StandardError)
|
||||
PageRenameError = Class.new(StandardError)
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
class EnvironmentPolicy < BasePolicy
|
||||
delegate { @subject.project }
|
||||
|
||||
condition(:stop_action_allowed) do
|
||||
@subject.stop_action? && can?(:update_build, @subject.stop_action)
|
||||
condition(:stop_with_deployment_allowed) do
|
||||
@subject.stop_action? && can?(:create_deployment) && can?(:update_build, @subject.stop_action)
|
||||
end
|
||||
|
||||
rule { can?(:create_deployment) & stop_action_allowed }.enable :stop_environment
|
||||
condition(:stop_with_update_allowed) do
|
||||
!@subject.stop_action? && can?(:update_environment, @subject)
|
||||
end
|
||||
|
||||
rule { stop_with_deployment_allowed | stop_with_update_allowed }.enable :stop_environment
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ class EnvironmentEntity < Grape::Entity
|
|||
expose :external_url
|
||||
expose :environment_type
|
||||
expose :last_deployment, using: DeploymentEntity
|
||||
expose :stop_action?
|
||||
expose :stop_action?, as: :has_stop_action
|
||||
|
||||
expose :metrics_path, if: -> (environment, _) { environment.has_metrics? } do |environment|
|
||||
metrics_project_environment_path(environment.project, environment)
|
||||
|
@ -31,4 +31,14 @@ class EnvironmentEntity < Grape::Entity
|
|||
end
|
||||
|
||||
expose :created_at, :updated_at
|
||||
|
||||
expose :can_stop do |environment|
|
||||
environment.available? && can?(current_user, :stop_environment, environment)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_user
|
||||
request.current_user
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ module Badges
|
|||
# returns the updated badge
|
||||
def execute(badge)
|
||||
if params.present?
|
||||
badge.update_attributes(params)
|
||||
badge.update(params)
|
||||
end
|
||||
|
||||
badge
|
||||
|
|
|
@ -13,8 +13,6 @@ module Commits
|
|||
|
||||
# rubocop:disable GitlabSecurity/PublicSend
|
||||
message = @commit.public_send(:"#{action}_message", current_user)
|
||||
|
||||
# rubocop:disable GitlabSecurity/PublicSend
|
||||
repository.public_send(
|
||||
action,
|
||||
current_user,
|
||||
|
|
|
@ -130,7 +130,7 @@ class IssuableBaseService < BaseService
|
|||
def create_issuable(issuable, attributes, label_ids:)
|
||||
issuable.with_transaction_returning_status do
|
||||
if issuable.save
|
||||
issuable.update_attributes(label_ids: label_ids)
|
||||
issuable.update(label_ids: label_ids)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ module Members
|
|||
|
||||
old_access_level = member.human_access
|
||||
|
||||
if member.update_attributes(params)
|
||||
if member.update(params)
|
||||
after_execute(action: permission, old_access_level: old_access_level, member: member)
|
||||
end
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ module MergeRequests
|
|||
|
||||
Gitlab::GitLogger.info("#{log_prefix} rebased to #{rebase_sha}")
|
||||
|
||||
merge_request.update_attributes(rebase_commit_sha: rebase_sha)
|
||||
merge_request.update(rebase_commit_sha: rebase_sha)
|
||||
|
||||
Gitlab::GitLogger.info("#{log_prefix} rebase SHA saved: #{rebase_sha}")
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ module Milestones
|
|||
end
|
||||
|
||||
if params.present?
|
||||
milestone.update_attributes(params.except(:state_event))
|
||||
milestone.update(params.except(:state_event))
|
||||
end
|
||||
|
||||
milestone
|
||||
|
|
|
@ -5,7 +5,7 @@ module Notes
|
|||
|
||||
old_mentioned_users = note.mentioned_users.to_a
|
||||
|
||||
note.update_attributes(params.merge(updated_by: current_user))
|
||||
note.update(params.merge(updated_by: current_user))
|
||||
note.create_new_cross_references!(current_user)
|
||||
|
||||
if note.previous_changes.include?('note')
|
||||
|
|
|
@ -10,16 +10,16 @@ module NotificationRecipientService
|
|||
NotificationRecipient.new(user, *args).notifiable?
|
||||
end
|
||||
|
||||
def self.build_recipients(*a)
|
||||
Builder::Default.new(*a).notification_recipients
|
||||
def self.build_recipients(*args)
|
||||
Builder::Default.new(*args).notification_recipients
|
||||
end
|
||||
|
||||
def self.build_new_note_recipients(*a)
|
||||
Builder::NewNote.new(*a).notification_recipients
|
||||
def self.build_new_note_recipients(*args)
|
||||
Builder::NewNote.new(*args).notification_recipients
|
||||
end
|
||||
|
||||
def self.build_merge_request_unmergeable_recipients(*a)
|
||||
Builder::MergeRequestUnmergeable.new(*a).notification_recipients
|
||||
def self.build_merge_request_unmergeable_recipients(*args)
|
||||
Builder::MergeRequestUnmergeable.new(*args).notification_recipients
|
||||
end
|
||||
|
||||
module Builder
|
||||
|
@ -44,7 +44,6 @@ module NotificationRecipientService
|
|||
raise 'abstract'
|
||||
end
|
||||
|
||||
# rubocop:disable Rails/Delegate
|
||||
def project
|
||||
target.project
|
||||
end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue