Merge branch 'master' into feature/sm/35954-create-kubernetes-cluster-on-gke-from-k8s-service
This commit is contained in:
commit
6d4e282958
|
@ -8,4 +8,4 @@
|
|||
karma.config.js
|
||||
webpack.config.js
|
||||
svg.config.js
|
||||
/app/assets/javascripts/locale/**/*.js
|
||||
/app/assets/javascripts/locale/**/app.js
|
||||
|
|
|
@ -404,6 +404,7 @@ docs lint:
|
|||
before_script: []
|
||||
script:
|
||||
- scripts/lint-doc.sh
|
||||
- scripts/lint-changelog-yaml
|
||||
- mv doc/ /nanoc/content/
|
||||
- cd /nanoc
|
||||
# Build HTML from Markdown
|
||||
|
|
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -2,6 +2,13 @@
|
|||
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||
entry.
|
||||
|
||||
## 10.0.2 (2017-09-27)
|
||||
|
||||
- [FIXED] Notes will not show an empty bubble when the author isn't a member. !14450
|
||||
- [FIXED] Some checks in `rake gitlab:check` were failling with 'undefined method `run_command`'. !14469
|
||||
- [FIXED] Make locked setting of Runner to not affect jobs scheduling. !14483
|
||||
- [FIXED] Re-allow `name` attribute on user-provided anchor HTML.
|
||||
|
||||
## 10.0.1 (2017-09-23)
|
||||
|
||||
- [FIXED] Fix duplicate key errors in PostDeployMigrateUserExternalMailData migration.
|
||||
|
@ -78,6 +85,8 @@ entry.
|
|||
- [FIXED] Fixed merge request changes bar jumping.
|
||||
- [FIXED] Improve migrations using triggers.
|
||||
- [FIXED] Fix ConvDev Index nav item and Monitoring submenu regression.
|
||||
- [FIXED] disabling notifications globally now properly turns off group/project added
|
||||
emails !13325
|
||||
- [DEPRECATED] Deprecate custom SSH client configuration for the git user. !13930
|
||||
- [CHANGED] allow all users to delete their account. !13636 (Jacopo Beschi @jacopo-beschi)
|
||||
- [CHANGED] Use full path of project's avatar in webhooks. !13649 (Vitaliy @blackst0ne Klachkov)
|
||||
|
@ -186,6 +195,13 @@ entry.
|
|||
- Added type to CHANGELOG entries. (Jacopo Beschi @jacopo-beschi)
|
||||
- [BUGIFX] Improves subgroup creation permissions. !13418
|
||||
|
||||
## 9.5.6 (2017-09-29)
|
||||
|
||||
- [FIXED] Fix MR ready to merge buttons/controls at mobile breakpoint. !14242
|
||||
- [FIXED] Fix errors thrown in merge request widget with external CI service/integration.
|
||||
- [FIXED] Update x/x discussions resolved checkmark icon to be green when all discussions resolved.
|
||||
- [FIXED] Fix 500 error on merged merge requests when GitLab is restored from a backup.
|
||||
|
||||
## 9.5.5 (2017-09-18)
|
||||
|
||||
- [SECURITY] Upgrade mail and nokogiri gems due to security issues. !13662 (Markus Koller)
|
||||
|
|
|
@ -49,7 +49,7 @@ _This notice should stay as the first item in the CONTRIBUTING.md file._
|
|||
Thank you for your interest in contributing to GitLab. This guide details how
|
||||
to contribute to GitLab in a way that is efficient for everyone.
|
||||
|
||||
Looking for something to work on? Look for the label [Accepting Merge Requests](#i-want-to-contribute).
|
||||
Looking for something to work on? Look for issues with the label [Accepting Merge Requests](#i-want-to-contribute).
|
||||
|
||||
GitLab comes into two flavors, GitLab Community Edition (CE) our free and open
|
||||
source edition, and GitLab Enterprise Edition (EE) which is our commercial
|
||||
|
@ -101,7 +101,7 @@ the remaining issues on the GitHub issue tracker.
|
|||
## I want to contribute!
|
||||
|
||||
If you want to contribute to GitLab, but are not sure where to start,
|
||||
look for [issues with the label `Accepting Merge Requests` and weight < 5][accepting-mrs-weight].
|
||||
look for [issues with the label `Accepting Merge Requests` and small weight][accepting-mrs-weight].
|
||||
These issues will be of reasonable size and challenge, for anyone to start
|
||||
contributing to GitLab.
|
||||
|
||||
|
@ -209,8 +209,7 @@ We add the ~"Accepting Merge Requests" label to:
|
|||
|
||||
- Low priority ~bug issues (i.e. we do not add it to the bugs that we want to
|
||||
solve in the ~"Next Patch Release")
|
||||
- Small ~"feature proposal" that do not need ~UX / ~"Product work", or for which
|
||||
the ~UX / ~"Product work" is already done
|
||||
- Small ~"feature proposal"
|
||||
- Small ~"technical debt" issues
|
||||
|
||||
After adding the ~"Accepting Merge Requests" label, we try to estimate the
|
||||
|
@ -223,6 +222,17 @@ know how difficult the issue is. Additionally:
|
|||
- We encourage people that have never contributed to any open source project to
|
||||
look for ["Accepting Merge Requests" issues with a weight of 1][firt-timers]
|
||||
|
||||
If you've decided that you would like to work on an issue, please @-mention
|
||||
the [appropriate product manager](https://about.gitlab.com/handbook/product/#who-to-talk-to-for-what)
|
||||
as soon as possible. The product manager will then pull in appropriate GitLab team
|
||||
members to further discuss scope, design, and technical considerations. This will
|
||||
ensure that that your contribution is aligned with the GitLab product and minimize
|
||||
any rework and delay in getting it merged into master.
|
||||
|
||||
GitLab team members who apply the ~"Accepting Merge Requests" label to an issue
|
||||
should update the issue description with a responsible product manager, inviting
|
||||
any potential community contributor to @-mention per above.
|
||||
|
||||
[up-for-grabs]: https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name=Accepting+Merge+Requests&scope=all&sort=weight_asc&state=opened
|
||||
[firt-timers]: https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=Accepting+Merge+Requests&scope=all&sort=upvotes_desc&state=opened&weight=1
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.40.0
|
||||
0.43.0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
5.9.0
|
||||
5.9.3
|
||||
|
||||
|
|
4
Gemfile
4
Gemfile
|
@ -26,7 +26,7 @@ gem 'doorkeeper', '~> 4.2.0'
|
|||
gem 'doorkeeper-openid_connect', '~> 1.1.0'
|
||||
gem 'omniauth', '~> 1.4.2'
|
||||
gem 'omniauth-auth0', '~> 1.4.1'
|
||||
gem 'omniauth-azure-oauth2', '~> 0.0.6'
|
||||
gem 'omniauth-azure-oauth2', '~> 0.0.9'
|
||||
gem 'omniauth-cas3', '~> 1.1.4'
|
||||
gem 'omniauth-facebook', '~> 4.0.0'
|
||||
gem 'omniauth-github', '~> 1.1.1'
|
||||
|
@ -398,7 +398,7 @@ group :ed25519 do
|
|||
end
|
||||
|
||||
# Gitaly GRPC client
|
||||
gem 'gitaly-proto', '~> 0.33.0', require: 'gitaly'
|
||||
gem 'gitaly-proto', '~> 0.38.0', require: 'gitaly'
|
||||
|
||||
gem 'toml-rb', '~> 0.3.15', require: false
|
||||
|
||||
|
|
12
Gemfile.lock
12
Gemfile.lock
|
@ -273,7 +273,7 @@ GEM
|
|||
po_to_json (>= 1.0.0)
|
||||
rails (>= 3.2.0)
|
||||
gherkin-ruby (0.3.2)
|
||||
gitaly-proto (0.33.0)
|
||||
gitaly-proto (0.38.0)
|
||||
google-protobuf (~> 3.1)
|
||||
grpc (~> 1.0)
|
||||
github-linguist (4.7.6)
|
||||
|
@ -512,10 +512,10 @@ GEM
|
|||
omniauth-oauth2 (~> 1.1)
|
||||
omniauth-authentiq (0.3.1)
|
||||
omniauth-oauth2 (~> 1.3, >= 1.3.1)
|
||||
omniauth-azure-oauth2 (0.0.6)
|
||||
omniauth-azure-oauth2 (0.0.9)
|
||||
jwt (~> 1.0)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-oauth2 (~> 1.1)
|
||||
omniauth-oauth2 (~> 1.4)
|
||||
omniauth-cas3 (1.1.4)
|
||||
addressable (~> 2.3)
|
||||
nokogiri (~> 1.7, >= 1.7.1)
|
||||
|
@ -541,7 +541,7 @@ GEM
|
|||
omniauth-oauth (1.1.0)
|
||||
oauth
|
||||
omniauth (~> 1.0)
|
||||
omniauth-oauth2 (1.3.1)
|
||||
omniauth-oauth2 (1.4.0)
|
||||
oauth2 (~> 1.0)
|
||||
omniauth (~> 1.2)
|
||||
omniauth-oauth2-generic (0.2.2)
|
||||
|
@ -1027,7 +1027,7 @@ DEPENDENCIES
|
|||
gettext (~> 3.2.2)
|
||||
gettext_i18n_rails (~> 1.8.0)
|
||||
gettext_i18n_rails_js (~> 1.2.0)
|
||||
gitaly-proto (~> 0.33.0)
|
||||
gitaly-proto (~> 0.38.0)
|
||||
github-linguist (~> 4.7.0)
|
||||
gitlab-flowdock-git-hook (~> 1.0.1)
|
||||
gitlab-markup (~> 1.6.2)
|
||||
|
@ -1077,7 +1077,7 @@ DEPENDENCIES
|
|||
omniauth (~> 1.4.2)
|
||||
omniauth-auth0 (~> 1.4.1)
|
||||
omniauth-authentiq (~> 0.3.1)
|
||||
omniauth-azure-oauth2 (~> 0.0.6)
|
||||
omniauth-azure-oauth2 (~> 0.0.9)
|
||||
omniauth-cas3 (~> 1.1.4)
|
||||
omniauth-facebook (~> 4.0.0)
|
||||
omniauth-github (~> 1.1.1)
|
||||
|
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
@ -1 +1 @@
|
|||
{"iconCount":134,"icons":["abuse","account","admin","angle-double-left","angle-down","angle-left","angle-right","angle-up","appearance","applications","approval","arrow-right","assignee","bold","book","branch","calendar","cancel","chevron-down","chevron-left","chevron-right","chevron-up","clock","code","comment-dots","comment-next","comment","comments","commit","credit-card","disk","doc_code","doc_image","doc_text","download","duplicate","earth","eye-slash","eye","file-additions","file-deletion","file-modified","filter","folder","fork","geo-nodes","git-merge","group","history","home","hook","issue-block","issue-child","issue-close","issue-duplicate","issue-new","issue-open-m","issue-open","issue-parent","issues","key-2","key","label","labels","leave","level-up","license","link","list-bulleted","list-numbered","location-dot","location","lock-open","lock","log","mail","merge-request-close-m","merge-request-close","messages","mobile-issue-close","monitor","more","notifications-off","notifications","overview","pencil","pipeline","play","plus-square-o","plus-square","plus","preferences","profile","project","push-rules","question-o","question","quote","redo","remove","repeat","retry","scale","screen-full","screen-normal","search","settings","shield","slight-frown","slight-smile","smile","smiley","snippet","spam","star-o","star","stop","talic","task-done","template","thump-down","thump-up","timer","todo-add","todo-done","token","unapproval","unassignee","unlink","user","users","volume-up","warning","work"]}
|
||||
{"iconCount":135,"spriteSize":58718,"icons":["abuse","account","admin","angle-double-left","angle-double-right","angle-down","angle-left","angle-right","angle-up","appearance","applications","approval","arrow-right","assignee","bold","book","branch","calendar","cancel","chevron-down","chevron-left","chevron-right","chevron-up","clock","close","code","comment-dots","comment-next","comment","comments","commit","credit-card","disk","doc_code","doc_image","doc_text","download","duplicate","earth","eye-slash","eye","file-additions","file-deletion","file-modified","filter","folder","fork","geo-nodes","git-merge","group","history","home","hook","issue-block","issue-child","issue-close","issue-duplicate","issue-new","issue-open-m","issue-open","issue-parent","issues","key-2","key","label","labels","leave","level-up","license","link","list-bulleted","list-numbered","location-dot","location","lock-open","lock","log","mail","merge-request-close","messages","mobile-issue-close","monitor","more","notifications-off","notifications","overview","pencil","pipeline","play","plus-square-o","plus-square","plus","preferences","profile","project","push-rules","question-o","question","quote","redo","remove","repeat","retry","scale","screen-full","screen-normal","search","settings","shield","slight-frown","slight-smile","smile","smiley","snippet","spam","star-o","star","stop","talic","task-done","template","thump-down","thump-up","timer","todo-add","todo-done","token","unapproval","unassignee","unlink","user","users","volume-up","warning","work"]}
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -40,10 +40,10 @@ export default () => {
|
|||
class="text-center"
|
||||
v-if="error">
|
||||
<span v-if="loadError">
|
||||
An error occured whilst loading the file. Please try again later.
|
||||
An error occurred whilst loading the file. Please try again later.
|
||||
</span>
|
||||
<span v-else>
|
||||
An error occured whilst parsing the file.
|
||||
An error occurred whilst parsing the file.
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -48,10 +48,10 @@ export default () => {
|
|||
class="text-center"
|
||||
v-if="error">
|
||||
<span v-if="loadError">
|
||||
An error occured whilst loading the file. Please try again later.
|
||||
An error occurred whilst loading the file. Please try again later.
|
||||
</span>
|
||||
<span v-else>
|
||||
An error occured whilst decoding the file.
|
||||
An error occurred whilst decoding the file.
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -77,9 +77,6 @@ $(() => {
|
|||
});
|
||||
Store.rootPath = this.boardsEndpoint;
|
||||
|
||||
this.filterManager = new FilteredSearchBoards(Store.filter, true);
|
||||
this.filterManager.setup();
|
||||
|
||||
// Listen for updateTokens event
|
||||
eventHub.$on('updateTokens', this.updateTokens);
|
||||
},
|
||||
|
@ -87,6 +84,9 @@ $(() => {
|
|||
eventHub.$off('updateTokens', this.updateTokens);
|
||||
},
|
||||
mounted () {
|
||||
this.filterManager = new FilteredSearchBoards(Store.filter, true);
|
||||
this.filterManager.setup();
|
||||
|
||||
Store.disabled = this.disabled;
|
||||
gl.boardService.all()
|
||||
.then(response => response.json())
|
||||
|
|
|
@ -68,7 +68,7 @@ export default {
|
|||
<div class="flash-container"
|
||||
v-if="error">
|
||||
<div class="flash-alert">
|
||||
An error occured. Please try again.
|
||||
An error occurred. Please try again.
|
||||
</div>
|
||||
</div>
|
||||
<label class="label-light"
|
||||
|
|
|
@ -167,7 +167,7 @@ window.Build = (function () {
|
|||
Build.prototype.getBuildTrace = function () {
|
||||
return $.ajax({
|
||||
url: `${this.pageUrl}/trace.json`,
|
||||
data: this.state,
|
||||
data: { state: this.state },
|
||||
})
|
||||
.done((log) => {
|
||||
setCiStatusFavicon(`${this.pageUrl}/status.json`);
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
export default {
|
||||
props: {
|
||||
count: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<span v-if="count === 50" class="events-info pull-right">
|
||||
<i class="fa fa-warning has-tooltip"
|
||||
aria-hidden="true"
|
||||
:title="n__('Limited to showing %d event at most', 'Limited to showing %d events at most', 50)"
|
||||
data-placement="top"></i>
|
||||
{{ n__('Showing %d event', 'Showing %d events', 50) }}
|
||||
</span>
|
||||
`,
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
<script>
|
||||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
count: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<span v-if="count === 50" class="events-info pull-right">
|
||||
<i
|
||||
class="fa fa-warning"
|
||||
v-tooltip
|
||||
aria-hidden="true"
|
||||
:title="n__('Limited to showing %d event at most', 'Limited to showing %d events at most', 50)"
|
||||
data-placement="top"></i>
|
||||
{{ n__('Showing %d event', 'Showing %d events', 50) }}
|
||||
</span>
|
||||
</template>
|
|
@ -1,51 +0,0 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
|
||||
import Vue from 'vue';
|
||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
|
||||
const global = window.gl || (window.gl = {});
|
||||
global.cycleAnalytics = global.cycleAnalytics || {};
|
||||
|
||||
global.cycleAnalytics.StageCodeComponent = Vue.extend({
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
components: {
|
||||
userAvatarImage,
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li v-for="mergeRequest in items" class="stage-event-item">
|
||||
<div class="item-details">
|
||||
<!-- FIXME: Pass an alt attribute here for accessibility -->
|
||||
<user-avatar-image :img-src="mergeRequest.author.avatarUrl"/>
|
||||
<h5 class="item-title merge-merquest-title">
|
||||
<a :href="mergeRequest.url">
|
||||
{{ mergeRequest.title }}
|
||||
</a>
|
||||
</h5>
|
||||
<a :href="mergeRequest.url" class="issue-link">!{{ mergeRequest.iid }}</a>
|
||||
·
|
||||
<span>
|
||||
{{ s__('OpenedNDaysAgo|Opened') }}
|
||||
<a :href="mergeRequest.url" class="issue-date">{{ mergeRequest.createdAt }}</a>
|
||||
</span>
|
||||
<span>
|
||||
{{ s__('ByAuthor|by') }}
|
||||
<a :href="mergeRequest.author.webUrl" class="issue-author-link">{{ mergeRequest.author.name }}</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="mergeRequest.totalTime"></total-time>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
});
|
|
@ -0,0 +1,51 @@
|
|||
<script>
|
||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
import limitWarning from './limit_warning_component.vue';
|
||||
import totalTime from './total_time_component.vue';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
components: {
|
||||
userAvatarImage,
|
||||
limitWarning,
|
||||
totalTime,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li v-for="mergeRequest in items" class="stage-event-item">
|
||||
<div class="item-details">
|
||||
<!-- FIXME: Pass an alt attribute here for accessibility -->
|
||||
<user-avatar-image :img-src="mergeRequest.author.avatarUrl"/>
|
||||
<h5 class="item-title merge-merquest-title">
|
||||
<a :href="mergeRequest.url">
|
||||
{{ mergeRequest.title }}
|
||||
</a>
|
||||
</h5>
|
||||
<a :href="mergeRequest.url" class="issue-link">!{{ mergeRequest.iid }}</a>
|
||||
·
|
||||
<span>
|
||||
{{ s__('OpenedNDaysAgo|Opened') }}
|
||||
<a :href="mergeRequest.url" class="issue-date">{{ mergeRequest.createdAt }}</a>
|
||||
</span>
|
||||
<span>
|
||||
{{ s__('ByAuthor|by') }}
|
||||
<a :href="mergeRequest.author.webUrl" class="issue-author-link">{{ mergeRequest.author.name }}</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="mergeRequest.totalTime"></total-time>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,57 @@
|
|||
<script>
|
||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
import limitWarning from './limit_warning_component.vue';
|
||||
import totalTime from './total_time_component.vue';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
components: {
|
||||
userAvatarImage,
|
||||
limitWarning,
|
||||
totalTime,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li
|
||||
v-for="(issue, i) in items"
|
||||
:key="i"
|
||||
class="stage-event-item">
|
||||
<div class="item-details">
|
||||
<!-- FIXME: Pass an alt attribute here for accessibility -->
|
||||
<user-avatar-image :img-src="issue.author.avatarUrl"/>
|
||||
<h5 class="item-title issue-title">
|
||||
<a class="issue-title" :href="issue.url">
|
||||
{{ issue.title }}
|
||||
</a>
|
||||
</h5>
|
||||
<a :href="issue.url" class="issue-link">#{{ issue.iid }}</a>
|
||||
·
|
||||
<span>
|
||||
{{ s__('OpenedNDaysAgo|Opened') }}
|
||||
<a :href="issue.url" class="issue-date">{{ issue.createdAt }}</a>
|
||||
</span>
|
||||
<span>
|
||||
{{ s__('ByAuthor|by') }}
|
||||
<a :href="issue.author.webUrl" class="issue-author-link">
|
||||
{{ issue.author.name }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="issue.totalTime"/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
import Vue from 'vue';
|
||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
|
||||
const global = window.gl || (window.gl = {});
|
||||
global.cycleAnalytics = global.cycleAnalytics || {};
|
||||
|
||||
global.cycleAnalytics.StageIssueComponent = Vue.extend({
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
components: {
|
||||
userAvatarImage,
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li v-for="issue in items" class="stage-event-item">
|
||||
<div class="item-details">
|
||||
<!-- FIXME: Pass an alt attribute here for accessibility -->
|
||||
<user-avatar-image :img-src="issue.author.avatarUrl"/>
|
||||
<h5 class="item-title issue-title">
|
||||
<a class="issue-title" :href="issue.url">
|
||||
{{ issue.title }}
|
||||
</a>
|
||||
</h5>
|
||||
<a :href="issue.url" class="issue-link">#{{ issue.iid }}</a>
|
||||
·
|
||||
<span>
|
||||
{{ s__('OpenedNDaysAgo|Opened') }}
|
||||
<a :href="issue.url" class="issue-date">{{ issue.createdAt }}</a>
|
||||
</span>
|
||||
<span>
|
||||
{{ s__('ByAuthor|by') }}
|
||||
<a :href="issue.author.webUrl" class="issue-author-link">
|
||||
{{ issue.author.name }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="issue.totalTime"></total-time>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
});
|
|
@ -1,53 +0,0 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
import Vue from 'vue';
|
||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
import iconCommit from '../svg/icon_commit.svg';
|
||||
|
||||
const global = window.gl || (window.gl = {});
|
||||
global.cycleAnalytics = global.cycleAnalytics || {};
|
||||
|
||||
global.cycleAnalytics.StagePlanComponent = Vue.extend({
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
components: {
|
||||
userAvatarImage,
|
||||
},
|
||||
data() {
|
||||
return { iconCommit };
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li v-for="commit in items" class="stage-event-item">
|
||||
<div class="item-details item-conmmit-component">
|
||||
<!-- FIXME: Pass an alt attribute here for accessibility -->
|
||||
<user-avatar-image :img-src="commit.author.avatarUrl"/>
|
||||
<h5 class="item-title commit-title">
|
||||
<a :href="commit.commitUrl">
|
||||
{{ commit.title }}
|
||||
</a>
|
||||
</h5>
|
||||
<span>
|
||||
{{ s__('FirstPushedBy|First') }}
|
||||
<span class="commit-icon">${iconCommit}</span>
|
||||
<a :href="commit.commitUrl" class="commit-hash-link commit-sha">{{ commit.shortSha }}</a>
|
||||
{{ s__('FirstPushedBy|pushed by') }}
|
||||
<a :href="commit.author.webUrl" class="commit-author-link">
|
||||
{{ commit.author.name }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="commit.totalTime"></total-time>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
});
|
|
@ -0,0 +1,60 @@
|
|||
<script>
|
||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
import iconCommit from '../svg/icon_commit.svg';
|
||||
import limitWarning from './limit_warning_component.vue';
|
||||
import totalTime from './total_time_component.vue';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
components: {
|
||||
userAvatarImage,
|
||||
totalTime,
|
||||
limitWarning,
|
||||
},
|
||||
computed: {
|
||||
iconCommit() {
|
||||
return iconCommit;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li
|
||||
v-for="(commit, i) in items"
|
||||
:key="i"
|
||||
class="stage-event-item">
|
||||
<div class="item-details item-conmmit-component">
|
||||
<!-- FIXME: Pass an alt attribute here for accessibility -->
|
||||
<user-avatar-image :img-src="commit.author.avatarUrl"/>
|
||||
<h5 class="item-title commit-title">
|
||||
<a :href="commit.commitUrl">
|
||||
{{ commit.title }}
|
||||
</a>
|
||||
</h5>
|
||||
<span>
|
||||
{{ s__('FirstPushedBy|First') }}
|
||||
<span class="commit-icon" v-html="iconCommit"></span>
|
||||
<a :href="commit.commitUrl" class="commit-hash-link commit-sha">{{ commit.shortSha }}</a>
|
||||
{{ s__('FirstPushedBy|pushed by') }}
|
||||
<a :href="commit.author.webUrl" class="commit-author-link">
|
||||
{{ commit.author.name }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="commit.totalTime" />
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
import Vue from 'vue';
|
||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
|
||||
const global = window.gl || (window.gl = {});
|
||||
global.cycleAnalytics = global.cycleAnalytics || {};
|
||||
|
||||
global.cycleAnalytics.StageProductionComponent = Vue.extend({
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
components: {
|
||||
userAvatarImage,
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li v-for="issue in items" class="stage-event-item">
|
||||
<div class="item-details">
|
||||
<!-- FIXME: Pass an alt attribute here for accessibility -->
|
||||
<user-avatar-image :img-src="issue.author.avatarUrl"/>
|
||||
<h5 class="item-title issue-title">
|
||||
<a class="issue-title" :href="issue.url">
|
||||
{{ issue.title }}
|
||||
</a>
|
||||
</h5>
|
||||
<a :href="issue.url" class="issue-link">#{{ issue.iid }}</a>
|
||||
·
|
||||
<span>
|
||||
{{ s__('OpenedNDaysAgo|Opened') }}
|
||||
<a :href="issue.url" class="issue-date">{{ issue.createdAt }}</a>
|
||||
</span>
|
||||
<span>
|
||||
{{ s__('ByAuthor|by') }}
|
||||
<a :href="issue.author.webUrl" class="issue-author-link">
|
||||
{{ issue.author.name }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="issue.totalTime"></total-time>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
});
|
|
@ -1,62 +0,0 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
import Vue from 'vue';
|
||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
|
||||
const global = window.gl || (window.gl = {});
|
||||
global.cycleAnalytics = global.cycleAnalytics || {};
|
||||
|
||||
global.cycleAnalytics.StageReviewComponent = Vue.extend({
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
components: {
|
||||
userAvatarImage,
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li v-for="mergeRequest in items" class="stage-event-item">
|
||||
<div class="item-details">
|
||||
<!-- FIXME: Pass an alt attribute here for accessibility -->
|
||||
<user-avatar-image :img-src="mergeRequest.author.avatarUrl"/>
|
||||
<h5 class="item-title merge-merquest-title">
|
||||
<a :href="mergeRequest.url">
|
||||
{{ mergeRequest.title }}
|
||||
</a>
|
||||
</h5>
|
||||
<a :href="mergeRequest.url" class="issue-link">!{{ mergeRequest.iid }}</a>
|
||||
·
|
||||
<span>
|
||||
{{ s__('OpenedNDaysAgo|Opened') }}
|
||||
<a :href="mergeRequest.url" class="issue-date">{{ mergeRequest.createdAt }}</a>
|
||||
</span>
|
||||
<span>
|
||||
{{ s__('ByAuthor|by') }}
|
||||
<a :href="mergeRequest.author.webUrl" class="issue-author-link">{{ mergeRequest.author.name }}</a>
|
||||
</span>
|
||||
<template v-if="mergeRequest.state === 'closed'">
|
||||
<span class="merge-request-state">
|
||||
<i class="fa fa-ban"></i>
|
||||
{{ mergeRequest.state.toUpperCase() }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="merge-request-branch" v-if="mergeRequest.branch">
|
||||
<i class= "fa fa-code-fork"></i>
|
||||
<a :href="mergeRequest.branch.url">{{ mergeRequest.branch.name }}</a>
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="mergeRequest.totalTime"></total-time>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
});
|
|
@ -0,0 +1,66 @@
|
|||
<script>
|
||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
import limitWarning from './limit_warning_component.vue';
|
||||
import totalTime from './total_time_component.vue';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
components: {
|
||||
userAvatarImage,
|
||||
totalTime,
|
||||
limitWarning,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li
|
||||
v-for="(mergeRequest, i) in items"
|
||||
:key="i"
|
||||
class="stage-event-item">
|
||||
<div class="item-details">
|
||||
<!-- FIXME: Pass an alt attribute here for accessibility -->
|
||||
<user-avatar-image :img-src="mergeRequest.author.avatarUrl"/>
|
||||
<h5 class="item-title merge-merquest-title">
|
||||
<a :href="mergeRequest.url">
|
||||
{{ mergeRequest.title }}
|
||||
</a>
|
||||
</h5>
|
||||
<a :href="mergeRequest.url" class="issue-link">!{{ mergeRequest.iid }}</a>
|
||||
·
|
||||
<span>
|
||||
{{ s__('OpenedNDaysAgo|Opened') }}
|
||||
<a :href="mergeRequest.url" class="issue-date">{{ mergeRequest.createdAt }}</a>
|
||||
</span>
|
||||
<span>
|
||||
{{ s__('ByAuthor|by') }}
|
||||
<a :href="mergeRequest.author.webUrl" class="issue-author-link">{{ mergeRequest.author.name }}</a>
|
||||
</span>
|
||||
<template v-if="mergeRequest.state === 'closed'">
|
||||
<span class="merge-request-state">
|
||||
<i class="fa fa-ban"></i>
|
||||
{{ mergeRequest.state.toUpperCase() }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="merge-request-branch" v-if="mergeRequest.branch">
|
||||
<i class= "fa fa-code-fork"></i>
|
||||
<a :href="mergeRequest.branch.url">{{ mergeRequest.branch.name }}</a>
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="mergeRequest.totalTime"/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
|
@ -1,53 +0,0 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
import Vue from 'vue';
|
||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
import iconBranch from '../svg/icon_branch.svg';
|
||||
|
||||
const global = window.gl || (window.gl = {});
|
||||
global.cycleAnalytics = global.cycleAnalytics || {};
|
||||
|
||||
global.cycleAnalytics.StageStagingComponent = Vue.extend({
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
data() {
|
||||
return { iconBranch };
|
||||
},
|
||||
components: {
|
||||
userAvatarImage,
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li v-for="build in items" class="stage-event-item item-build-component">
|
||||
<div class="item-details">
|
||||
<!-- FIXME: Pass an alt attribute here for accessibility -->
|
||||
<user-avatar-image :img-src="build.author.avatarUrl"/>
|
||||
<h5 class="item-title">
|
||||
<a :href="build.url" class="pipeline-id">#{{ build.id }}</a>
|
||||
<i class="fa fa-code-fork"></i>
|
||||
<a :href="build.branch.url" class="ref-name">{{ build.branch.name }}</a>
|
||||
<span class="icon-branch">${iconBranch}</span>
|
||||
<a :href="build.commitUrl" class="commit-sha">{{ build.shortSha }}</a>
|
||||
</h5>
|
||||
<span>
|
||||
<a :href="build.url" class="build-date">{{ build.date }}</a>
|
||||
{{ s__('ByAuthor|by') }}
|
||||
<a :href="build.author.webUrl" class="issue-author-link">
|
||||
{{ build.author.name }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="build.totalTime"></total-time>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
});
|
|
@ -0,0 +1,59 @@
|
|||
<script>
|
||||
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
import iconBranch from '../svg/icon_branch.svg';
|
||||
import limitWarning from './limit_warning_component.vue';
|
||||
import totalTime from './total_time_component.vue';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
components: {
|
||||
userAvatarImage,
|
||||
totalTime,
|
||||
limitWarning,
|
||||
},
|
||||
computed: {
|
||||
iconBranch() {
|
||||
return iconBranch;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li
|
||||
v-for="(build, i) in items"
|
||||
class="stage-event-item item-build-component"
|
||||
:key="i">
|
||||
<div class="item-details">
|
||||
<!-- FIXME: Pass an alt attribute here for accessibility -->
|
||||
<user-avatar-image :img-src="build.author.avatarUrl"/>
|
||||
<h5 class="item-title">
|
||||
<a :href="build.url" class="pipeline-id">#{{ build.id }}</a>
|
||||
<i class="fa fa-code-fork"></i>
|
||||
<a :href="build.branch.url" class="ref-name">{{ build.branch.name }}</a>
|
||||
<span class="icon-branch" v-html="iconBranch"></span>
|
||||
<a :href="build.commitUrl" class="commit-sha">{{ build.shortSha }}</a>
|
||||
</h5>
|
||||
<span>
|
||||
<a :href="build.url" class="build-date">{{ build.date }}</a>
|
||||
{{ s__('ByAuthor|by') }}
|
||||
<a :href="build.author.webUrl" class="issue-author-link">
|
||||
{{ build.author.name }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="build.totalTime"/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
|
@ -1,49 +0,0 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
import Vue from 'vue';
|
||||
import iconBuildStatus from '../svg/icon_build_status.svg';
|
||||
import iconBranch from '../svg/icon_branch.svg';
|
||||
|
||||
const global = window.gl || (window.gl = {});
|
||||
global.cycleAnalytics = global.cycleAnalytics || {};
|
||||
|
||||
global.cycleAnalytics.StageTestComponent = Vue.extend({
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
data() {
|
||||
return { iconBuildStatus, iconBranch };
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li v-for="build in items" class="stage-event-item item-build-component">
|
||||
<div class="item-details">
|
||||
<h5 class="item-title">
|
||||
<span class="icon-build-status">${iconBuildStatus}</span>
|
||||
<a :href="build.url" class="item-build-name">{{ build.name }}</a>
|
||||
·
|
||||
<a :href="build.url" class="pipeline-id">#{{ build.id }}</a>
|
||||
<i class="fa fa-code-fork"></i>
|
||||
<a :href="build.branch.url" class="ref-name">{{ build.branch.name }}</a>
|
||||
<span class="icon-branch">${iconBranch}</span>
|
||||
<a :href="build.commitUrl" class="commit-sha">{{ build.shortSha }}</a>
|
||||
</h5>
|
||||
<span>
|
||||
<a :href="build.url" class="issue-date">
|
||||
{{ build.date }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="build.totalTime"></total-time>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
});
|
|
@ -0,0 +1,60 @@
|
|||
<script>
|
||||
import iconBuildStatus from '../svg/icon_build_status.svg';
|
||||
import iconBranch from '../svg/icon_branch.svg';
|
||||
import limitWarning from './limit_warning_component.vue';
|
||||
import totalTime from './total_time_component.vue';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
items: Array,
|
||||
stage: Object,
|
||||
},
|
||||
components: {
|
||||
totalTime,
|
||||
limitWarning,
|
||||
},
|
||||
computed: {
|
||||
iconBuildStatus() {
|
||||
return iconBuildStatus;
|
||||
},
|
||||
iconBranch() {
|
||||
return iconBranch;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="events-description">
|
||||
{{ stage.description }}
|
||||
<limit-warning :count="items.length" />
|
||||
</div>
|
||||
<ul class="stage-event-list">
|
||||
<li
|
||||
v-for="(build, i) in items"
|
||||
:key="i"
|
||||
class="stage-event-item item-build-component">
|
||||
<div class="item-details">
|
||||
<h5 class="item-title">
|
||||
<span class="icon-build-status" v-html="iconBuildStatus"></span>
|
||||
<a :href="build.url" class="item-build-name">{{ build.name }}</a>
|
||||
·
|
||||
<a :href="build.url" class="pipeline-id">#{{ build.id }}</a>
|
||||
<i class="fa fa-code-fork"></i>
|
||||
<a :href="build.branch.url" class="ref-name">{{ build.branch.name }}</a>
|
||||
<span class="icon-branch" v-html="iconBranch"></span>
|
||||
<a :href="build.commitUrl" class="commit-sha">{{ build.shortSha }}</a>
|
||||
</h5>
|
||||
<span>
|
||||
<a :href="build.url" class="issue-date">
|
||||
{{ build.date }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-time">
|
||||
<total-time :time="build.totalTime"/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
|
@ -1,25 +0,0 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
|
||||
import Vue from 'vue';
|
||||
|
||||
const global = window.gl || (window.gl = {});
|
||||
global.cycleAnalytics = global.cycleAnalytics || {};
|
||||
|
||||
global.cycleAnalytics.TotalTimeComponent = Vue.extend({
|
||||
props: {
|
||||
time: Object,
|
||||
},
|
||||
template: `
|
||||
<span class="total-time">
|
||||
<template v-if="Object.keys(time).length">
|
||||
<template v-if="time.days">{{ time.days }} <span>{{ n__('day', 'days', time.days) }}</span></template>
|
||||
<template v-if="time.hours">{{ time.hours }} <span>{{ n__('Time|hr', 'Time|hrs', time.hours) }}</span></template>
|
||||
<template v-if="time.mins && !time.days">{{ time.mins }} <span>{{ n__('Time|min', 'Time|mins', time.mins) }}</span></template>
|
||||
<template v-if="time.seconds && Object.keys(time).length === 1 || time.seconds === 0">{{ time.seconds }} <span>{{ s__('Time|s') }}</span></template>
|
||||
</template>
|
||||
<template v-else>
|
||||
--
|
||||
</template>
|
||||
</span>
|
||||
`,
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
<script>
|
||||
export default {
|
||||
props: {
|
||||
time: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
hasData() {
|
||||
return Object.keys(this.time).length;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<span class="total-time">
|
||||
<template v-if="hasData">
|
||||
<template v-if="time.days">{{ time.days }} <span>{{ n__('day', 'days', time.days) }}</span></template>
|
||||
<template v-if="time.hours">{{ time.hours }} <span>{{ n__('Time|hr', 'Time|hrs', time.hours) }}</span></template>
|
||||
<template v-if="time.mins && !time.days">{{ time.mins }} <span>{{ n__('Time|min', 'Time|mins', time.mins) }}</span></template>
|
||||
<template v-if="time.seconds && hasDa === 1 || time.seconds === 0">{{ time.seconds }} <span>{{ s__('Time|s') }}</span></template>
|
||||
</template>
|
||||
<template v-else>
|
||||
--
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
|
@ -3,60 +3,61 @@
|
|||
import Vue from 'vue';
|
||||
import Cookies from 'js-cookie';
|
||||
import Translate from '../vue_shared/translate';
|
||||
import LimitWarningComponent from './components/limit_warning_component';
|
||||
import './components/stage_code_component';
|
||||
import './components/stage_issue_component';
|
||||
import './components/stage_plan_component';
|
||||
import './components/stage_production_component';
|
||||
import './components/stage_review_component';
|
||||
import './components/stage_staging_component';
|
||||
import './components/stage_test_component';
|
||||
import './components/total_time_component';
|
||||
import './cycle_analytics_service';
|
||||
import './cycle_analytics_store';
|
||||
import stageCodeComponent from './components/stage_code_component.vue';
|
||||
import stagePlanComponent from './components/stage_plan_component.vue';
|
||||
import stageComponent from './components/stage_component.vue';
|
||||
import stageReviewComponent from './components/stage_review_component.vue';
|
||||
import stageStagingComponent from './components/stage_staging_component.vue';
|
||||
import stageTestComponent from './components/stage_test_component.vue';
|
||||
import CycleAnalyticsService from './cycle_analytics_service';
|
||||
import CycleAnalyticsStore from './cycle_analytics_store';
|
||||
|
||||
Vue.use(Translate);
|
||||
|
||||
$(() => {
|
||||
const OVERVIEW_DIALOG_COOKIE = 'cycle_analytics_help_dismissed';
|
||||
const cycleAnalyticsEl = document.querySelector('#cycle-analytics');
|
||||
const cycleAnalyticsStore = gl.cycleAnalytics.CycleAnalyticsStore;
|
||||
const cycleAnalyticsService = new gl.cycleAnalytics.CycleAnalyticsService({
|
||||
requestPath: cycleAnalyticsEl.dataset.requestPath,
|
||||
});
|
||||
|
||||
gl.cycleAnalyticsApp = new Vue({
|
||||
el: '#cycle-analytics',
|
||||
name: 'CycleAnalytics',
|
||||
data: {
|
||||
state: cycleAnalyticsStore.state,
|
||||
data() {
|
||||
const cycleAnalyticsEl = document.querySelector('#cycle-analytics');
|
||||
const cycleAnalyticsService = new CycleAnalyticsService({
|
||||
requestPath: cycleAnalyticsEl.dataset.requestPath,
|
||||
});
|
||||
|
||||
return {
|
||||
store: CycleAnalyticsStore,
|
||||
state: CycleAnalyticsStore.state,
|
||||
isLoading: false,
|
||||
isLoadingStage: false,
|
||||
isEmptyStage: false,
|
||||
hasError: false,
|
||||
startDate: 30,
|
||||
isOverviewDialogDismissed: Cookies.get(OVERVIEW_DIALOG_COOKIE),
|
||||
service: cycleAnalyticsService,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
currentStage() {
|
||||
return cycleAnalyticsStore.currentActiveStage();
|
||||
return this.store.currentActiveStage();
|
||||
},
|
||||
},
|
||||
components: {
|
||||
'stage-issue-component': gl.cycleAnalytics.StageIssueComponent,
|
||||
'stage-plan-component': gl.cycleAnalytics.StagePlanComponent,
|
||||
'stage-code-component': gl.cycleAnalytics.StageCodeComponent,
|
||||
'stage-test-component': gl.cycleAnalytics.StageTestComponent,
|
||||
'stage-review-component': gl.cycleAnalytics.StageReviewComponent,
|
||||
'stage-staging-component': gl.cycleAnalytics.StageStagingComponent,
|
||||
'stage-production-component': gl.cycleAnalytics.StageProductionComponent,
|
||||
'stage-issue-component': stageComponent,
|
||||
'stage-plan-component': stagePlanComponent,
|
||||
'stage-code-component': stageCodeComponent,
|
||||
'stage-test-component': stageTestComponent,
|
||||
'stage-review-component': stageReviewComponent,
|
||||
'stage-staging-component': stageStagingComponent,
|
||||
'stage-production-component': stageComponent,
|
||||
},
|
||||
created() {
|
||||
this.fetchCycleAnalyticsData();
|
||||
},
|
||||
methods: {
|
||||
handleError() {
|
||||
cycleAnalyticsStore.setErrorState(true);
|
||||
this.store.setErrorState(true);
|
||||
return new Flash('There was an error while fetching cycle analytics data.');
|
||||
},
|
||||
initDropdown() {
|
||||
|
@ -77,17 +78,17 @@ $(() => {
|
|||
|
||||
this.isLoading = true;
|
||||
|
||||
cycleAnalyticsService
|
||||
this.service
|
||||
.fetchCycleAnalyticsData(fetchOptions)
|
||||
.done((response) => {
|
||||
cycleAnalyticsStore.setCycleAnalyticsData(response);
|
||||
.then(resp => resp.json())
|
||||
.then((response) => {
|
||||
this.store.setCycleAnalyticsData(response);
|
||||
this.selectDefaultStage();
|
||||
this.initDropdown();
|
||||
this.isLoading = false;
|
||||
})
|
||||
.error(() => {
|
||||
.catch(() => {
|
||||
this.handleError();
|
||||
})
|
||||
.always(() => {
|
||||
this.isLoading = false;
|
||||
});
|
||||
},
|
||||
|
@ -100,27 +101,27 @@ $(() => {
|
|||
if (this.currentStage === stage) return;
|
||||
|
||||
if (!stage.isUserAllowed) {
|
||||
cycleAnalyticsStore.setActiveStage(stage);
|
||||
this.store.setActiveStage(stage);
|
||||
return;
|
||||
}
|
||||
|
||||
this.isLoadingStage = true;
|
||||
cycleAnalyticsStore.setStageEvents([], stage);
|
||||
cycleAnalyticsStore.setActiveStage(stage);
|
||||
this.store.setStageEvents([], stage);
|
||||
this.store.setActiveStage(stage);
|
||||
|
||||
cycleAnalyticsService
|
||||
this.service
|
||||
.fetchStageData({
|
||||
stage,
|
||||
startDate: this.startDate,
|
||||
})
|
||||
.done((response) => {
|
||||
.then(resp => resp.json())
|
||||
.then((response) => {
|
||||
this.isEmptyStage = !response.events.length;
|
||||
cycleAnalyticsStore.setStageEvents(response.events, stage);
|
||||
this.store.setStageEvents(response.events, stage);
|
||||
this.isLoadingStage = false;
|
||||
})
|
||||
.error(() => {
|
||||
.catch(() => {
|
||||
this.isEmptyStage = true;
|
||||
})
|
||||
.always(() => {
|
||||
this.isLoadingStage = false;
|
||||
});
|
||||
},
|
||||
|
@ -130,8 +131,4 @@ $(() => {
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Register global components
|
||||
Vue.component('limit-warning', LimitWarningComponent);
|
||||
Vue.component('total-time', gl.cycleAnalytics.TotalTimeComponent);
|
||||
});
|
||||
|
|
|
@ -1,27 +1,16 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
import Vue from 'vue';
|
||||
import VueResource from 'vue-resource';
|
||||
|
||||
const global = window.gl || (window.gl = {});
|
||||
global.cycleAnalytics = global.cycleAnalytics || {};
|
||||
Vue.use(VueResource);
|
||||
|
||||
class CycleAnalyticsService {
|
||||
export default class CycleAnalyticsService {
|
||||
constructor(options) {
|
||||
this.requestPath = options.requestPath;
|
||||
this.cycleAnalytics = Vue.resource(this.requestPath);
|
||||
}
|
||||
|
||||
fetchCycleAnalyticsData(options) {
|
||||
options = options || { startDate: 30 };
|
||||
|
||||
return $.ajax({
|
||||
url: this.requestPath,
|
||||
method: 'GET',
|
||||
dataType: 'json',
|
||||
contentType: 'application/json',
|
||||
data: {
|
||||
cycle_analytics: {
|
||||
start_date: options.startDate,
|
||||
},
|
||||
},
|
||||
});
|
||||
fetchCycleAnalyticsData(options = { startDate: 30 }) {
|
||||
return this.cycleAnalytics.get({ cycle_analytics: { start_date: options.startDate } });
|
||||
}
|
||||
|
||||
fetchStageData(options) {
|
||||
|
@ -30,12 +19,12 @@ class CycleAnalyticsService {
|
|||
startDate,
|
||||
} = options;
|
||||
|
||||
return $.get(`${this.requestPath}/events/${stage.name}.json`, {
|
||||
return Vue.http.get(`${this.requestPath}/events/${stage.name}.json`, {
|
||||
params: {
|
||||
cycle_analytics: {
|
||||
start_date: startDate,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
global.cycleAnalytics.CycleAnalyticsService = CycleAnalyticsService;
|
||||
|
|
|
@ -4,9 +4,6 @@ import { __ } from '../locale';
|
|||
import '../lib/utils/text_utility';
|
||||
import DEFAULT_EVENT_OBJECTS from './default_event_objects';
|
||||
|
||||
const global = window.gl || (window.gl = {});
|
||||
global.cycleAnalytics = global.cycleAnalytics || {};
|
||||
|
||||
const EMPTY_STAGE_TEXTS = {
|
||||
issue: __('The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.'),
|
||||
plan: __('The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.'),
|
||||
|
@ -17,7 +14,7 @@ const EMPTY_STAGE_TEXTS = {
|
|||
production: __('The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.'),
|
||||
};
|
||||
|
||||
global.cycleAnalytics.CycleAnalyticsStore = {
|
||||
export default {
|
||||
state: {
|
||||
summary: '',
|
||||
stats: '',
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
/* global NotificationsDropdown */
|
||||
/* global GroupAvatar */
|
||||
/* global LineHighlighter */
|
||||
/* global ProjectFork */
|
||||
/* global BuildArtifacts */
|
||||
/* global GroupsSelect */
|
||||
/* global Search */
|
||||
|
@ -476,7 +475,9 @@ import { ajaxGet, convertPermissionToBoolean } from './lib/utils/common_utils';
|
|||
shortcut_handler = true;
|
||||
break;
|
||||
case 'projects:forks:new':
|
||||
new ProjectFork();
|
||||
import(/* webpackChunkName: 'project_fork' */ './project_fork')
|
||||
.then(fork => fork.default())
|
||||
.catch(() => {});
|
||||
break;
|
||||
case 'projects:artifacts:browse':
|
||||
new ShortcutsNavigation();
|
||||
|
|
|
@ -163,7 +163,7 @@ export default {
|
|||
|
||||
this.service.postAction(endpoint)
|
||||
.then(() => this.fetchEnvironments())
|
||||
.catch(() => new Flash('An error occured while making the request.'));
|
||||
.catch(() => new Flash('An error occurred while making the request.'));
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ export default {
|
|||
|
||||
this.service.postAction(endpoint)
|
||||
.then(() => this.fetchEnvironments())
|
||||
.catch(() => new Flash('An error occured while making the request.'));
|
||||
.catch(() => new Flash('An error occurred while making the request.'));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
* causes reflows, visit https://gist.github.com/paulirish/5d52fb081b3570c81e3a
|
||||
*/
|
||||
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
const LINE_NUMBER_CLASS = 'diff-line-num';
|
||||
const UNFOLDABLE_LINE_CLASS = 'js-unfold';
|
||||
const NO_COMMENT_CLASS = 'no-comment-btn';
|
||||
|
@ -27,9 +29,7 @@ export default {
|
|||
this.userCanCreateNote = $diffFile.closest(DIFF_CONTAINER_SELECTOR).data('can-create-note') === '';
|
||||
}
|
||||
|
||||
if (typeof notes !== 'undefined' && !this.isParallelView) {
|
||||
this.isParallelView = notes.isParallelView && notes.isParallelView();
|
||||
}
|
||||
this.isParallelView = Cookies.get('diff_view') === 'parallel';
|
||||
|
||||
if (this.userCanCreateNote) {
|
||||
$diffFile.on('mouseover', LINE_COLUMN_CLASSES, e => this.showButton(this.isParallelView, e))
|
||||
|
|
|
@ -14,7 +14,7 @@ class DropdownEmoji extends gl.FilteredSearchDropdown {
|
|||
loadingTemplate: this.loadingTemplate,
|
||||
onError() {
|
||||
/* eslint-disable no-new */
|
||||
new Flash('An error occured fetching the dropdown data.');
|
||||
new Flash('An error occurred fetching the dropdown data.');
|
||||
/* eslint-enable no-new */
|
||||
},
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ class DropdownNonUser extends gl.FilteredSearchDropdown {
|
|||
preprocessing,
|
||||
onError() {
|
||||
/* eslint-disable no-new */
|
||||
new Flash('An error occured fetching the dropdown data.');
|
||||
new Flash('An error occurred fetching the dropdown data.');
|
||||
/* eslint-enable no-new */
|
||||
},
|
||||
},
|
||||
|
|
|
@ -26,7 +26,7 @@ class DropdownUser extends gl.FilteredSearchDropdown {
|
|||
},
|
||||
onError() {
|
||||
/* eslint-disable no-new */
|
||||
new Flash('An error occured fetching the dropdown data.');
|
||||
new Flash('An error occurred fetching the dropdown data.');
|
||||
/* eslint-enable no-new */
|
||||
},
|
||||
},
|
||||
|
|
|
@ -36,7 +36,7 @@ class FilteredSearchManager {
|
|||
.catch((error) => {
|
||||
if (error.name === 'RecentSearchesServiceError') return undefined;
|
||||
// eslint-disable-next-line no-new
|
||||
new window.Flash('An error occured while parsing recent searches');
|
||||
new window.Flash('An error occurred while parsing recent searches');
|
||||
// Gracefully fail to empty array
|
||||
return [];
|
||||
})
|
||||
|
|
|
@ -34,7 +34,7 @@ export const canShowActiveSubItems = (el) => {
|
|||
export const canShowSubItems = () => bp.getBreakpointSize() === 'sm' || bp.getBreakpointSize() === 'md' || bp.getBreakpointSize() === 'lg';
|
||||
|
||||
export const getHideSubItemsInterval = () => {
|
||||
if (!currentOpenMenu) return 0;
|
||||
if (!currentOpenMenu || !mousePos.length) return 0;
|
||||
|
||||
const currentMousePos = mousePos[mousePos.length - 1];
|
||||
const prevMousePos = mousePos[0];
|
||||
|
|
|
@ -67,10 +67,13 @@ const PARTICIPANTS_ROW_COUNT = 7;
|
|||
originalText = $(this).data("original-text");
|
||||
if (currentText === originalText) {
|
||||
$(this).text(lessText);
|
||||
|
||||
if (gl.lazyLoader) gl.lazyLoader.loadCheck();
|
||||
} else {
|
||||
$(this).text(originalText);
|
||||
}
|
||||
return $(".js-participants-hidden").toggle();
|
||||
|
||||
$(".js-participants-hidden").toggle();
|
||||
};
|
||||
|
||||
return IssuableContext;
|
||||
|
|
|
@ -71,6 +71,7 @@ export const handleLocationHash = () => {
|
|||
// This is required to handle non-unicode characters in hash
|
||||
hash = decodeURIComponent(hash);
|
||||
|
||||
const target = document.getElementById(hash) || document.getElementById(`user-content-${hash}`);
|
||||
const fixedTabs = document.querySelector('.js-tabs-affix');
|
||||
const fixedDiffStats = document.querySelector('.js-diff-files-changed.is-stuck');
|
||||
const fixedNav = document.querySelector('.navbar-gitlab');
|
||||
|
@ -78,15 +79,10 @@ export const handleLocationHash = () => {
|
|||
let adjustment = 0;
|
||||
if (fixedNav) adjustment -= fixedNav.offsetHeight;
|
||||
|
||||
// scroll to user-generated markdown anchor if we cannot find a match
|
||||
if (document.getElementById(hash) === null) {
|
||||
const target = document.getElementById(`user-content-${hash}`);
|
||||
if (target && target.scrollIntoView) {
|
||||
target.scrollIntoView(true);
|
||||
window.scrollBy(0, adjustment);
|
||||
}
|
||||
} else {
|
||||
// only adjust for fixedTabs when not targeting user-generated content
|
||||
|
||||
if (fixedTabs) {
|
||||
adjustment -= fixedTabs.offsetHeight;
|
||||
}
|
||||
|
@ -96,7 +92,6 @@ export const handleLocationHash = () => {
|
|||
}
|
||||
|
||||
window.scrollBy(0, adjustment);
|
||||
}
|
||||
};
|
||||
|
||||
// Check if element scrolled into viewport from above or below
|
||||
|
|
|
@ -55,7 +55,7 @@ window.dateFormat = dateFormat;
|
|||
if (!timeagoInstance) {
|
||||
const localeRemaining = function(number, index) {
|
||||
return [
|
||||
[s__('Timeago|less than a minute ago'), s__('Timeago|a while')],
|
||||
[s__('Timeago|less than a minute ago'), s__('Timeago|in a while')],
|
||||
[s__('Timeago|less than a minute ago'), s__('Timeago|%s seconds remaining')],
|
||||
[s__('Timeago|about a minute ago'), s__('Timeago|1 minute remaining')],
|
||||
[s__('Timeago|%s minutes ago'), s__('Timeago|%s minutes remaining')],
|
||||
|
@ -73,7 +73,7 @@ window.dateFormat = dateFormat;
|
|||
};
|
||||
locale = function(number, index) {
|
||||
return [
|
||||
[s__('Timeago|less than a minute ago'), s__('Timeago|a while')],
|
||||
[s__('Timeago|less than a minute ago'), s__('Timeago|in a while')],
|
||||
[s__('Timeago|less than a minute ago'), s__('Timeago|in %s seconds')],
|
||||
[s__('Timeago|about a minute ago'), s__('Timeago|in 1 minute')],
|
||||
[s__('Timeago|%s minutes ago'), s__('Timeago|in %s minutes')],
|
||||
|
|
|
@ -1,14 +1,34 @@
|
|||
export const isSticky = (el, scrollY, stickyTop) => {
|
||||
export const createPlaceholder = () => {
|
||||
const placeholder = document.createElement('div');
|
||||
placeholder.classList.add('sticky-placeholder');
|
||||
|
||||
return placeholder;
|
||||
};
|
||||
|
||||
export const isSticky = (el, scrollY, stickyTop, insertPlaceholder) => {
|
||||
const top = Math.floor(el.offsetTop - scrollY);
|
||||
|
||||
if (top <= stickyTop) {
|
||||
if (top <= stickyTop && !el.classList.contains('is-stuck')) {
|
||||
const placeholder = insertPlaceholder ? createPlaceholder() : null;
|
||||
const heightBefore = el.offsetHeight;
|
||||
|
||||
el.classList.add('is-stuck');
|
||||
} else {
|
||||
|
||||
if (insertPlaceholder) {
|
||||
el.parentNode.insertBefore(placeholder, el.nextElementSibling);
|
||||
|
||||
placeholder.style.height = `${heightBefore - el.offsetHeight}px`;
|
||||
}
|
||||
} else if (top > stickyTop && el.classList.contains('is-stuck')) {
|
||||
el.classList.remove('is-stuck');
|
||||
|
||||
if (insertPlaceholder && el.nextElementSibling && el.nextElementSibling.classList.contains('sticky-placeholder')) {
|
||||
el.nextElementSibling.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default (el) => {
|
||||
export default (el, insertPlaceholder = true) => {
|
||||
if (!el) return;
|
||||
|
||||
const computedStyle = window.getComputedStyle(el);
|
||||
|
@ -17,7 +37,7 @@ export default (el) => {
|
|||
|
||||
const stickyTop = parseInt(computedStyle.top, 10);
|
||||
|
||||
document.addEventListener('scroll', () => isSticky(el, window.scrollY, stickyTop), {
|
||||
document.addEventListener('scroll', () => isSticky(el, window.scrollY, stickyTop, insertPlaceholder), {
|
||||
passive: true,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -28,47 +28,51 @@
|
|||
// </div>
|
||||
// </div>
|
||||
//
|
||||
(function() {
|
||||
this.LineHighlighter = (function() {
|
||||
// CSS class applied to highlighted lines
|
||||
LineHighlighter.prototype.highlightClass = 'hll';
|
||||
|
||||
// Internal copy of location.hash so we're not dependent on `location` in tests
|
||||
LineHighlighter.prototype._hash = '';
|
||||
const LineHighlighter = function(options = {}) {
|
||||
options.highlightLineClass = options.highlightLineClass || 'hll';
|
||||
options.fileHolderSelector = options.fileHolderSelector || '.file-holder';
|
||||
options.scrollFileHolder = options.scrollFileHolder || false;
|
||||
options.hash = options.hash || location.hash;
|
||||
|
||||
function LineHighlighter(hash) {
|
||||
if (hash == null) {
|
||||
// Initialize a LineHighlighter object
|
||||
//
|
||||
// hash - String URL hash for dependency injection in tests
|
||||
hash = location.hash;
|
||||
}
|
||||
this.options = options;
|
||||
this._hash = options.hash;
|
||||
this.highlightLineClass = options.highlightLineClass;
|
||||
this.setHash = this.setHash.bind(this);
|
||||
this.highlightLine = this.highlightLine.bind(this);
|
||||
this.clickHandler = this.clickHandler.bind(this);
|
||||
this.highlightHash = this.highlightHash.bind(this);
|
||||
this._hash = hash;
|
||||
|
||||
this.bindEvents();
|
||||
this.highlightHash();
|
||||
}
|
||||
};
|
||||
|
||||
LineHighlighter.prototype.bindEvents = function() {
|
||||
const $fileHolder = $('.file-holder');
|
||||
const $fileHolder = $(this.options.fileHolderSelector);
|
||||
|
||||
$fileHolder.on('click', 'a[data-line-number]', this.clickHandler);
|
||||
$fileHolder.on('highlight:line', this.highlightHash);
|
||||
};
|
||||
|
||||
LineHighlighter.prototype.highlightHash = function() {
|
||||
var range;
|
||||
|
||||
if (this._hash !== '') {
|
||||
range = this.hashToRange(this._hash);
|
||||
|
||||
if (range[0]) {
|
||||
this.highlightRange(range);
|
||||
$.scrollTo("#L" + range[0], {
|
||||
const lineSelector = `#L${range[0]}`;
|
||||
const scrollOptions = {
|
||||
// Scroll to the first highlighted line on initial load
|
||||
// Offset -50 for the sticky top bar, and another -100 for some context
|
||||
offset: -150
|
||||
});
|
||||
};
|
||||
if (this.options.scrollFileHolder) {
|
||||
$(this.options.fileHolderSelector).scrollTo(lineSelector, scrollOptions);
|
||||
} else {
|
||||
$.scrollTo(lineSelector, scrollOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -96,8 +100,7 @@
|
|||
};
|
||||
|
||||
LineHighlighter.prototype.clearHighlight = function() {
|
||||
return $("." + this.highlightClass).removeClass(this.highlightClass);
|
||||
// Unhighlight previously highlighted lines
|
||||
return $("." + this.highlightLineClass).removeClass(this.highlightLineClass);
|
||||
};
|
||||
|
||||
// Convert a URL hash String into line numbers
|
||||
|
@ -128,7 +131,7 @@
|
|||
//
|
||||
// lineNumber - Line number to highlight
|
||||
LineHighlighter.prototype.highlightLine = function(lineNumber) {
|
||||
return $("#LC" + lineNumber).addClass(this.highlightClass);
|
||||
return $("#LC" + lineNumber).addClass(this.highlightLineClass);
|
||||
};
|
||||
|
||||
// Highlight all lines within a range
|
||||
|
@ -170,6 +173,4 @@
|
|||
}, document.title, value);
|
||||
};
|
||||
|
||||
return LineHighlighter;
|
||||
})();
|
||||
}).call(window);
|
||||
window.LineHighlighter = LineHighlighter;
|
||||
|
|
|
@ -16,9 +16,8 @@ const locales = allLocales.reduce((d, obj) => {
|
|||
return data;
|
||||
}, {});
|
||||
|
||||
let lang = document.querySelector('html').getAttribute('lang') || 'en';
|
||||
lang = lang.replace(/-/g, '_');
|
||||
|
||||
const langAttribute = document.querySelector('html').getAttribute('lang');
|
||||
const lang = (langAttribute || 'en').replace(/-/g, '_');
|
||||
const locale = new Jed(locales[lang]);
|
||||
|
||||
/**
|
||||
|
|
|
@ -124,7 +124,6 @@ import './preview_markdown';
|
|||
import './project';
|
||||
import './project_avatar';
|
||||
import './project_find_file';
|
||||
import './project_fork';
|
||||
import './project_import';
|
||||
import './project_label_subscription';
|
||||
import './project_new';
|
||||
|
@ -302,7 +301,10 @@ $(function () {
|
|||
return $container.remove();
|
||||
// Commit show suppressed diff
|
||||
});
|
||||
$('.navbar-toggle').on('click', () => $('.header-content').toggleClass('menu-expanded'));
|
||||
$('.navbar-toggle').on('click', () => {
|
||||
$('.header-content').toggleClass('menu-expanded');
|
||||
gl.lazyLoader.loadCheck();
|
||||
});
|
||||
// Show/hide comments on diff
|
||||
$body.on('click', '.js-toggle-diff-comments', function (e) {
|
||||
var $this = $(this);
|
||||
|
|
|
@ -352,7 +352,7 @@ import {
|
|||
}
|
||||
|
||||
expandViewContainer() {
|
||||
const $wrapper = $('.content-wrapper .container-fluid');
|
||||
const $wrapper = $('.content-wrapper .container-fluid').not('.breadcrumbs');
|
||||
if (this.fixedLayoutPref === null) {
|
||||
this.fixedLayoutPref = $wrapper.hasClass('container-limited');
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
},
|
||||
deleteHandler() {
|
||||
// eslint-disable-next-line no-alert
|
||||
if (confirm('Are you sure you want to delete this list?')) {
|
||||
if (confirm('Are you sure you want to delete this comment?')) {
|
||||
this.isDeleting = true;
|
||||
|
||||
this.deleteNote(this.note)
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
popoverOptions() {
|
||||
return {
|
||||
html: true,
|
||||
delay: { hide: 600 },
|
||||
trigger: 'hover',
|
||||
trigger: 'focus',
|
||||
placement: 'top',
|
||||
title: '<div class="autodevops-title">This pipeline makes use of a predefined CI/CD configuration enabled by <b>Auto DevOps.</b></div>',
|
||||
content: `<a class="autodevops-link" href="${this.autoDevopsHelpPath}" target="_blank" rel="noopener noreferrer nofollow">Learn more about Auto DevOps</a>`,
|
||||
|
@ -75,6 +74,7 @@
|
|||
</span>
|
||||
<a
|
||||
v-if="pipeline.flags.auto_devops"
|
||||
tabindex="0"
|
||||
class="js-pipeline-url-autodevops label label-info autodevops-badge"
|
||||
v-popover="popoverOptions"
|
||||
role="button">
|
||||
|
|
|
@ -97,7 +97,7 @@ export default {
|
|||
postAction(endpoint) {
|
||||
this.service.postAction(endpoint)
|
||||
.then(() => eventHub.$emit('refreshPipelines'))
|
||||
.catch(() => new Flash('An error occured while making the request.'));
|
||||
.catch(() => new Flash('An error occurred while making the request.'));
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -73,7 +73,8 @@ import _ from 'underscore';
|
|||
aspectRatio: 1,
|
||||
modal: true,
|
||||
scalable: false,
|
||||
rotatable: false,
|
||||
rotatable: true,
|
||||
checkOrientation: true,
|
||||
zoomable: true,
|
||||
dragMode: 'move',
|
||||
guides: false,
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, wrap-iife, prefer-arrow-callback, max-len */
|
||||
(function() {
|
||||
this.ProjectFork = (function() {
|
||||
function ProjectFork() {
|
||||
$('.fork-thumbnail a').on('click', function() {
|
||||
export default () => {
|
||||
$('.fork-thumbnail a').on('click', function forkThumbnailClicked() {
|
||||
if ($(this).hasClass('disabled')) return false;
|
||||
|
||||
$('.fork-namespaces').hide();
|
||||
return $('.save-project-loader').show();
|
||||
});
|
||||
}
|
||||
|
||||
return ProjectFork;
|
||||
})();
|
||||
}).call(window);
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@ export default class ProjectsService {
|
|||
|
||||
getSearchedProjects(searchQuery) {
|
||||
return this.projectsPath.get({
|
||||
simple: false,
|
||||
simple: true,
|
||||
per_page: 20,
|
||||
membership: !!gon.current_user_id,
|
||||
order_by: 'last_activity_at',
|
||||
|
|
|
@ -37,14 +37,14 @@ export default {
|
|||
content: f.newContent,
|
||||
}));
|
||||
const payload = {
|
||||
branch: Store.targetBranch,
|
||||
branch: Store.currentBranch,
|
||||
commit_message: commitMessage,
|
||||
actions,
|
||||
};
|
||||
Store.submitCommitsLoading = true;
|
||||
Service.commitFiles(payload)
|
||||
.then(this.resetCommitState)
|
||||
.catch(() => Flash('An error occured while committing your changes'));
|
||||
.catch(() => Flash('An error occurred while committing your changes'));
|
||||
},
|
||||
|
||||
resetCommitState() {
|
||||
|
@ -105,7 +105,7 @@ export default {
|
|||
</label>
|
||||
<div class="col-md-6">
|
||||
<span class="help-block">
|
||||
{{targetBranch}}
|
||||
{{currentBranch}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -26,16 +26,6 @@ export default {
|
|||
this.editMode = !this.editMode;
|
||||
Store.toggleBlobView();
|
||||
},
|
||||
toggleProjectRefsForm() {
|
||||
$('.project-refs-form').toggleClass('disabled', this.editMode);
|
||||
$('.js-tree-ref-target-holder').toggle(this.editMode);
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
editMode() {
|
||||
this.toggleProjectRefsForm();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -95,7 +95,7 @@ export default RepoFile;
|
|||
</div>
|
||||
</td>
|
||||
|
||||
<td class="hidden-xs">
|
||||
<td class="hidden-xs text-right">
|
||||
<span
|
||||
class="commit-update"
|
||||
:title="tooltipTitle(file.lastCommitUpdate)">
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
<script>
|
||||
/* global LineHighlighter */
|
||||
|
||||
import Store from '../stores/repo_store';
|
||||
|
||||
export default {
|
||||
data: () => Store,
|
||||
mounted() {
|
||||
this.highlightFile();
|
||||
},
|
||||
computed: {
|
||||
html() {
|
||||
return this.activeFile.html;
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
highlightFile() {
|
||||
$(this.$el).find('.file-content').syntaxHighlight();
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.highlightFile();
|
||||
this.lineHighlighter = new LineHighlighter({
|
||||
fileHolderSelector: '.blob-viewer-container',
|
||||
scrollFileHolder: true,
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
html() {
|
||||
this.$nextTick(() => {
|
||||
|
@ -45,7 +49,7 @@ export default {
|
|||
v-else
|
||||
class="vertical-center render-error">
|
||||
<p class="text-center">
|
||||
The source could not be displayed because a rendering error occured. You can <a :href="activeFile.raw_path">download</a> it instead.
|
||||
The source could not be displayed because a rendering error occurred. You can <a :href="activeFile.raw_path">download</a> it instead.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -37,9 +37,15 @@ export default {
|
|||
let file = clickedFile;
|
||||
if (file.loading) return;
|
||||
file.loading = true;
|
||||
|
||||
if (file.type === 'tree' && file.opened) {
|
||||
file = Store.removeChildFilesOfTree(file);
|
||||
file.loading = false;
|
||||
} else {
|
||||
const openFile = Helper.getFileFromPath(file.url);
|
||||
if (openFile) {
|
||||
file.loading = false;
|
||||
Store.setActiveFiles(openFile);
|
||||
} else {
|
||||
Service.url = file.url;
|
||||
Helper.getContent(file)
|
||||
|
@ -49,6 +55,7 @@ export default {
|
|||
})
|
||||
.catch(Helper.loadingError);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
goToPreviousDirectoryClicked(prevURL) {
|
||||
|
@ -68,7 +75,7 @@ export default {
|
|||
<tr>
|
||||
<th class="name">Name</th>
|
||||
<th class="hidden-sm hidden-xs last-commit">Last Commit</th>
|
||||
<th class="hidden-xs last-update">Last Update</th>
|
||||
<th class="hidden-xs last-update text-right">Last Update</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
|
@ -58,13 +58,13 @@ const RepoHelper = {
|
|||
return langs.find(lang => lang.extensions && lang.extensions.indexOf(`.${ext}`) > -1);
|
||||
},
|
||||
|
||||
setDirectoryOpen(tree) {
|
||||
setDirectoryOpen(tree, title) {
|
||||
const file = tree;
|
||||
if (!file) return undefined;
|
||||
|
||||
file.opened = true;
|
||||
file.icon = 'fa-folder-open';
|
||||
RepoHelper.updateHistoryEntry(file.url, file.name);
|
||||
RepoHelper.updateHistoryEntry(file.url, title);
|
||||
return file;
|
||||
},
|
||||
|
||||
|
@ -135,6 +135,8 @@ const RepoHelper = {
|
|||
return Service.getContent()
|
||||
.then((response) => {
|
||||
const data = response.data;
|
||||
if (response.headers && response.headers['page-title']) data.pageTitle = response.headers['page-title'];
|
||||
|
||||
Store.isTree = RepoHelper.isTree(data);
|
||||
if (!Store.isTree) {
|
||||
if (!file) file = data;
|
||||
|
@ -168,7 +170,7 @@ const RepoHelper = {
|
|||
} else {
|
||||
// it's a tree
|
||||
if (!file) Store.isRoot = RepoHelper.isRoot(Service.url);
|
||||
file = RepoHelper.setDirectoryOpen(file);
|
||||
file = RepoHelper.setDirectoryOpen(file, data.pageTitle || data.name);
|
||||
const newDirectory = RepoHelper.dataToListOfFiles(data);
|
||||
Store.addFilesToDirectory(file, Store.files, newDirectory);
|
||||
Store.prevURL = Service.blobURLtoParentTree(Service.url);
|
||||
|
@ -178,8 +180,8 @@ const RepoHelper = {
|
|||
|
||||
setFile(data, file) {
|
||||
const newFile = data;
|
||||
newFile.url = file.url || Service.url; // Grab the URL from service, happens on page refresh.
|
||||
|
||||
newFile.url = file.url;
|
||||
if (newFile.render_error === 'too_large' || newFile.render_error === 'collapsed') {
|
||||
newFile.tooLarge = true;
|
||||
}
|
||||
|
@ -255,7 +257,7 @@ const RepoHelper = {
|
|||
history.pushState({ key: RepoHelper.key }, '', url);
|
||||
|
||||
if (title) {
|
||||
document.title = `${title} · GitLab`;
|
||||
document.title = title;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -263,6 +265,10 @@ const RepoHelper = {
|
|||
return Store.openedFiles.find(openedFile => Store.activeFile.url === openedFile.url);
|
||||
},
|
||||
|
||||
getFileFromPath(path) {
|
||||
return Store.openedFiles.find(file => file.url === path);
|
||||
},
|
||||
|
||||
loadingError() {
|
||||
Flash('Unable to load this content at this time.');
|
||||
},
|
||||
|
|
|
@ -11,10 +11,6 @@ function initDropdowns() {
|
|||
}
|
||||
|
||||
function addEventsForNonVueEls() {
|
||||
$(document).on('change', '.dropdown', () => {
|
||||
Store.targetBranch = $('.project-refs-target-form input[name="ref"]').val();
|
||||
});
|
||||
|
||||
window.onbeforeunload = function confirmUnload(e) {
|
||||
const hasChanged = Store.openedFiles
|
||||
.some(file => file.changed);
|
||||
|
|
|
@ -32,7 +32,6 @@ const RepoStore = {
|
|||
isCommitable: false,
|
||||
binary: false,
|
||||
currentBranch: '',
|
||||
targetBranch: 'new-branch',
|
||||
commitMessage: '',
|
||||
binaryTypes: {
|
||||
png: false,
|
||||
|
@ -84,7 +83,7 @@ const RepoStore = {
|
|||
}).catch(Helper.loadingError);
|
||||
}
|
||||
|
||||
if (!file.loading) Helper.updateHistoryEntry(file.url, file.name);
|
||||
if (!file.loading) Helper.updateHistoryEntry(file.url, file.pageTitle || file.name);
|
||||
RepoStore.binary = file.binary;
|
||||
},
|
||||
|
||||
|
|
|
@ -29,7 +29,11 @@ import Cookies from 'js-cookie';
|
|||
$('.dropdown').on('loading.gl.dropdown', this.sidebarDropdownLoading);
|
||||
$('.dropdown').on('loaded.gl.dropdown', this.sidebarDropdownLoaded);
|
||||
|
||||
$document.on('click', '.js-sidebar-toggle', function(e, triggered) {
|
||||
$document.on('click', '.js-sidebar-toggle', this.sidebarToggleClicked);
|
||||
return $(document).off('click', '.js-issuable-todo').on('click', '.js-issuable-todo', this.toggleTodo);
|
||||
};
|
||||
|
||||
Sidebar.prototype.sidebarToggleClicked = function (e, triggered) {
|
||||
var $allGutterToggleIcons, $this, $thisIcon;
|
||||
e.preventDefault();
|
||||
$this = $(this);
|
||||
|
@ -43,12 +47,12 @@ import Cookies from 'js-cookie';
|
|||
$allGutterToggleIcons.removeClass('fa-angle-double-left').addClass('fa-angle-double-right');
|
||||
$('aside.right-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded');
|
||||
$('.page-with-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded');
|
||||
|
||||
if (gl.lazyLoader) gl.lazyLoader.loadCheck();
|
||||
}
|
||||
if (!triggered) {
|
||||
return Cookies.set("collapsed_gutter", $('.right-sidebar').hasClass('right-sidebar-collapsed'));
|
||||
Cookies.set("collapsed_gutter", $('.right-sidebar').hasClass('right-sidebar-collapsed'));
|
||||
}
|
||||
});
|
||||
return $(document).off('click', '.js-issuable-todo').on('click', '.js-issuable-todo', this.toggleTodo);
|
||||
};
|
||||
|
||||
Sidebar.prototype.toggleTodo = function(e) {
|
||||
|
|
|
@ -287,6 +287,7 @@ import { isInGroupsPage, isInProjectPage, getGroupSlug, getProjectSlug } from '.
|
|||
|
||||
onClearInputClick(e) {
|
||||
e.preventDefault();
|
||||
this.wrap.toggleClass('has-value', !!e.target.value);
|
||||
return this.searchInput.val('').focus();
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ class SidebarMoveIssue {
|
|||
data: (searchTerm, callback) => {
|
||||
this.mediator.fetchAutocompleteProjects(searchTerm)
|
||||
.then(callback)
|
||||
.catch(() => new Flash('An error occured while fetching projects autocomplete.'));
|
||||
.catch(() => new Flash('An error occurred while fetching projects autocomplete.'));
|
||||
},
|
||||
renderRow: project => `
|
||||
<li>
|
||||
|
@ -73,7 +73,7 @@ class SidebarMoveIssue {
|
|||
|
||||
this.mediator.moveIssue()
|
||||
.catch(() => {
|
||||
Flash('An error occured while moving the issue.');
|
||||
Flash('An error occurred while moving the issue.');
|
||||
this.$confirmButton
|
||||
.enable()
|
||||
.removeClass('is-loading');
|
||||
|
|
|
@ -41,7 +41,7 @@ export default class SidebarMediator {
|
|||
this.store.setAssigneeData(data);
|
||||
this.store.setTimeTrackingData(data);
|
||||
})
|
||||
.catch(() => new Flash('Error occured when fetching sidebar data'));
|
||||
.catch(() => new Flash('Error occurred when fetching sidebar data'));
|
||||
}
|
||||
|
||||
fetchAutocompleteProjects(searchTerm) {
|
||||
|
|
|
@ -31,10 +31,12 @@
|
|||
@import "framework/mobile";
|
||||
@import "framework/modal";
|
||||
@import "framework/nav";
|
||||
@import "framework/new-nav";
|
||||
@import "framework/pagination";
|
||||
@import "framework/panels";
|
||||
@import "framework/selects";
|
||||
@import "framework/sidebar";
|
||||
@import "framework/new-sidebar";
|
||||
@import "framework/tables";
|
||||
@import "framework/notes";
|
||||
@import "framework/timeline";
|
||||
|
|
|
@ -260,7 +260,7 @@
|
|||
position: relative;
|
||||
border: 1px solid $blue-300;
|
||||
border-radius: $border-radius-default;
|
||||
background-color: $blue-25;
|
||||
background-color: $blue-50;
|
||||
justify-content: center;
|
||||
|
||||
.dismiss-button {
|
||||
|
|
|
@ -779,6 +779,14 @@
|
|||
white-space: normal;
|
||||
width: 100%;
|
||||
|
||||
&.dropdown-menu-user-link {
|
||||
white-space: nowrap;
|
||||
|
||||
.dropdown-menu-user-username {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the text color is not overriden
|
||||
&.text-danger {
|
||||
color: $brand-danger;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// Header
|
||||
|
||||
header.navbar-gitlab-new {
|
||||
background: linear-gradient(to right, $color-900, $color-800);
|
||||
background-color: $color-900;
|
||||
|
||||
.navbar-collapse {
|
||||
color: $color-200;
|
||||
|
@ -126,7 +126,7 @@
|
|||
.search-input-wrap {
|
||||
.search-icon,
|
||||
.clear-icon {
|
||||
color: rgba($color-200, .8);
|
||||
fill: rgba($color-200, .8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@
|
|||
|
||||
.search-input-wrap {
|
||||
.search-icon {
|
||||
color: rgba($color-200, .8);
|
||||
fill: rgba($color-200, .8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ body {
|
|||
@include gitlab-theme($theme-gray-900, $theme-gray-700, $theme-gray-800, $theme-gray-700, $theme-gray-700, $theme-gray-100, $theme-gray-700);
|
||||
|
||||
header.navbar-gitlab-new {
|
||||
background: $theme-gray-100;
|
||||
background-color: $theme-gray-100;
|
||||
box-shadow: 0 2px 0 0 $border-color;
|
||||
|
||||
.logo-text svg {
|
||||
|
@ -242,17 +242,21 @@ body {
|
|||
|
||||
&:hover {
|
||||
background-color: $white-light;
|
||||
box-shadow: inset 0 0 0 1px $blue-100;
|
||||
box-shadow: inset 0 0 0 1px $blue-200;
|
||||
|
||||
.location-badge {
|
||||
box-shadow: inset 0 0 0 1px $blue-100;
|
||||
box-shadow: inset 0 0 0 1px $blue-200;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-input-wrap {
|
||||
.search-icon {
|
||||
color: $theme-gray-200;
|
||||
fill: $theme-gray-200;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
color: $gl-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -109,8 +109,7 @@ header {
|
|||
|
||||
.user-counter {
|
||||
svg {
|
||||
height: 16px;
|
||||
width: 23px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,16 +132,16 @@ header {
|
|||
}
|
||||
|
||||
&.navbar-gitlab-new {
|
||||
.fa-times {
|
||||
.close-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.menu-expanded {
|
||||
.fa-ellipsis-v {
|
||||
.more-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.fa-times {
|
||||
.close-icon {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
}
|
||||
|
||||
svg {
|
||||
&.s8 { @include svg-size(8px); }
|
||||
&.s16 { @include svg-size(16px); }
|
||||
&.s18 { @include svg-size(18px); }
|
||||
&.s24 { @include svg-size(24px); }
|
||||
&.s32 { @include svg-size(32px); }
|
||||
&.s48 { @include svg-size(48px); }
|
||||
|
|
|
@ -142,5 +142,41 @@
|
|||
}
|
||||
|
||||
@mixin green-status-color {
|
||||
@include status-color($green-50, $green-500, $green-700);
|
||||
@include status-color($green-100, $green-500, $green-700);
|
||||
}
|
||||
|
||||
@mixin fade($gradient-direction, $gradient-color) {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
bottom: 12px;
|
||||
width: 43px;
|
||||
height: 30px;
|
||||
transition-duration: .3s;
|
||||
-webkit-transform: translateZ(0);
|
||||
background: linear-gradient(to $gradient-direction, $gradient-color 45%, rgba($gradient-color, 0.4));
|
||||
|
||||
&.scrolling {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition-duration: .3s;
|
||||
}
|
||||
|
||||
.fa {
|
||||
position: relative;
|
||||
top: 5px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin scrolling-links() {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
display: flex;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +1,4 @@
|
|||
@mixin fade($gradient-direction, $gradient-color) {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
bottom: 12px;
|
||||
width: 43px;
|
||||
height: 30px;
|
||||
transition-duration: .3s;
|
||||
-webkit-transform: translateZ(0);
|
||||
background: linear-gradient(to $gradient-direction, $gradient-color 45%, rgba($gradient-color, 0.4));
|
||||
|
||||
&.scrolling {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition-duration: .3s;
|
||||
}
|
||||
|
||||
.fa {
|
||||
position: relative;
|
||||
top: 5px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin scrolling-links() {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
display: flex;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
|
|
|
@ -120,17 +120,24 @@ header.navbar-gitlab-new {
|
|||
.container-fluid {
|
||||
.navbar-toggle {
|
||||
min-width: 45px;
|
||||
padding: 4px $gl-padding;
|
||||
padding: 0 $gl-padding;
|
||||
margin-right: -7px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: currentColor;
|
||||
|
||||
svg {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&.active {
|
||||
color: currentColor;
|
||||
background-color: transparent;
|
||||
|
||||
svg {
|
||||
fill: currentColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,10 +286,6 @@ header.navbar-gitlab-new {
|
|||
}
|
||||
}
|
||||
|
||||
.admin-icon i {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.caret-down {
|
||||
height: 11px;
|
||||
width: 11px;
|
||||
|
@ -295,75 +298,6 @@ header.navbar-gitlab-new {
|
|||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.search {
|
||||
margin: 4px 8px 0;
|
||||
|
||||
form {
|
||||
height: 32px;
|
||||
border: 0;
|
||||
border-radius: $border-radius-default;
|
||||
transition: border-color ease-in-out 0.15s, background-color ease-in-out 0.15s;
|
||||
|
||||
&:hover {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.search-active form {
|
||||
box-shadow: none;
|
||||
|
||||
.search-input {
|
||||
color: $gl-text-color;
|
||||
transition: color ease-in-out 0.15s;
|
||||
}
|
||||
|
||||
.search-input::placeholder {
|
||||
color: $gl-text-color-tertiary;
|
||||
}
|
||||
|
||||
.search-input-wrap {
|
||||
.search-icon,
|
||||
.clear-icon {
|
||||
color: $gl-text-color-tertiary;
|
||||
transition: color ease-in-out 0.15s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-input {
|
||||
color: $white-light;
|
||||
background: none;
|
||||
transition: color ease-in-out 0.15s;
|
||||
}
|
||||
|
||||
.search-input::placeholder {
|
||||
transition: color ease-in-out 0.15s;
|
||||
}
|
||||
|
||||
.location-badge {
|
||||
font-size: 12px;
|
||||
margin: -4px 4px -4px -4px;
|
||||
line-height: 25px;
|
||||
padding: 4px 8px;
|
||||
border-radius: 2px 0 0 2px;
|
||||
height: 32px;
|
||||
transition: border-color ease-in-out 0.15s;
|
||||
}
|
||||
|
||||
&.search-active {
|
||||
.location-badge {
|
||||
background-color: $nav-badge-bg;
|
||||
border-color: $border-color;
|
||||
}
|
||||
|
||||
.search-input-wrap {
|
||||
.clear-icon {
|
||||
color: $white-light;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumbs {
|
||||
display: flex;
|
||||
min-height: 48px;
|
||||
|
@ -375,6 +309,8 @@ header.navbar-gitlab-new {
|
|||
display: flex;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
padding-top: $gl-padding / 2;
|
||||
padding-bottom: $gl-padding / 2;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid $border-color;
|
||||
}
|
||||
|
@ -386,11 +322,6 @@ header.navbar-gitlab-new {
|
|||
align-self: center;
|
||||
color: $gl-text-color-secondary;
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
padding-left: 17px;
|
||||
border-left: 1px solid $gl-text-color-quaternary;
|
||||
}
|
||||
|
||||
.avatar-tile {
|
||||
margin-right: 4px;
|
||||
border: 1px solid $border-color;
|
||||
|
@ -420,6 +351,7 @@ header.navbar-gitlab-new {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding: 2px 0;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 20px;
|
||||
|
@ -455,7 +387,7 @@ header.navbar-gitlab-new {
|
|||
margin: 0;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
line-height: 16px;
|
||||
|
||||
a {
|
||||
color: $gl-text-color;
|
|
@ -56,8 +56,8 @@ $new-sidebar-collapsed-width: 50px;
|
|||
color: $hover-color;
|
||||
|
||||
.settings-avatar {
|
||||
i {
|
||||
color: $hover-color;
|
||||
svg {
|
||||
fill: $hover-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,12 +76,9 @@ $new-sidebar-collapsed-width: 50px;
|
|||
.settings-avatar {
|
||||
background-color: $white-light;
|
||||
|
||||
i {
|
||||
font-size: 20px;
|
||||
width: 100%;
|
||||
color: $gl-text-color-secondary;
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
svg {
|
||||
fill: $gl-text-color-secondary;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,16 +174,16 @@ $new-sidebar-collapsed-width: 50px;
|
|||
.nav-icon-container {
|
||||
display: flex;
|
||||
margin-right: 8px;
|
||||
|
||||
svg {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.fly-out-top-item {
|
||||
display: none;
|
||||
}
|
||||
|
||||
svg {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-sidebar-inner-scroll {
|
||||
|
@ -354,18 +351,22 @@ $new-sidebar-collapsed-width: 50px;
|
|||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
font-size: 20px;
|
||||
svg {
|
||||
fill: $gl-text-color-secondary;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.fa-angle-double-right {
|
||||
.icon-angle-double-right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $border-color;
|
||||
color: $gl-text-color;
|
||||
|
||||
svg {
|
||||
fill: $gl-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,15 +408,16 @@ $new-sidebar-collapsed-width: 50px;
|
|||
|
||||
.toggle-sidebar-button {
|
||||
width: $new-sidebar-collapsed-width - 2px;
|
||||
padding: 16px 18px;
|
||||
padding: 16px;
|
||||
|
||||
.collapse-text,
|
||||
.fa-angle-double-left {
|
||||
.icon-angle-double-left {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.fa-angle-double-right {
|
||||
.icon-angle-double-right {
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -461,6 +463,13 @@ $new-sidebar-collapsed-width: 50px;
|
|||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
+ .breadcrumbs-links {
|
||||
padding-left: 17px;
|
||||
border-left: 1px solid $gl-text-color-quaternary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
|
@ -137,7 +137,7 @@ $well-border: #eee;
|
|||
//##
|
||||
|
||||
$code-color: $red-600;
|
||||
$code-bg: lighten($red-50, 2%);
|
||||
$code-bg: lighten($red-100, 2%);
|
||||
|
||||
$kbd-color: $white-light;
|
||||
$kbd-bg: #333;
|
||||
|
|
|
@ -6,6 +6,8 @@ $gutter_width: 290px;
|
|||
$gutter_inner_width: 250px;
|
||||
$sidebar-transition-duration: .15s;
|
||||
$sidebar-breakpoint: 1024px;
|
||||
$default-transition-duration: .15s;
|
||||
$right-sidebar-transition-duration: .3s;
|
||||
|
||||
/*
|
||||
* Color schema
|
||||
|
@ -27,46 +29,45 @@ $gray-dark: darken($gray-light, $darken-dark-factor);
|
|||
$gray-darker: #eee;
|
||||
$gray-darkest: #c4c4c4;
|
||||
|
||||
$green-25: #f6fcf8;
|
||||
$green-50: #e4f5eb;
|
||||
$green-100: #bae6cc;
|
||||
$green-200: #8dd5aa;
|
||||
$green-300: #5fc488;
|
||||
$green-400: #3cb76f;
|
||||
$green-50: #f1fdf6;
|
||||
$green-100: #dcf5e7;
|
||||
$green-200: #b3e6c8;
|
||||
$green-300: #75d09b;
|
||||
$green-400: #37b96d;
|
||||
$green-500: #1aaa55;
|
||||
$green-600: #168f48;
|
||||
$green-700: #12753a;
|
||||
$green-800: #0e5a2d;
|
||||
$green-900: #0a4020;
|
||||
$green-950: #072b15;
|
||||
|
||||
$blue-25: #f6fafd;
|
||||
$blue-50: #e4eff9;
|
||||
$blue-100: #bcd7f1;
|
||||
$blue-200: #8fbce8;
|
||||
$blue-300: #62a1df;
|
||||
$blue-400: #418cd8;
|
||||
$blue-50: #f6fafe;
|
||||
$blue-100: #e4f0fb;
|
||||
$blue-200: #b8d6f4;
|
||||
$blue-300: #73afea;
|
||||
$blue-400: #2e87e0;
|
||||
$blue-500: #1f78d1;
|
||||
$blue-600: #1b69b6;
|
||||
$blue-700: #17599c;
|
||||
$blue-800: #134a81;
|
||||
$blue-900: #0f3b66;
|
||||
$blue-950: #0a2744;
|
||||
|
||||
$orange-25: #fffcf8;
|
||||
$orange-50: #fff2e1;
|
||||
$orange-100: #fedfb3;
|
||||
$orange-200: #feca81;
|
||||
$orange-300: #fdb44f;
|
||||
$orange-400: #fca429;
|
||||
$orange-50: #fffaf4;
|
||||
$orange-100: #fff1de;
|
||||
$orange-200: #fed69f;
|
||||
$orange-300: #fdbc60;
|
||||
$orange-400: #fca121;
|
||||
$orange-500: #fc9403;
|
||||
$orange-600: #de7e00;
|
||||
$orange-700: #c26700;
|
||||
$orange-800: #a35100;
|
||||
$orange-900: #853b00;
|
||||
$orange-800: #a35200;
|
||||
$orange-900: #853c00;
|
||||
$orange-950: #592800;
|
||||
|
||||
$red-25: #fef7f6;
|
||||
$red-50: #fbe7e4;
|
||||
$red-100: #f4c4bc;
|
||||
$red-200: #ed9d90;
|
||||
$red-50: #fef6f5;
|
||||
$red-100: #fbe5e1;
|
||||
$red-200: #f2b4a9;
|
||||
$red-300: #e67664;
|
||||
$red-400: #e05842;
|
||||
$red-500: #db3b21;
|
||||
|
@ -74,6 +75,7 @@ $red-600: #c0341d;
|
|||
$red-700: #a62d19;
|
||||
$red-800: #8b2615;
|
||||
$red-900: #711e11;
|
||||
$red-950: #4b140b;
|
||||
|
||||
// GitLab themes
|
||||
|
||||
|
@ -184,8 +186,8 @@ $list-text-disabled-color: $gl-text-color-tertiary;
|
|||
$list-border-light: #eee;
|
||||
$list-border: rgba(0, 0, 0, 0.05);
|
||||
$list-text-height: 42px;
|
||||
$list-warning-row-bg: $orange-50;
|
||||
$list-warning-row-border: $orange-100;
|
||||
$list-warning-row-bg: $orange-100;
|
||||
$list-warning-row-border: $orange-200;
|
||||
$list-warning-row-color: $orange-700;
|
||||
|
||||
/*
|
||||
|
@ -214,8 +216,8 @@ $gl-sidebar-padding: 22px;
|
|||
/*
|
||||
* Misc
|
||||
*/
|
||||
$row-hover: $blue-25;
|
||||
$row-hover-border: $blue-100;
|
||||
$row-hover: $blue-50;
|
||||
$row-hover-border: $blue-200;
|
||||
$progress-color: #c0392b;
|
||||
$header-height: 50px;
|
||||
$new-navbar-height: 40px;
|
||||
|
@ -265,8 +267,8 @@ $time-color: #999;
|
|||
$project-member-show-color: #aaa;
|
||||
$gl-promo-color: #aaa;
|
||||
$error-bg: $red-400;
|
||||
$warning-message-bg: $orange-50;
|
||||
$warning-message-border: $orange-100;
|
||||
$warning-message-bg: $orange-100;
|
||||
$warning-message-border: $orange-200;
|
||||
$warning-message-color: $orange-700;
|
||||
$control-group-descr-color: #666;
|
||||
$table-permission-x-bg: #d9edf7;
|
||||
|
@ -451,17 +453,17 @@ $builds-trace-bg: #111;
|
|||
/*
|
||||
* Callout
|
||||
*/
|
||||
$callout-danger-bg: $red-50;
|
||||
$callout-danger-border: $red-100;
|
||||
$callout-danger-bg: $red-100;
|
||||
$callout-danger-border: $red-200;
|
||||
$callout-danger-color: $red-700;
|
||||
$callout-warning-bg: $orange-50;
|
||||
$callout-warning-border: $orange-100;
|
||||
$callout-warning-bg: $orange-100;
|
||||
$callout-warning-border: $orange-200;
|
||||
$callout-warning-color: $orange-700;
|
||||
$callout-info-bg: $blue-50;
|
||||
$callout-info-border: $blue-100;
|
||||
$callout-info-bg: $blue-100;
|
||||
$callout-info-border: $blue-200;
|
||||
$callout-info-color: $blue-700;
|
||||
$callout-success-bg: $green-50;
|
||||
$callout-success-border: $green-100;
|
||||
$callout-success-bg: $green-100;
|
||||
$callout-success-border: $green-200;
|
||||
$callout-success-color: $green-700;
|
||||
|
||||
/*
|
||||
|
|
|
@ -55,6 +55,15 @@
|
|||
|
||||
.boards-app {
|
||||
position: relative;
|
||||
|
||||
@media (min-width: $screen-sm-min) {
|
||||
transition: width $right-sidebar-transition-duration;
|
||||
width: 100%;
|
||||
|
||||
&.is-compact {
|
||||
width: calc(100% - #{$gutter_width});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.boards-app-loading {
|
||||
|
@ -78,11 +87,6 @@
|
|||
height: calc(100vh - 222px);
|
||||
// scss-lint:enable DuplicateProperty
|
||||
min-height: 475px;
|
||||
transition: width .2s;
|
||||
|
||||
&.is-compact {
|
||||
width: calc(100% - 290px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -412,14 +416,6 @@
|
|||
|
||||
.page-with-layout-nav.page-with-sub-nav .issue-boards-sidebar,
|
||||
.page-with-new-sidebar.page-with-sidebar .issue-boards-sidebar {
|
||||
position: absolute;
|
||||
|
||||
&.right-sidebar {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.issuable-sidebar-header {
|
||||
position: relative;
|
||||
}
|
||||
|
@ -457,8 +453,8 @@
|
|||
.right-sidebar.right-sidebar-expanded {
|
||||
&.boards-sidebar-slide-enter-active,
|
||||
&.boards-sidebar-slide-leave-active {
|
||||
transition: width .2s,
|
||||
padding .2s;
|
||||
transition: width $right-sidebar-transition-duration,
|
||||
padding $right-sidebar-transition-duration;
|
||||
}
|
||||
|
||||
&.boards-sidebar-slide-enter,
|
||||
|
|
|
@ -83,7 +83,7 @@ $space-between-cards: 8px;
|
|||
border-top-color: $color-low-score;
|
||||
|
||||
.card-score-big {
|
||||
background-color: $red-25;
|
||||
background-color: $red-50;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ $space-between-cards: 8px;
|
|||
border-top-color: $color-average-score;
|
||||
|
||||
.card-score-big {
|
||||
background-color: $orange-25;
|
||||
background-color: $orange-50;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ $space-between-cards: 8px;
|
|||
border-top-color: $color-high-score;
|
||||
|
||||
.card-score-big {
|
||||
background-color: $green-25;
|
||||
background-color: $green-50;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -451,7 +451,7 @@
|
|||
}
|
||||
|
||||
.files {
|
||||
margin-top: -1px;
|
||||
margin-top: 1px;
|
||||
|
||||
.diff-file:last-child {
|
||||
margin-bottom: 0;
|
||||
|
@ -535,7 +535,6 @@
|
|||
}
|
||||
|
||||
.diff-notes-collapse {
|
||||
position: relative;
|
||||
width: 19px;
|
||||
height: 19px;
|
||||
padding: 0;
|
||||
|
@ -543,11 +542,7 @@
|
|||
z-index: 100;
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-left: -5.5px;
|
||||
margin-top: -5.5px;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
path {
|
||||
|
@ -586,11 +581,6 @@
|
|||
top: 76px;
|
||||
}
|
||||
|
||||
+ .files,
|
||||
+ .alert {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
&:not(.is-stuck) .diff-stats-additions-deletions-collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
@ -605,11 +595,6 @@
|
|||
.inline-parallel-buttons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
+ .files,
|
||||
+ .alert {
|
||||
margin-top: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
.is-confidential {
|
||||
color: $orange-600;
|
||||
background-color: $orange-50;
|
||||
background-color: $orange-100;
|
||||
border-radius: $border-radius-default;
|
||||
padding: 5px;
|
||||
margin: 0 3px 0 -4px;
|
||||
|
@ -223,14 +223,14 @@
|
|||
top: $new-navbar-height;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
transition: width .3s;
|
||||
transition: width $right-sidebar-transition-duration;
|
||||
background: $gray-light;
|
||||
z-index: 200;
|
||||
overflow: hidden;
|
||||
|
||||
.issuable-sidebar {
|
||||
width: calc(100% + 100px);
|
||||
height: calc(100% - #{$new-navbar-height});
|
||||
height: 100%;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
|
|
@ -255,7 +255,7 @@ $colors: (
|
|||
|
||||
&.saved {
|
||||
.editor {
|
||||
border-top: solid 2px $green-200;
|
||||
border-top: solid 2px $green-300;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
|
||||
.confidential-issue-warning {
|
||||
color: $orange-600;
|
||||
background-color: $orange-50;
|
||||
background-color: $orange-100;
|
||||
border-radius: $border-radius-default $border-radius-default 0 0;
|
||||
border: 1px solid $border-gray-normal;
|
||||
border-bottom: none;
|
||||
|
|
|
@ -644,20 +644,20 @@ button.mini-pipeline-graph-dropdown-toggle {
|
|||
|
||||
// Dropdown button animation in mini pipeline graph
|
||||
&.ci-status-icon-success {
|
||||
@include mini-pipeline-graph-color($green-50, $green-500, $green-600);
|
||||
@include mini-pipeline-graph-color($green-100, $green-500, $green-600);
|
||||
}
|
||||
|
||||
&.ci-status-icon-failed {
|
||||
@include mini-pipeline-graph-color($red-50, $red-500, $red-600);
|
||||
@include mini-pipeline-graph-color($red-100, $red-500, $red-600);
|
||||
}
|
||||
|
||||
&.ci-status-icon-pending,
|
||||
&.ci-status-icon-success_with_warnings {
|
||||
@include mini-pipeline-graph-color($orange-50, $orange-500, $orange-600);
|
||||
@include mini-pipeline-graph-color($orange-100, $orange-500, $orange-600);
|
||||
}
|
||||
|
||||
&.ci-status-icon-running {
|
||||
@include mini-pipeline-graph-color($blue-50, $blue-400, $blue-600);
|
||||
@include mini-pipeline-graph-color($blue-100, $blue-400, $blue-600);
|
||||
}
|
||||
|
||||
&.ci-status-icon-canceled,
|
||||
|
|
|
@ -291,7 +291,7 @@ table.u2f-registrations {
|
|||
.bordered-box {
|
||||
border: 1px solid $blue-300;
|
||||
border-radius: $border-radius-default;
|
||||
background-color: $blue-25;
|
||||
background-color: $blue-50;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
@ -379,7 +379,7 @@ table.u2f-registrations {
|
|||
|
||||
.nav-wip {
|
||||
border: 1px solid $blue-500;
|
||||
background: $blue-25;
|
||||
background: $blue-50;
|
||||
padding: $gl-padding;
|
||||
margin-bottom: $gl-padding;
|
||||
|
||||
|
|
|
@ -516,7 +516,7 @@ a.deploy-project-label {
|
|||
text-align: center;
|
||||
width: 169px;
|
||||
|
||||
&:hover,
|
||||
&:hover:not(.disabled),
|
||||
&.forked {
|
||||
background-color: $row-hover;
|
||||
border-color: $row-hover-border;
|
||||
|
@ -543,6 +543,15 @@ a.deploy-project-label {
|
|||
padding-top: $gl-padding;
|
||||
color: $gl-text-color;
|
||||
|
||||
&.disabled {
|
||||
opacity: .3;
|
||||
cursor: not-allowed;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.caption {
|
||||
min-height: 30px;
|
||||
padding: $gl-padding 0;
|
||||
|
|
|
@ -54,6 +54,10 @@
|
|||
border-radius: $border-radius-default;
|
||||
color: $almost-black;
|
||||
|
||||
.code.white pre .hll {
|
||||
background-color: $well-light-border !important;
|
||||
}
|
||||
|
||||
.tree-content-holder {
|
||||
display: flex;
|
||||
min-height: 300px;
|
||||
|
|
|
@ -28,9 +28,7 @@ input[type="checkbox"]:hover {
|
|||
}
|
||||
|
||||
.search {
|
||||
margin-right: 10px;
|
||||
margin-left: 10px;
|
||||
margin-top: ($header-height - 35) / 2;
|
||||
margin: 4px 8px 0;
|
||||
|
||||
form {
|
||||
@extend .form-control;
|
||||
|
@ -38,15 +36,23 @@ input[type="checkbox"]:hover {
|
|||
padding: 4px;
|
||||
width: $search-input-width;
|
||||
line-height: 24px;
|
||||
height: 32px;
|
||||
border: 0;
|
||||
border-radius: $border-radius-default;
|
||||
transition: border-color ease-in-out $default-transition-duration, background-color ease-in-out $default-transition-duration;
|
||||
|
||||
&:hover {
|
||||
border-color: lighten($dropdown-input-focus-border, 20%);
|
||||
box-shadow: 0 0 4px lighten($search-input-focus-shadow-color, 20%);
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.location-text {
|
||||
font-style: normal;
|
||||
.location-badge {
|
||||
font-size: 12px;
|
||||
margin: -4px 4px -4px -4px;
|
||||
line-height: 25px;
|
||||
padding: 4px 8px;
|
||||
border-radius: $border-radius-default 0 0 $border-radius-default;
|
||||
transition: border-color ease-in-out $default-transition-duration;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
|
@ -56,59 +62,36 @@ input[type="checkbox"]:hover {
|
|||
margin-left: 5px;
|
||||
line-height: 25px;
|
||||
width: 98%;
|
||||
color: $white-light;
|
||||
background: none;
|
||||
transition: color ease-in-out $default-transition-duration;
|
||||
}
|
||||
|
||||
.location-badge {
|
||||
line-height: 25px;
|
||||
padding: 0 5px;
|
||||
border-radius: $border-radius-default;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
color: $note-disabled-comment-color;
|
||||
display: inline-block;
|
||||
background-color: $gray-normal;
|
||||
vertical-align: top;
|
||||
cursor: default;
|
||||
.search-input::placeholder {
|
||||
transition: color ease-in-out $default-transition-duration;
|
||||
}
|
||||
|
||||
.search-input-container {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.search-input-wrap {
|
||||
// Fallback if flexbox is not supported
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.search-input-wrap {
|
||||
width: 100%;
|
||||
|
||||
.search-icon,
|
||||
.clear-icon {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 0;
|
||||
color: $location-icon-color;
|
||||
|
||||
&::before {
|
||||
font-family: FontAwesome;
|
||||
font-weight: $gl-font-weight-normal;
|
||||
font-style: normal;
|
||||
}
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
@extend .fa-search;
|
||||
transition: color 0.15s;
|
||||
transition: color $default-transition-duration;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.clear-icon {
|
||||
@extend .fa-times;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -148,19 +131,30 @@ input[type="checkbox"]:hover {
|
|||
form {
|
||||
@extend .form-control:focus;
|
||||
border-color: $dropdown-input-focus-border;
|
||||
box-shadow: 0 0 4px $search-input-focus-shadow-color;
|
||||
box-shadow: none;
|
||||
|
||||
.search-input-wrap {
|
||||
.search-icon,
|
||||
.clear-icon {
|
||||
color: $gl-text-color-tertiary;
|
||||
transition: color ease-in-out $default-transition-duration;
|
||||
}
|
||||
}
|
||||
|
||||
.search-input {
|
||||
color: $gl-text-color;
|
||||
transition: color ease-in-out $default-transition-duration;
|
||||
}
|
||||
|
||||
.search-input::placeholder {
|
||||
color: $gl-text-color-tertiary;
|
||||
}
|
||||
}
|
||||
|
||||
.location-badge {
|
||||
transition: all 0.15s;
|
||||
background-color: $location-badge-active-bg;
|
||||
color: $white-light;
|
||||
}
|
||||
|
||||
.search-input-wrap {
|
||||
i {
|
||||
color: $layout-link-gray;
|
||||
}
|
||||
transition: all $default-transition-duration;
|
||||
background-color: $nav-badge-bg;
|
||||
border-color: $border-color;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
}
|
||||
|
||||
&.ci-failed {
|
||||
@include status-color($red-50, $red-500, $red-600);
|
||||
@include status-color($red-100, $red-500, $red-600);
|
||||
}
|
||||
|
||||
&.ci-success {
|
||||
|
@ -39,12 +39,12 @@
|
|||
&.ci-pending,
|
||||
&.ci-failed_with_warnings,
|
||||
&.ci-success_with_warnings {
|
||||
@include status-color($orange-50, $orange-500, $orange-700);
|
||||
@include status-color($orange-100, $orange-500, $orange-700);
|
||||
}
|
||||
|
||||
&.ci-info,
|
||||
&.ci-running {
|
||||
@include status-color($blue-50, $blue-500, $blue-600);
|
||||
@include status-color($blue-100, $blue-500, $blue-600);
|
||||
}
|
||||
|
||||
&.ci-created,
|
||||
|
|
|
@ -15,3 +15,9 @@
|
|||
-ms-animation: none !important;
|
||||
animation: none !important;
|
||||
}
|
||||
|
||||
// Disable sticky changes bar for tests
|
||||
.diff-files-changed {
|
||||
position: relative !important;
|
||||
top: 0 !important;
|
||||
}
|
||||
|
|
|
@ -22,8 +22,7 @@ class Admin::ApplicationsController < Admin::ApplicationController
|
|||
@application = Doorkeeper::Application.new(application_params)
|
||||
|
||||
if @application.save
|
||||
flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create])
|
||||
redirect_to admin_application_url(@application)
|
||||
redirect_to_admin_page
|
||||
else
|
||||
render :new
|
||||
end
|
||||
|
@ -42,6 +41,13 @@ class Admin::ApplicationsController < Admin::ApplicationController
|
|||
redirect_to admin_applications_url, status: 302, notice: 'Application was successfully destroyed.'
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def redirect_to_admin_page
|
||||
flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create])
|
||||
redirect_to admin_application_url(@application)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_application
|
||||
|
|
|
@ -128,7 +128,7 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
respond_to do |format|
|
||||
result = Users::UpdateService.new(user, user_params_with_pass).execute do |user|
|
||||
result = Users::UpdateService.new(current_user, user_params_with_pass.merge(user: user)).execute do |user|
|
||||
user.skip_reconfirmation!
|
||||
end
|
||||
|
||||
|
@ -155,7 +155,7 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
|
||||
def remove_email
|
||||
email = user.emails.find(params[:email_id])
|
||||
success = Emails::DestroyService.new(user, email: email.email).execute
|
||||
success = Emails::DestroyService.new(current_user, user: user, email: email.email).execute
|
||||
|
||||
respond_to do |format|
|
||||
if success
|
||||
|
@ -219,7 +219,7 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def update_user(&block)
|
||||
result = Users::UpdateService.new(user).execute(&block)
|
||||
result = Users::UpdateService.new(current_user, user: user).execute(&block)
|
||||
|
||||
result[:status] == :success
|
||||
end
|
||||
|
|
|
@ -25,6 +25,8 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
around_action :set_locale
|
||||
|
||||
after_action :set_page_title_header, if: -> { request.format == :json }
|
||||
|
||||
protect_from_forgery with: :exception
|
||||
|
||||
helper_method :can?, :current_application_settings
|
||||
|
@ -335,4 +337,9 @@ class ApplicationController < ActionController::Base
|
|||
sign_in user, store: false
|
||||
end
|
||||
end
|
||||
|
||||
def set_page_title_header
|
||||
# Per https://tools.ietf.org/html/rfc5987, headers need to be ISO-8859-1, not UTF-8
|
||||
response.headers['Page-Title'] = page_title('GitLab').encode('ISO-8859-1')
|
||||
end
|
||||
end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue