Commit a0ac2d93 authored by Valery Sizov's avatar Valery Sizov

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into ff_port_from_ee

parents 284185a3 42d7d355
...@@ -404,6 +404,7 @@ docs lint: ...@@ -404,6 +404,7 @@ docs lint:
before_script: [] before_script: []
script: script:
- scripts/lint-doc.sh - scripts/lint-doc.sh
- scripts/lint-changelog-yaml
- mv doc/ /nanoc/content/ - mv doc/ /nanoc/content/
- cd /nanoc - cd /nanoc
# Build HTML from Markdown # Build HTML from Markdown
......
...@@ -85,6 +85,8 @@ entry. ...@@ -85,6 +85,8 @@ entry.
- [FIXED] Fixed merge request changes bar jumping. - [FIXED] Fixed merge request changes bar jumping.
- [FIXED] Improve migrations using triggers. - [FIXED] Improve migrations using triggers.
- [FIXED] Fix ConvDev Index nav item and Monitoring submenu regression. - [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 - [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] 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) - [CHANGED] Use full path of project's avatar in webhooks. !13649 (Vitaliy @blackst0ne Klachkov)
......
...@@ -49,7 +49,7 @@ _This notice should stay as the first item in the CONTRIBUTING.md file._ ...@@ -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 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. 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 GitLab comes into two flavors, GitLab Community Edition (CE) our free and open
source edition, and GitLab Enterprise Edition (EE) which is our commercial source edition, and GitLab Enterprise Edition (EE) which is our commercial
...@@ -101,7 +101,7 @@ the remaining issues on the GitHub issue tracker. ...@@ -101,7 +101,7 @@ the remaining issues on the GitHub issue tracker.
## I want to contribute! ## I want to contribute!
If you want to contribute to GitLab, but are not sure where to start, 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 These issues will be of reasonable size and challenge, for anyone to start
contributing to GitLab. contributing to GitLab.
...@@ -209,8 +209,7 @@ We add the ~"Accepting Merge Requests" label to: ...@@ -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 - Low priority ~bug issues (i.e. we do not add it to the bugs that we want to
solve in the ~"Next Patch Release") solve in the ~"Next Patch Release")
- Small ~"feature proposal" that do not need ~UX / ~"Product work", or for which - Small ~"feature proposal"
the ~UX / ~"Product work" is already done
- Small ~"technical debt" issues - Small ~"technical debt" issues
After adding the ~"Accepting Merge Requests" label, we try to estimate the After adding the ~"Accepting Merge Requests" label, we try to estimate the
...@@ -223,6 +222,17 @@ know how difficult the issue is. Additionally: ...@@ -223,6 +222,17 @@ know how difficult the issue is. Additionally:
- We encourage people that have never contributed to any open source project to - 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] 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 [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 [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
......
...@@ -398,7 +398,7 @@ group :ed25519 do ...@@ -398,7 +398,7 @@ group :ed25519 do
end end
# Gitaly GRPC client # 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 gem 'toml-rb', '~> 0.3.15', require: false
......
...@@ -275,7 +275,7 @@ GEM ...@@ -275,7 +275,7 @@ GEM
po_to_json (>= 1.0.0) po_to_json (>= 1.0.0)
rails (>= 3.2.0) rails (>= 3.2.0)
gherkin-ruby (0.3.2) gherkin-ruby (0.3.2)
gitaly-proto (0.33.0) gitaly-proto (0.38.0)
google-protobuf (~> 3.1) google-protobuf (~> 3.1)
grpc (~> 1.0) grpc (~> 1.0)
github-linguist (4.7.6) github-linguist (4.7.6)
...@@ -1025,7 +1025,7 @@ DEPENDENCIES ...@@ -1025,7 +1025,7 @@ DEPENDENCIES
gettext (~> 3.2.2) gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0) gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.2.0) gettext_i18n_rails_js (~> 1.2.0)
gitaly-proto (~> 0.33.0) gitaly-proto (~> 0.38.0)
github-linguist (~> 4.7.0) github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1) gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-markup (~> 1.6.2) gitlab-markup (~> 1.6.2)
......
{"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"]}
\ No newline at end of file \ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -167,7 +167,7 @@ window.Build = (function () { ...@@ -167,7 +167,7 @@ window.Build = (function () {
Build.prototype.getBuildTrace = function () { Build.prototype.getBuildTrace = function () {
return $.ajax({ return $.ajax({
url: `${this.pageUrl}/trace.json`, url: `${this.pageUrl}/trace.json`,
data: this.state, data: { state: this.state },
}) })
.done((log) => { .done((log) => {
setCiStatusFavicon(`${this.pageUrl}/status.json`); setCiStatusFavicon(`${this.pageUrl}/status.json`);
......
<script> <script>
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; 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 { export default {
props: { props: {
...@@ -8,6 +10,8 @@ ...@@ -8,6 +10,8 @@
}, },
components: { components: {
userAvatarImage, userAvatarImage,
limitWarning,
totalTime,
}, },
}; };
</script> </script>
......
<script> <script>
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; 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 { export default {
props: { props: {
...@@ -8,6 +10,8 @@ ...@@ -8,6 +10,8 @@
}, },
components: { components: {
userAvatarImage, userAvatarImage,
limitWarning,
totalTime,
}, },
}; };
</script> </script>
......
<script> <script>
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import iconCommit from '../svg/icon_commit.svg'; import iconCommit from '../svg/icon_commit.svg';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
export default { export default {
props: { props: {
items: Array, items: Array,
stage: Object, stage: Object,
}, },
components: { components: {
userAvatarImage, userAvatarImage,
totalTime,
limitWarning,
}, },
computed: { computed: {
iconCommit() { iconCommit() {
return iconCommit; return iconCommit;
}, },
}, },
}; };
</script> </script>
<template> <template>
<div> <div>
......
<script> <script>
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; 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 { export default {
props: { props: {
...@@ -8,6 +10,8 @@ ...@@ -8,6 +10,8 @@
}, },
components: { components: {
userAvatarImage, userAvatarImage,
totalTime,
limitWarning,
}, },
}; };
</script> </script>
......
<script> <script>
import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue'; import userAvatarImage from '../../vue_shared/components/user_avatar/user_avatar_image.vue';
import iconBranch from '../svg/icon_branch.svg'; import iconBranch from '../svg/icon_branch.svg';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
export default { export default {
props: { props: {
...@@ -9,6 +11,8 @@ ...@@ -9,6 +11,8 @@
}, },
components: { components: {
userAvatarImage, userAvatarImage,
totalTime,
limitWarning,
}, },
computed: { computed: {
iconBranch() { iconBranch() {
......
<script> <script>
import iconBuildStatus from '../svg/icon_build_status.svg'; import iconBuildStatus from '../svg/icon_build_status.svg';
import iconBranch from '../svg/icon_branch.svg'; import iconBranch from '../svg/icon_branch.svg';
import limitWarning from './limit_warning_component.vue';
import totalTime from './total_time_component.vue';
export default { export default {
props: { props: {
items: Array, items: Array,
stage: Object, stage: Object,
}, },
components: {
totalTime,
limitWarning,
},
computed: { computed: {
iconBuildStatus() { iconBuildStatus() {
return iconBuildStatus; return iconBuildStatus;
...@@ -15,7 +21,7 @@ export default { ...@@ -15,7 +21,7 @@ export default {
return iconBranch; return iconBranch;
}, },
}, },
}; };
</script> </script>
<template> <template>
<div> <div>
......
...@@ -3,14 +3,12 @@ ...@@ -3,14 +3,12 @@
import Vue from 'vue'; import Vue from 'vue';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import Translate from '../vue_shared/translate'; import Translate from '../vue_shared/translate';
import limitWarningComponent from './components/limit_warning_component.vue';
import stageCodeComponent from './components/stage_code_component.vue'; import stageCodeComponent from './components/stage_code_component.vue';
import stagePlanComponent from './components/stage_plan_component.vue'; import stagePlanComponent from './components/stage_plan_component.vue';
import stageComponent from './components/stage_component.vue'; import stageComponent from './components/stage_component.vue';
import stageReviewComponent from './components/stage_review_component.vue'; import stageReviewComponent from './components/stage_review_component.vue';
import stageStagingComponent from './components/stage_staging_component.vue'; import stageStagingComponent from './components/stage_staging_component.vue';
import stageTestComponent from './components/stage_test_component.vue'; import stageTestComponent from './components/stage_test_component.vue';
import totalTime from './components/total_time_component.vue';
import CycleAnalyticsService from './cycle_analytics_service'; import CycleAnalyticsService from './cycle_analytics_service';
import CycleAnalyticsStore from './cycle_analytics_store'; import CycleAnalyticsStore from './cycle_analytics_store';
...@@ -133,8 +131,4 @@ $(() => { ...@@ -133,8 +131,4 @@ $(() => {
}, },
}, },
}); });
// Register global components
Vue.component('limit-warning', limitWarningComponent);
Vue.component('total-time', totalTime);
}); });
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
/* global NotificationsDropdown */ /* global NotificationsDropdown */
/* global GroupAvatar */ /* global GroupAvatar */
/* global LineHighlighter */ /* global LineHighlighter */
/* global ProjectFork */
/* global BuildArtifacts */ /* global BuildArtifacts */
/* global GroupsSelect */ /* global GroupsSelect */
/* global Search */ /* global Search */
...@@ -476,7 +475,9 @@ import { ajaxGet, convertPermissionToBoolean } from './lib/utils/common_utils'; ...@@ -476,7 +475,9 @@ import { ajaxGet, convertPermissionToBoolean } from './lib/utils/common_utils';
shortcut_handler = true; shortcut_handler = true;
break; break;
case 'projects:forks:new': case 'projects:forks:new':
new ProjectFork(); import(/* webpackChunkName: 'project_fork' */ './project_fork')
.then(fork => fork.default())
.catch(() => {});
break; break;
case 'projects:artifacts:browse': case 'projects:artifacts:browse':
new ShortcutsNavigation(); new ShortcutsNavigation();
......
...@@ -67,10 +67,13 @@ const PARTICIPANTS_ROW_COUNT = 7; ...@@ -67,10 +67,13 @@ const PARTICIPANTS_ROW_COUNT = 7;
originalText = $(this).data("original-text"); originalText = $(this).data("original-text");
if (currentText === originalText) { if (currentText === originalText) {
$(this).text(lessText); $(this).text(lessText);
if (gl.lazyLoader) gl.lazyLoader.loadCheck();
} else { } else {
$(this).text(originalText); $(this).text(originalText);
} }
return $(".js-participants-hidden").toggle();
$(".js-participants-hidden").toggle();
}; };
return IssuableContext; return IssuableContext;
......
...@@ -71,6 +71,7 @@ export const handleLocationHash = () => { ...@@ -71,6 +71,7 @@ export const handleLocationHash = () => {
// This is required to handle non-unicode characters in hash // This is required to handle non-unicode characters in hash
hash = decodeURIComponent(hash); hash = decodeURIComponent(hash);
const target = document.getElementById(hash) || document.getElementById(`user-content-${hash}`);
const fixedTabs = document.querySelector('.js-tabs-affix'); const fixedTabs = document.querySelector('.js-tabs-affix');
const fixedDiffStats = document.querySelector('.js-diff-files-changed.is-stuck'); const fixedDiffStats = document.querySelector('.js-diff-files-changed.is-stuck');
const fixedNav = document.querySelector('.navbar-gitlab'); const fixedNav = document.querySelector('.navbar-gitlab');
...@@ -78,15 +79,10 @@ export const handleLocationHash = () => { ...@@ -78,15 +79,10 @@ export const handleLocationHash = () => {
let adjustment = 0; let adjustment = 0;
if (fixedNav) adjustment -= fixedNav.offsetHeight; 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) { if (target && target.scrollIntoView) {
target.scrollIntoView(true); target.scrollIntoView(true);
window.scrollBy(0, adjustment);
} }
} else {
// only adjust for fixedTabs when not targeting user-generated content
if (fixedTabs) { if (fixedTabs) {
adjustment -= fixedTabs.offsetHeight; adjustment -= fixedTabs.offsetHeight;
} }
...@@ -96,7 +92,6 @@ export const handleLocationHash = () => { ...@@ -96,7 +92,6 @@ export const handleLocationHash = () => {
} }
window.scrollBy(0, adjustment); window.scrollBy(0, adjustment);
}
}; };
// Check if element scrolled into viewport from above or below // Check if element scrolled into viewport from above or below
......
...@@ -124,7 +124,6 @@ import './preview_markdown'; ...@@ -124,7 +124,6 @@ import './preview_markdown';
import './project'; import './project';
import './project_avatar'; import './project_avatar';
import './project_find_file'; import './project_find_file';
import './project_fork';
import './project_import'; import './project_import';
import './project_label_subscription'; import './project_label_subscription';
import './project_new'; import './project_new';
......
...@@ -28,8 +28,7 @@ ...@@ -28,8 +28,7 @@
popoverOptions() { popoverOptions() {
return { return {
html: true, html: true,
delay: { hide: 600 }, trigger: 'focus',
trigger: 'hover',
placement: 'top', placement: 'top',
title: '<div class="autodevops-title">This pipeline makes use of a predefined CI/CD configuration enabled by <b>Auto DevOps.</b></div>', 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>`, content: `<a class="autodevops-link" href="${this.autoDevopsHelpPath}" target="_blank" rel="noopener noreferrer nofollow">Learn more about Auto DevOps</a>`,
...@@ -75,6 +74,7 @@ ...@@ -75,6 +74,7 @@
</span> </span>
<a <a
v-if="pipeline.flags.auto_devops" v-if="pipeline.flags.auto_devops"
tabindex="0"
class="js-pipeline-url-autodevops label label-info autodevops-badge" class="js-pipeline-url-autodevops label label-info autodevops-badge"
v-popover="popoverOptions" v-popover="popoverOptions"
role="button"> role="button">
......
/* eslint-disable func-names, space-before-function-paren, wrap-iife, prefer-arrow-callback, max-len */ export default () => {
(function() { $('.fork-thumbnail a').on('click', function forkThumbnailClicked() {
this.ProjectFork = (function() { if ($(this).hasClass('disabled')) return false;
function ProjectFork() {
$('.fork-thumbnail a').on('click', function() {
$('.fork-namespaces').hide(); $('.fork-namespaces').hide();
return $('.save-project-loader').show(); return $('.save-project-loader').show();
}); });
} };
return ProjectFork;
})();
}).call(window);
...@@ -19,7 +19,7 @@ export default class ProjectsService { ...@@ -19,7 +19,7 @@ export default class ProjectsService {
getSearchedProjects(searchQuery) { getSearchedProjects(searchQuery) {
return this.projectsPath.get({ return this.projectsPath.get({
simple: false, simple: true,
per_page: 20, per_page: 20,
membership: !!gon.current_user_id, membership: !!gon.current_user_id,
order_by: 'last_activity_at', order_by: 'last_activity_at',
......
...@@ -37,7 +37,7 @@ export default { ...@@ -37,7 +37,7 @@ export default {
content: f.newContent, content: f.newContent,
})); }));
const payload = { const payload = {
branch: Store.targetBranch, branch: Store.currentBranch,
commit_message: commitMessage, commit_message: commitMessage,
actions, actions,
}; };
...@@ -105,7 +105,7 @@ export default { ...@@ -105,7 +105,7 @@ export default {
</label> </label>
<div class="col-md-6"> <div class="col-md-6">
<span class="help-block"> <span class="help-block">
{{targetBranch}} {{currentBranch}}
</span> </span>
</div> </div>
</div> </div>
......
...@@ -26,16 +26,6 @@ export default { ...@@ -26,16 +26,6 @@ export default {
this.editMode = !this.editMode; this.editMode = !this.editMode;
Store.toggleBlobView(); Store.toggleBlobView();
}, },
toggleProjectRefsForm() {
$('.project-refs-form').toggleClass('disabled', this.editMode);
$('.js-tree-ref-target-holder').toggle(this.editMode);
},
},
watch: {
editMode() {
this.toggleProjectRefsForm();
},
}, },
}; };
</script> </script>
......
...@@ -95,7 +95,7 @@ export default RepoFile; ...@@ -95,7 +95,7 @@ export default RepoFile;
</div> </div>
</td> </td>
<td class="hidden-xs"> <td class="hidden-xs text-right">
<span <span
class="commit-update" class="commit-update"
:title="tooltipTitle(file.lastCommitUpdate)"> :title="tooltipTitle(file.lastCommitUpdate)">
......
...@@ -75,7 +75,7 @@ export default { ...@@ -75,7 +75,7 @@ export default {
<tr> <tr>
<th class="name">Name</th> <th class="name">Name</th>
<th class="hidden-sm hidden-xs last-commit">Last Commit</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> </tr>
</thead> </thead>
<tbody> <tbody>
......
...@@ -58,13 +58,13 @@ const RepoHelper = { ...@@ -58,13 +58,13 @@ const RepoHelper = {
return langs.find(lang => lang.extensions && lang.extensions.indexOf(`.${ext}`) > -1); return langs.find(lang => lang.extensions && lang.extensions.indexOf(`.${ext}`) > -1);
}, },
setDirectoryOpen(tree) { setDirectoryOpen(tree, title) {
const file = tree; const file = tree;
if (!file) return undefined; if (!file) return undefined;
file.opened = true; file.opened = true;
file.icon = 'fa-folder-open'; file.icon = 'fa-folder-open';
RepoHelper.updateHistoryEntry(file.url, file.name); RepoHelper.updateHistoryEntry(file.url, title);
return file; return file;
}, },
...@@ -135,6 +135,8 @@ const RepoHelper = { ...@@ -135,6 +135,8 @@ const RepoHelper = {
return Service.getContent() return Service.getContent()
.then((response) => { .then((response) => {
const data = response.data; const data = response.data;
if (response.headers && response.headers['page-title']) data.pageTitle = response.headers['page-title'];
Store.isTree = RepoHelper.isTree(data); Store.isTree = RepoHelper.isTree(data);
if (!Store.isTree) { if (!Store.isTree) {
if (!file) file = data; if (!file) file = data;
...@@ -168,7 +170,7 @@ const RepoHelper = { ...@@ -168,7 +170,7 @@ const RepoHelper = {
} else { } else {
// it's a tree // it's a tree
if (!file) Store.isRoot = RepoHelper.isRoot(Service.url); 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); const newDirectory = RepoHelper.dataToListOfFiles(data);
Store.addFilesToDirectory(file, Store.files, newDirectory); Store.addFilesToDirectory(file, Store.files, newDirectory);
Store.prevURL = Service.blobURLtoParentTree(Service.url); Store.prevURL = Service.blobURLtoParentTree(Service.url);
...@@ -255,7 +257,7 @@ const RepoHelper = { ...@@ -255,7 +257,7 @@ const RepoHelper = {
history.pushState({ key: RepoHelper.key }, '', url); history.pushState({ key: RepoHelper.key }, '', url);
if (title) { if (title) {
document.title = `${title} · GitLab`; document.title = title;
} }
}, },
......
...@@ -11,10 +11,6 @@ function initDropdowns() { ...@@ -11,10 +11,6 @@ function initDropdowns() {
} }
function addEventsForNonVueEls() { function addEventsForNonVueEls() {
$(document).on('change', '.dropdown', () => {
Store.targetBranch = $('.project-refs-target-form input[name="ref"]').val();
});
window.onbeforeunload = function confirmUnload(e) { window.onbeforeunload = function confirmUnload(e) {
const hasChanged = Store.openedFiles const hasChanged = Store.openedFiles
.some(file => file.changed); .some(file => file.changed);
......
...@@ -32,7 +32,6 @@ const RepoStore = { ...@@ -32,7 +32,6 @@ const RepoStore = {
isCommitable: false, isCommitable: false,
binary: false, binary: false,
currentBranch: '', currentBranch: '',
targetBranch: 'new-branch',
commitMessage: '', commitMessage: '',
binaryTypes: { binaryTypes: {
png: false, png: false,
...@@ -84,7 +83,7 @@ const RepoStore = { ...@@ -84,7 +83,7 @@ const RepoStore = {
}).catch(Helper.loadingError); }).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; RepoStore.binary = file.binary;
}, },
......
...@@ -29,7 +29,11 @@ import Cookies from 'js-cookie'; ...@@ -29,7 +29,11 @@ import Cookies from 'js-cookie';
$('.dropdown').on('loading.gl.dropdown', this.sidebarDropdownLoading); $('.dropdown').on('loading.gl.dropdown', this.sidebarDropdownLoading);
$('.dropdown').on('loaded.gl.dropdown', this.sidebarDropdownLoaded); $('.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; var $allGutterToggleIcons, $this, $thisIcon;
e.preventDefault(); e.preventDefault();
$this = $(this); $this = $(this);
...@@ -47,10 +51,8 @@ import Cookies from 'js-cookie'; ...@@ -47,10 +51,8 @@ import Cookies from 'js-cookie';
if (gl.lazyLoader) gl.lazyLoader.loadCheck(); if (gl.lazyLoader) gl.lazyLoader.loadCheck();
} }
if (!triggered) { 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) { Sidebar.prototype.toggleTodo = function(e) {
......
...@@ -287,6 +287,7 @@ import { isInGroupsPage, isInProjectPage, getGroupSlug, getProjectSlug } from '. ...@@ -287,6 +287,7 @@ import { isInGroupsPage, isInProjectPage, getGroupSlug, getProjectSlug } from '.
onClearInputClick(e) { onClearInputClick(e) {
e.preventDefault(); e.preventDefault();
this.wrap.toggleClass('has-value', !!e.target.value);
return this.searchInput.val('').focus(); return this.searchInput.val('').focus();
} }
......
...@@ -126,7 +126,7 @@ ...@@ -126,7 +126,7 @@
.search-input-wrap { .search-input-wrap {
.search-icon, .search-icon,
.clear-icon { .clear-icon {
color: rgba($color-200, .8); fill: rgba($color-200, .8);
} }
} }
...@@ -141,7 +141,7 @@ ...@@ -141,7 +141,7 @@
.search-input-wrap { .search-input-wrap {
.search-icon { .search-icon {
color: rgba($color-200, .8); fill: rgba($color-200, .8);
} }
} }
} }
...@@ -252,7 +252,7 @@ body { ...@@ -252,7 +252,7 @@ body {
.search-input-wrap { .search-input-wrap {
.search-icon { .search-icon {
color: $theme-gray-200; fill: $theme-gray-200;
} }
.search-input { .search-input {
......
...@@ -109,8 +109,7 @@ header { ...@@ -109,8 +109,7 @@ header {
.user-counter { .user-counter {
svg { svg {
height: 16px; margin-right: 3px;
width: 23px;
} }
} }
...@@ -133,16 +132,16 @@ header { ...@@ -133,16 +132,16 @@ header {
} }
&.navbar-gitlab-new { &.navbar-gitlab-new {
.fa-times { .close-icon {
display: none; display: none;
} }
.menu-expanded { .menu-expanded {
.fa-ellipsis-v { .more-icon {
display: none; display: none;
} }
.fa-times { .close-icon {
display: block; display: block;
} }
} }
......
...@@ -27,7 +27,9 @@ ...@@ -27,7 +27,9 @@
} }
svg { svg {
&.s8 { @include svg-size(8px); }
&.s16 { @include svg-size(16px); } &.s16 { @include svg-size(16px); }
&.s18 { @include svg-size(18px); }
&.s24 { @include svg-size(24px); } &.s24 { @include svg-size(24px); }
&.s32 { @include svg-size(32px); } &.s32 { @include svg-size(32px); }
&.s48 { @include svg-size(48px); } &.s48 { @include svg-size(48px); }
......
...@@ -120,17 +120,24 @@ header.navbar-gitlab-new { ...@@ -120,17 +120,24 @@ header.navbar-gitlab-new {
.container-fluid { .container-fluid {
.navbar-toggle { .navbar-toggle {
min-width: 45px; min-width: 45px;
padding: 4px $gl-padding; padding: 0 $gl-padding;
margin-right: -7px; margin-right: -7px;
font-size: 14px;
text-align: center; text-align: center;
color: currentColor; color: currentColor;
svg {
fill: currentColor;
}
&:hover, &:hover,
&:focus, &:focus,
&.active { &.active {
color: currentColor; color: currentColor;
background-color: transparent; background-color: transparent;
svg {
fill: currentColor;
}
} }
} }
...@@ -279,10 +286,6 @@ header.navbar-gitlab-new { ...@@ -279,10 +286,6 @@ header.navbar-gitlab-new {
} }
} }
.admin-icon i {
font-size: 18px;
}
.caret-down { .caret-down {
height: 11px; height: 11px;
width: 11px; width: 11px;
......
...@@ -56,8 +56,8 @@ $new-sidebar-collapsed-width: 50px; ...@@ -56,8 +56,8 @@ $new-sidebar-collapsed-width: 50px;
color: $hover-color; color: $hover-color;
.settings-avatar { .settings-avatar {
i { svg {
color: $hover-color; fill: $hover-color;
} }
} }
} }
...@@ -76,12 +76,9 @@ $new-sidebar-collapsed-width: 50px; ...@@ -76,12 +76,9 @@ $new-sidebar-collapsed-width: 50px;
.settings-avatar { .settings-avatar {
background-color: $white-light; background-color: $white-light;
i { svg {
font-size: 20px; fill: $gl-text-color-secondary;
width: 100%; margin: auto;
color: $gl-text-color-secondary;
text-align: center;
align-self: center;
} }
} }
...@@ -177,16 +174,16 @@ $new-sidebar-collapsed-width: 50px; ...@@ -177,16 +174,16 @@ $new-sidebar-collapsed-width: 50px;
.nav-icon-container { .nav-icon-container {
display: flex; display: flex;
margin-right: 8px; margin-right: 8px;
svg {
height: 16px;
width: 16px;
}
} }
.fly-out-top-item { .fly-out-top-item {
display: none; display: none;
} }
svg {
height: 16px;
width: 16px;
}
} }
.nav-sidebar-inner-scroll { .nav-sidebar-inner-scroll {
...@@ -354,18 +351,22 @@ $new-sidebar-collapsed-width: 50px; ...@@ -354,18 +351,22 @@ $new-sidebar-collapsed-width: 50px;
display: flex; display: flex;
align-items: center; align-items: center;
i { svg {
font-size: 20px; fill: $gl-text-color-secondary;
margin-right: 8px; margin-right: 8px;
} }
.fa-angle-double-right { .icon-angle-double-right {
display: none; display: none;
} }
&:hover { &:hover {
background-color: $border-color; background-color: $border-color;
color: $gl-text-color; color: $gl-text-color;
svg {
fill: $gl-text-color;
}
} }
} }
...@@ -407,15 +408,16 @@ $new-sidebar-collapsed-width: 50px; ...@@ -407,15 +408,16 @@ $new-sidebar-collapsed-width: 50px;
.toggle-sidebar-button { .toggle-sidebar-button {
width: $new-sidebar-collapsed-width - 2px; width: $new-sidebar-collapsed-width - 2px;
padding: 16px 18px; padding: 16px;
.collapse-text, .collapse-text,
.fa-angle-double-left { .icon-angle-double-left {
display: none; display: none;
} }
.fa-angle-double-right { .icon-angle-double-right {
display: block; display: block;
margin: 0;
} }
} }
} }
......
...@@ -516,7 +516,7 @@ a.deploy-project-label { ...@@ -516,7 +516,7 @@ a.deploy-project-label {
text-align: center; text-align: center;
width: 169px; width: 169px;
&:hover, &:hover:not(.disabled),
&.forked { &.forked {
background-color: $row-hover; background-color: $row-hover;
border-color: $row-hover-border; border-color: $row-hover-border;
...@@ -543,6 +543,15 @@ a.deploy-project-label { ...@@ -543,6 +543,15 @@ a.deploy-project-label {
padding-top: $gl-padding; padding-top: $gl-padding;
color: $gl-text-color; color: $gl-text-color;
&.disabled {
opacity: .3;
cursor: not-allowed;
&:hover {
text-decoration: none;
}
}
.caption { .caption {
min-height: 30px; min-height: 30px;
padding: $gl-padding 0; padding: $gl-padding 0;
......
...@@ -81,17 +81,10 @@ input[type="checkbox"]:hover { ...@@ -81,17 +81,10 @@ input[type="checkbox"]:hover {
.clear-icon { .clear-icon {
position: absolute; position: absolute;
right: 5px; right: 5px;
top: 0; top: 4px;
&::before {
font-family: FontAwesome;
font-weight: $gl-font-weight-normal;
font-style: normal;
}
} }
.search-icon { .search-icon {
@extend .fa-search;
transition: color $default-transition-duration; transition: color $default-transition-duration;
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
...@@ -99,7 +92,6 @@ input[type="checkbox"]:hover { ...@@ -99,7 +92,6 @@ input[type="checkbox"]:hover {
} }
.clear-icon { .clear-icon {
@extend .fa-times;
display: none; display: none;
} }
......
...@@ -25,6 +25,8 @@ class ApplicationController < ActionController::Base ...@@ -25,6 +25,8 @@ class ApplicationController < ActionController::Base
around_action :set_locale around_action :set_locale
after_action :set_page_title_header, if: -> { request.format == :json }
protect_from_forgery with: :exception protect_from_forgery with: :exception
helper_method :can?, :current_application_settings helper_method :can?, :current_application_settings
...@@ -335,4 +337,9 @@ class ApplicationController < ActionController::Base ...@@ -335,4 +337,9 @@ class ApplicationController < ActionController::Base
sign_in user, store: false sign_in user, store: false
end end
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 end
...@@ -41,6 +41,8 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -41,6 +41,8 @@ class Projects::BlobController < Projects::ApplicationController
end end
format.json do format.json do
page_title @blob.path, @ref, @project.name_with_namespace
show_json show_json
end end
end end
......
...@@ -35,6 +35,8 @@ class Projects::TreeController < Projects::ApplicationController ...@@ -35,6 +35,8 @@ class Projects::TreeController < Projects::ApplicationController
end end
format.json do format.json do
page_title @path.presence || _("Files"), @ref, @project.name_with_namespace
# n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/38261 # n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/38261
Gitlab::GitalyClient.allow_n_plus_1_calls do Gitlab::GitalyClient.allow_n_plus_1_calls do
render json: TreeSerializer.new(project: @project, repository: @repository, ref: @ref).represent(@tree) render json: TreeSerializer.new(project: @project, repository: @repository, ref: @ref).represent(@tree)
......
...@@ -10,12 +10,8 @@ module BreadcrumbsHelper ...@@ -10,12 +10,8 @@ module BreadcrumbsHelper
def breadcrumb_title_link def breadcrumb_title_link
return @breadcrumb_link if @breadcrumb_link return @breadcrumb_link if @breadcrumb_link
if controller.available_action?(:index)
url_for(action: "index")
else
request.path request.path
end end
end
def breadcrumb_title(title) def breadcrumb_title(title)
return if defined?(@breadcrumb_title) return if defined?(@breadcrumb_title)
...@@ -25,7 +21,7 @@ module BreadcrumbsHelper ...@@ -25,7 +21,7 @@ module BreadcrumbsHelper
def breadcrumb_list_item(link) def breadcrumb_list_item(link)
content_tag "li" do content_tag "li" do
link + icon("angle-right", class: "breadcrumbs-list-angle") link + sprite_icon("angle-right", size: 8, css_class: "breadcrumbs-list-angle")
end end
end end
......
...@@ -24,9 +24,9 @@ module IconsHelper ...@@ -24,9 +24,9 @@ module IconsHelper
end end
def sprite_icon(icon_name, size: nil, css_class: nil) def sprite_icon(icon_name, size: nil, css_class: nil)
css_classes = size ? "s#{size}" : nil css_classes = size ? "s#{size}" : ""
css_classes << " #{css_class}" unless css_class.blank? css_classes << " #{css_class}" unless css_class.blank?
content_tag(:svg, content_tag(:use, "", { "xlink:href" => "#{image_path('icons.svg')}##{icon_name}" } ), class: css_classes) content_tag(:svg, content_tag(:use, "", { "xlink:href" => "#{image_path('icons.svg')}##{icon_name}" } ), class: css_classes.empty? ? nil : css_classes)
end end
def audit_icon(names, options = {}) def audit_icon(names, options = {})
......
...@@ -9,7 +9,7 @@ module PageLayoutHelper ...@@ -9,7 +9,7 @@ module PageLayoutHelper
end end
# Segments are seperated by middot # Segments are seperated by middot
@page_title.join(" \u00b7 ") @page_title.join(" · ")
end end
# Define or get a description for the current page # Define or get a description for the current page
......
...@@ -21,11 +21,14 @@ module ProjectsHelper ...@@ -21,11 +21,14 @@ module ProjectsHelper
classes = %W[avatar avatar-inline s#{opts[:size]}] classes = %W[avatar avatar-inline s#{opts[:size]}]
classes << opts[:avatar_class] if opts[:avatar_class] classes << opts[:avatar_class] if opts[:avatar_class]
image_tag(avatar_icon(author, opts[:size]), width: opts[:size], class: classes, alt: '') avatar = avatar_icon(author, opts[:size])
src = opts[:lazy_load] ? nil : avatar
image_tag(src, width: opts[:size], class: classes, alt: '', "data-src" => avatar)
end end
def link_to_member(project, author, opts = {}, &block) def link_to_member(project, author, opts = {}, &block)
default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name", tooltip: false } default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name", tooltip: false, lazy_load: false }
opts = default_opts.merge(opts) opts = default_opts.merge(opts)
return "(deleted)" unless author return "(deleted)" unless author
......
...@@ -1035,7 +1035,7 @@ class Project < ActiveRecord::Base ...@@ -1035,7 +1035,7 @@ class Project < ActiveRecord::Base
# Forked import is handled asynchronously # Forked import is handled asynchronously
return if forked? && !force return if forked? && !force
if gitlab_shell.add_repository(repository_storage_path, disk_path) if gitlab_shell.add_repository(repository_storage, disk_path)
repository.after_create repository.after_create
true true
else else
......
...@@ -174,7 +174,7 @@ class ProjectWiki ...@@ -174,7 +174,7 @@ class ProjectWiki
private private
def init_repo(disk_path) def init_repo(disk_path)
gitlab_shell.add_repository(project.repository_storage_path, disk_path) gitlab_shell.add_repository(project.repository_storage, disk_path)
end end
def commit_details(action, message = nil, title = nil) def commit_details(action, message = nil, title = nil)
......
...@@ -34,7 +34,10 @@ class Repository ...@@ -34,7 +34,10 @@ class Repository
CACHED_METHODS = %i(size commit_count rendered_readme contribution_guide CACHED_METHODS = %i(size commit_count rendered_readme contribution_guide
changelog license_blob license_key gitignore koding_yml changelog license_blob license_key gitignore koding_yml
gitlab_ci_yml branch_names tag_names branch_count gitlab_ci_yml branch_names tag_names branch_count
tag_count avatar exists? empty? root_ref).freeze tag_count avatar exists? empty? root_ref has_visible_content?).freeze
# Methods that use cache_method but only memoize the value
MEMOIZED_CACHED_METHODS = %i(license empty_repo?).freeze
# Certain method caches should be refreshed when certain types of files are # Certain method caches should be refreshed when certain types of files are
# changed. This Hash maps file types (as returned by Gitlab::FileDetector) to # changed. This Hash maps file types (as returned by Gitlab::FileDetector) to
...@@ -91,12 +94,6 @@ class Repository ...@@ -91,12 +94,6 @@ class Repository
) )
end end
# we need to have this method here because it is not cached in ::Git and
# the method is called multiple times for every request
def has_visible_content?
branch_count > 0
end
def inspect def inspect
"#<#{self.class.name}:#{@disk_path}>" "#<#{self.class.name}:#{@disk_path}>"
end end
...@@ -275,7 +272,7 @@ class Repository ...@@ -275,7 +272,7 @@ class Repository
end end
def expire_branches_cache def expire_branches_cache
expire_method_caches(%i(branch_names branch_count)) expire_method_caches(%i(branch_names branch_count has_visible_content?))
@local_branches = nil @local_branches = nil
@branch_exists_memo = nil @branch_exists_memo = nil
end end
...@@ -346,7 +343,7 @@ class Repository ...@@ -346,7 +343,7 @@ class Repository
def expire_emptiness_caches def expire_emptiness_caches
return unless empty? return unless empty?
expire_method_caches(%i(empty?)) expire_method_caches(%i(empty? has_visible_content?))
end end
def lookup_cache def lookup_cache
...@@ -523,9 +520,10 @@ class Repository ...@@ -523,9 +520,10 @@ class Repository
delegate :tag_names, to: :raw_repository delegate :tag_names, to: :raw_repository
cache_method :tag_names, fallback: [] cache_method :tag_names, fallback: []
delegate :branch_count, :tag_count, to: :raw_repository delegate :branch_count, :tag_count, :has_visible_content?, to: :raw_repository
cache_method :branch_count, fallback: 0 cache_method :branch_count, fallback: 0
cache_method :tag_count, fallback: 0 cache_method :tag_count, fallback: 0
cache_method :has_visible_content?, fallback: false
def avatar def avatar
# n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/38327 # n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/38327
......
...@@ -11,6 +11,8 @@ class GlobalPolicy < BasePolicy ...@@ -11,6 +11,8 @@ class GlobalPolicy < BasePolicy
with_options scope: :user, score: 0 with_options scope: :user, score: 0
condition(:access_locked) { @user.access_locked? } condition(:access_locked) { @user.access_locked? }
condition(:can_create_fork, scope: :user) { @user.manageable_namespaces.any? { |namespace| @user.can?(:create_projects, namespace) } }
rule { anonymous }.policy do rule { anonymous }.policy do
prevent :log_in prevent :log_in
prevent :access_api prevent :access_api
...@@ -40,6 +42,10 @@ class GlobalPolicy < BasePolicy ...@@ -40,6 +42,10 @@ class GlobalPolicy < BasePolicy
enable :create_group enable :create_group
end end
rule { can_create_fork }.policy do
enable :create_fork
end
rule { access_locked }.policy do rule { access_locked }.policy do
prevent :log_in prevent :log_in
end end
......
class NamespacePolicy < BasePolicy class NamespacePolicy < BasePolicy
rule { anonymous }.prevent_all rule { anonymous }.prevent_all
condition(:personal_project, scope: :subject) { @subject.kind == 'user' }
condition(:can_create_personal_project, scope: :user) { @user.can_create_project? }
condition(:owner) { @subject.owner == @user } condition(:owner) { @subject.owner == @user }
rule { owner | admin }.policy do rule { owner | admin }.policy do
enable :create_projects enable :create_projects
enable :admin_namespace enable :admin_namespace
end end
rule { personal_project & ~can_create_personal_project }.prevent :create_projects
end end
...@@ -11,7 +11,7 @@ module Tags ...@@ -11,7 +11,7 @@ module Tags
begin begin
new_tag = repository.add_tag(current_user, tag_name, target, message) new_tag = repository.add_tag(current_user, tag_name, target, message)
rescue Rugged::TagError rescue Gitlab::Git::Repository::TagExistsError
return error("Tag #{tag_name} already exists") return error("Tag #{tag_name} already exists")
rescue Gitlab::Git::HooksService::PreReceiveError => ex rescue Gitlab::Git::HooksService::PreReceiveError => ex
return error(ex.message) return error(ex.message)
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
%a %a
Loading... Loading...
= dropdown_loading = dropdown_loading
%i.search-icon = sprite_icon('search', size: 16, css_class: 'search-icon')
%i.clear-icon.js-clear-input = sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input')
= hidden_field_tag :group_id, @group.try(:id), class: 'js-search-group-options', data: group_data_attrs = hidden_field_tag :group_id, @group.try(:id), class: 'js-search-group-options', data: group_data_attrs
......
...@@ -22,29 +22,29 @@ ...@@ -22,29 +22,29 @@
= render 'layouts/search' unless current_controller?(:search) = render 'layouts/search' unless current_controller?(:search)
%li.visible-sm-inline-block.visible-xs-inline-block %li.visible-sm-inline-block.visible-xs-inline-block
= link_to search_path, title: 'Search', aria: { label: "Search" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to search_path, title: 'Search', aria: { label: "Search" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('search') = sprite_icon('search', size: 16)
- if current_user - if current_user
%li.user-counter = nav_link(path: 'dashboard#issues', html_options: { class: "user-counter" }) do
= link_to assigned_issues_dashboard_path, title: 'Issues', class: 'dashboard-shortcuts-issues', aria: { label: "Issues" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'dashboard-shortcuts-issues', aria: { label: "Issues" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= custom_icon('issues') = sprite_icon('issues', size: 16)
- issues_count = assigned_issuables_count(:issues) - issues_count = assigned_issuables_count(:issues)
%span.badge.issues-count{ class: ('hidden' if issues_count.zero?) } %span.badge.issues-count{ class: ('hidden' if issues_count.zero?) }
= number_with_delimiter(issues_count) = number_with_delimiter(issues_count)
%li.user-counter = nav_link(path: 'dashboard#merge_requests', html_options: { class: "user-counter" }) do
= link_to assigned_mrs_dashboard_path, title: 'Merge requests', class: 'dashboard-shortcuts-merge_requests', aria: { label: "Merge requests" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to assigned_mrs_dashboard_path, title: 'Merge requests', class: 'dashboard-shortcuts-merge_requests', aria: { label: "Merge requests" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= custom_icon('mr_bold') = sprite_icon('git-merge', size: 16)
- merge_requests_count = assigned_issuables_count(:merge_requests) - merge_requests_count = assigned_issuables_count(:merge_requests)
%span.badge.merge-requests-count{ class: ('hidden' if merge_requests_count.zero?) } %span.badge.merge-requests-count{ class: ('hidden' if merge_requests_count.zero?) }
= number_with_delimiter(merge_requests_count) = number_with_delimiter(merge_requests_count)
%li.user-counter = nav_link(controller: 'dashboard/todos', html_options: { class: "user-counter" }) do
= link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, class: 'shortcuts-todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= custom_icon('todo_done') = sprite_icon('todo-done', size: 16)
%span.badge.todos-count{ class: ('hidden' if todos_pending_count.zero?) } %span.badge.todos-count{ class: ('hidden' if todos_pending_count.zero?) }
= todos_count_format(todos_pending_count) = todos_count_format(todos_pending_count)
%li.header-user.dropdown %li.header-user.dropdown
= link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown" } do = link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown" } do
= image_tag avatar_icon(current_user, 23), width: 23, height: 23, class: "header-user-avatar" = image_tag avatar_icon(current_user, 23), width: 23, height: 23, class: "header-user-avatar"
= custom_icon('caret_down') = sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu-nav.dropdown-menu-align-right .dropdown-menu-nav.dropdown-menu-align-right
%ul %ul
%li.current-user %li.current-user
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
%button.navbar-toggle.hidden-sm.hidden-md.hidden-lg{ type: 'button' } %button.navbar-toggle.hidden-sm.hidden-md.hidden-lg{ type: 'button' }
%span.sr-only Toggle navigation %span.sr-only Toggle navigation
= icon('ellipsis-v', class: 'js-navbar-toggle-right') = sprite_icon('more', size: 16, css_class: 'more-icon js-navbar-toggle-right')
= icon('times', class: 'js-navbar-toggle-left') = sprite_icon('close', size: 16, css_class: 'close-icon js-navbar-toggle-left')
= render 'shared/outdated_browser' = render 'shared/outdated_browser'
%li.header-new.dropdown %li.header-new.dropdown
= link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip", title: "New...", ref: 'tooltip', aria: { label: "New..." }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body' } do = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip", title: "New...", ref: 'tooltip', aria: { label: "New..." }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body' } do
= custom_icon('plus_square') = sprite_icon('plus-square', size: 16)
= custom_icon('caret_down') = sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu-nav.dropdown-menu-align-right .dropdown-menu-nav.dropdown-menu-align-right
%ul %ul
- if @group&.persisted? - if @group&.persisted?
......
...@@ -16,5 +16,5 @@ ...@@ -16,5 +16,5 @@
= breadcrumb_list_item link_to(extra[:text], extra[:link]) = breadcrumb_list_item link_to(extra[:text], extra[:link])
= render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :after = render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :after
%li %li
%h2.breadcrumbs-sub-title= @breadcrumb_title %h2.breadcrumbs-sub-title= link_to @breadcrumb_title, breadcrumb_title_link
= yield :header_content = yield :header_content
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
= nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects" }) do = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: { id: 'nav-projects-dropdown', class: "home dropdown header-projects" }) do
%a{ href: "#", data: { toggle: "dropdown" } } %a{ href: "#", data: { toggle: "dropdown" } }
Projects Projects
= custom_icon('caret_down') = sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu.projects-dropdown-menu .dropdown-menu.projects-dropdown-menu
= render "layouts/nav/projects_dropdown/show" = render "layouts/nav/projects_dropdown/show"
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
%li.header-more.dropdown.hidden-lg %li.header-more.dropdown.hidden-lg
%a{ href: "#", data: { toggle: "dropdown" } } %a{ href: "#", data: { toggle: "dropdown" } }
More More
= custom_icon('caret_down') = sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu .dropdown-menu
%ul %ul
= nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { class: "visible-xs" }) do = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { class: "visible-xs" }) do
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
- if current_user.admin? - if current_user.admin?
= nav_link(controller: 'admin/dashboard') do = nav_link(controller: 'admin/dashboard') do
= link_to admin_root_path, class: 'admin-icon', title: 'Admin area', aria: { label: "Admin area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to admin_root_path, class: 'admin-icon', title: 'Admin area', aria: { label: "Admin area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('wrench fw') = sprite_icon('admin', size: 18)
- if Gitlab::Sherlock.enabled? - if Gitlab::Sherlock.enabled?
%li %li
= link_to sherlock_transactions_path, class: 'admin-icon', title: 'Sherlock Transactions', = link_to sherlock_transactions_path, class: 'admin-icon', title: 'Sherlock Transactions',
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
%li.dropdown %li.dropdown
%button.text-expander.has-tooltip.js-breadcrumbs-collapsed-expander{ type: "button", data: { toggle: "dropdown", container: "body" }, "aria-label": button_tooltip, title: button_tooltip } %button.text-expander.has-tooltip.js-breadcrumbs-collapsed-expander{ type: "button", data: { toggle: "dropdown", container: "body" }, "aria-label": button_tooltip, title: button_tooltip }
= icon("ellipsis-h") = icon("ellipsis-h")
= icon("angle-right", class: "breadcrumbs-list-angle") = sprite_icon("angle-right", css_class: "breadcrumbs-list-angle")
.dropdown-menu .dropdown-menu
%ul %ul
- @breadcrumb_dropdown_links[dropdown_location].each_with_index do |link, index| - @breadcrumb_dropdown_links[dropdown_location].each_with_index do |link, index|
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.context-header .context-header
= link_to admin_root_path, title: 'Admin Overview' do = link_to admin_root_path, title: 'Admin Overview' do
.avatar-container.s40.settings-avatar .avatar-container.s40.settings-avatar
= icon('wrench') = sprite_icon('admin', size: 24)
.sidebar-context-title Admin Area .sidebar-context-title Admin Area
%ul.sidebar-top-level-items %ul.sidebar-top-level-items
= nav_link(controller: %w(dashboard admin projects users groups jobs runners cohorts conversational_development_index), html_options: {class: 'home'}) do = nav_link(controller: %w(dashboard admin projects users groups jobs runners cohorts conversational_development_index), html_options: {class: 'home'}) do
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
= sprite_icon('overview') = sprite_icon('overview')
%span.nav-item-name %span.nav-item-name
Overview Overview
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
= nav_link(controller: %w(dashboard admin projects users groups jobs runners cohorts conversational_development_index), html_options: { class: "fly-out-top-item" } ) do = nav_link(controller: %w(dashboard admin projects users groups jobs runners cohorts conversational_development_index), html_options: { class: "fly-out-top-item" } ) do
= link_to admin_root_path do = link_to admin_root_path do
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.context-header .context-header
= link_to profile_path, title: 'Profile Settings' do = link_to profile_path, title: 'Profile Settings' do
.avatar-container.s40.settings-avatar .avatar-container.s40.settings-avatar
= icon('user') = sprite_icon('user', size: 24)
.sidebar-context-title User Settings .sidebar-context-title User Settings
%ul.sidebar-top-level-items %ul.sidebar-top-level-items
= nav_link(path: 'profiles#show', html_options: {class: 'home'}) do = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
......
...@@ -4,12 +4,11 @@ ...@@ -4,12 +4,11 @@
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn has-tooltip' do = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn has-tooltip' do
= custom_icon('icon_fork') = custom_icon('icon_fork')
%span= s_('GoToYourFork|Fork') %span= s_('GoToYourFork|Fork')
- elsif !current_user.can_create_project?
= link_to new_project_fork_path(@project), title: _('You have reached your project limit'), class: 'btn has-tooltip disabled' do
= custom_icon('icon_fork')
%span= s_('CreateNewFork|Fork')
- else - else
= link_to new_project_fork_path(@project), class: 'btn' do - can_create_fork = current_user.can?(:create_fork)
= link_to new_project_fork_path(@project),
class: "btn btn-default #{'has-tooltip disabled' unless can_create_fork}",
title: (_('You have reached your project limit') unless can_create_fork) do
= custom_icon('icon_fork') = custom_icon('icon_fork')
%span= s_('CreateNewFork|Fork') %span= s_('CreateNewFork|Fork')
.count-with-arrow .count-with-arrow
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
- if @namespaces.present? - if @namespaces.present?
%label.label-light %label.label-light
%span %span
Click to fork the project to a user or group Click to fork the project
- @namespaces.in_groups_of(6, false) do |group| - @namespaces.in_groups_of(6, false) do |group|
.row .row
- group.each do |namespace| - group.each do |namespace|
...@@ -29,8 +29,12 @@ ...@@ -29,8 +29,12 @@
.caption .caption
= namespace.human_name = namespace.human_name
- else - else
.fork-thumbnail - can_create_project = current_user.can?(:create_projects, namespace)
= link_to project_forks_path(@project, namespace_key: namespace.id), method: "POST" do .fork-thumbnail{ class: ("disabled" unless can_create_project) }
= link_to project_forks_path(@project, namespace_key: namespace.id),
method: "POST",
class: ("disabled has-tooltip" unless can_create_project),
title: (_('You have reached your project limit') unless can_create_project) do
- if /no_((\w*)_)*avatar/.match(avatar) - if /no_((\w*)_)*avatar/.match(avatar)
.no-avatar .no-avatar
= icon 'question' = icon 'question'
......
- access = note_max_access_for_user(note) - access = note_max_access_for_user(note)
- if note.has_special_role?(Note::SpecialRole::FIRST_TIME_CONTRIBUTOR) - if note.has_special_role?(Note::SpecialRole::FIRST_TIME_CONTRIBUTOR)
%span.note-role.note-role-special.has-tooltip{ title: _("This is the author's first Merge Request to this project. Handle with care.") } %span.note-role.note-role-special.has-tooltip{ title: _("This is the author's first Merge Request to this project.") }
= issuable_first_contribution_icon = issuable_first_contribution_icon
- if access.nonzero? - if access.nonzero?
%span.note-role.note-role-access= Gitlab::Access.human_access(access) %span.note-role.note-role-access= Gitlab::Access.human_access(access)
......
.tree-ref-container .tree-ref-container
.tree-ref-holder .tree-ref-holder
= render 'shared/ref_switcher', destination: 'tree', path: @path = render 'shared/ref_switcher', destination: 'tree', path: @path
- if show_new_repo?
.tree-ref-target-holder.js-tree-ref-target-holder
= icon('long-arrow-right', title: 'to target branch')
= render 'shared/target_switcher', destination: 'tree', path: @path
- unless show_new_repo? - unless show_new_repo?
= render 'projects/tree/old_tree_header' = render 'projects/tree/old_tree_header'
......
- commit_message = @page.persisted? ? "Update #{@page.title}" : "Create #{@page.title}" - commit_message = @page.persisted? ? s_("WikiPageEdit|Update %{page_title}") : s_("WikiPageCreate|Create %{page_title}")
- commit_message = commit_message % { page_title: @page.title }
= form_for [@project.namespace.becomes(Namespace), @project, @page], method: @page.persisted? ? :put : :post, html: { class: 'form-horizontal wiki-form common-note-form prepend-top-default js-quick-submit' } do |f| = form_for [@project.namespace.becomes(Namespace), @project, @page], method: @page.persisted? ? :put : :post, html: { class: 'form-horizontal wiki-form common-note-form prepend-top-default js-quick-submit' } do |f|
= form_errors(@page) = form_errors(@page)
...@@ -12,13 +13,13 @@ ...@@ -12,13 +13,13 @@
.form-group .form-group
.col-sm-12= f.label :format, class: 'control-label-full-width' .col-sm-12= f.label :format, class: 'control-label-full-width'
.col-sm-12 .col-sm-12
= f.select :format, options_for_select(ProjectWiki::MARKUPS, {selected: @page.format}), {}, class: "form-control" = f.select :format, options_for_select(ProjectWiki::MARKUPS, {selected: @page.format}), {}, class: 'form-control'
.form-group .form-group
.col-sm-12= f.label :content, class: 'control-label-full-width' .col-sm-12= f.label :content, class: 'control-label-full-width'
.col-sm-12 .col-sm-12
= render layout: 'projects/md_preview', locals: { url: project_wiki_preview_markdown_path(@project, @page.slug) } do = render layout: 'projects/md_preview', locals: { url: project_wiki_preview_markdown_path(@project, @page.slug) } do
= render 'projects/zen', f: f, attr: :content, classes: 'note-textarea', placeholder: 'Write your content or drag files here...' = render 'projects/zen', f: f, attr: :content, classes: 'note-textarea', placeholder: s_("WikiPage|Write your content or drag files here...")
= render 'shared/notes/hints' = render 'shared/notes/hints'
.clearfix .clearfix
...@@ -26,12 +27,11 @@ ...@@ -26,12 +27,11 @@
.help-block .help-block
= succeed '.' do = succeed '.' do
To link to a (new) page, simply type = (s_("WikiMarkdownTip|To link to a (new) page, simply type %{link_example}") % { link_example: '<code>[Link Title](page-slug)</code>' }).html_safe
%code [Link Title](page-slug)
= succeed '.' do = succeed '.' do
More examples are in the - markdown_link = link_to s_("WikiMarkdownDocs|documentation"), help_page_path('user/markdown', anchor: 'wiki-specific-markdown')
= link_to 'documentation', help_page_path("user/markdown", anchor: "wiki-specific-markdown") = (s_("WikiMarkdownDocs|More examples are in the %{docs_link}") % { docs_link: markdown_link }).html_safe
.form-group .form-group
.col-sm-12= f.label :commit_message, class: 'control-label-full-width' .col-sm-12= f.label :commit_message, class: 'control-label-full-width'
...@@ -39,10 +39,10 @@ ...@@ -39,10 +39,10 @@
.form-actions .form-actions
- if @page && @page.persisted? - if @page && @page.persisted?
= f.submit 'Save changes', class: "btn-save btn" = f.submit _("Save changes"), class: 'btn-save btn'
.pull-right .pull-right
= link_to "Cancel", project_wiki_path(@project, @page), class: "btn btn-cancel btn-grouped" = link_to _("Cancel"), project_wiki_path(@project, @page), class: 'btn btn-cancel btn-grouped'
- else - else
= f.submit 'Create page', class: "btn-create btn" = f.submit s_("Wiki|Create page"), class: 'btn-create btn'
.pull-right .pull-right
= link_to "Cancel", project_wiki_path(@project, :home), class: "btn btn-cancel" = link_to _("Cancel"), project_wiki_path(@project, :home), class: 'btn btn-cancel'
- if (@page && @page.persisted?) - if (@page && @page.persisted?)
- if can?(current_user, :create_wiki, @project) - if can?(current_user, :create_wiki, @project)
= link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do
New page = s_("Wiki|New page")
= link_to project_wiki_history_path(@project, @page), class: "btn" do = link_to project_wiki_history_path(@project, @page), class: "btn" do
Page history = s_("Wiki|Page history")
- if can?(current_user, :create_wiki, @project) && @page.latest? - if can?(current_user, :create_wiki, @project) && @page.latest?
= link_to project_wiki_edit_path(@project, @page), class: "btn js-wiki-edit" do = link_to project_wiki_edit_path(@project, @page), class: "btn js-wiki-edit" do
Edit = _("Edit")
...@@ -3,16 +3,15 @@ ...@@ -3,16 +3,15 @@
.modal-content .modal-content
.modal-header .modal-header
%a.close{ href: "#", "data-dismiss" => "modal" } × %a.close{ href: "#", "data-dismiss" => "modal" } ×
%h3.page-title New Wiki Page %h3.page-title= s_("WikiNewPageTitle|New Wiki Page")
.modal-body .modal-body
%form.new-wiki-page %form.new-wiki-page
.form-group .form-group
= label_tag :new_wiki_path do = label_tag :new_wiki_path do
%span Page slug %span= s_("WikiPage|Page slug")
= text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => project_wikis_path(@project), autofocus: true = text_field_tag :new_wiki_path, nil, placeholder: s_("WikiNewPagePlaceholder|how-to-setup"), class: 'form-control', required: true, :'data-wikis-path' => project_wikis_path(@project), autofocus: true
%span.new-wiki-page-slug-tip %span.new-wiki-page-slug-tip
= icon('lightbulb-o') = icon('lightbulb-o')
Tip: You can specify the full path for the new file. = s_("WikiNewPageTip|Tip: You can specify the full path for the new file. We will automatically create any missing directories.")
We will automatically create any missing directories.
.form-actions .form-actions
= button_tag 'Create page', class: 'build-new-wiki btn btn-create' = button_tag s_("Wiki|Create page"), class: "build-new-wiki btn btn-create"
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
= link_to wiki_page.title, project_wiki_path(@project, wiki_page) = link_to wiki_page.title, project_wiki_path(@project, wiki_page)
%small (#{wiki_page.format}) %small (#{wiki_page.format})
.pull-right .pull-right
%small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} %small= (s_("Last edited %{date}") % { date: time_ago_with_tooltip(wiki_page.commit.authored_date) }).html_safe
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
= link_to git_access_url, class: active_nav_link?(path: 'wikis#git_access') ? 'active' : '' do = link_to git_access_url, class: active_nav_link?(path: 'wikis#git_access') ? 'active' : '' do
= succeed '&nbsp;' do = succeed '&nbsp;' do
= icon('cloud-download') = icon('cloud-download')
Clone repository = _("Clone repository")
.blocks-container .blocks-container
.block.block-first .block.block-first
...@@ -17,6 +17,6 @@ ...@@ -17,6 +17,6 @@
.block .block
= link_to project_wikis_pages_path(@project), class: 'btn btn-block' do = link_to project_wikis_pages_path(@project), class: 'btn btn-block' do
More Pages = s_("Wiki|More Pages")
= render 'projects/wikis/new' = render 'projects/wikis/new'
- @content_class = "limit-container-width limit-container-width-sm" unless fluid_layout - @content_class = "limit-container-width limit-container-width-sm" unless fluid_layout
- page_title "Edit", @page.title.capitalize, "Wiki" - page_title _("Edit"), @page.title.capitalize, _("Wiki")
- if @conflict - if @conflict
.alert.alert-danger .alert.alert-danger
Someone edited the page the same time you did. Please check out - page_link = link_to s_("WikiPageConflictMessage|the page"), project_wiki_path(@project, @page), target: "_blank"
= link_to "the page", project_wiki_path(@project, @page), target: "_blank" = (s_("WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{page_link} and make sure your changes will not unintentionally remove theirs.") % { page_link: page_link }).html_safe
and make sure your changes will not unintentionally remove theirs.
.wiki-page-header.has-sidebar-toggle .wiki-page-header.has-sidebar-toggle
%button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" } %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
...@@ -20,20 +19,20 @@ ...@@ -20,20 +19,20 @@
%span.light %span.light
&middot; &middot;
- if @page.persisted? - if @page.persisted?
Edit Page = s_("Wiki|Edit Page")
- else - else
Create Page = s_("Wiki|Create Page")
.nav-controls .nav-controls
- if can?(current_user, :create_wiki, @project) - if can?(current_user, :create_wiki, @project)
= link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do
New page = s_("Wiki|New page")
- if @page.persisted? - if @page.persisted?
= link_to project_wiki_history_path(@project, @page), class: "btn" do = link_to project_wiki_history_path(@project, @page), class: "btn" do
Page history = s_("Wiki|Page history")
- if can?(current_user, :admin_wiki, @project) - if can?(current_user, :admin_wiki, @project)
= link_to project_wiki_path(@project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-danger" do = link_to project_wiki_path(@project, @page), data: { confirm: s_("WikiPageConfirmDelete|Are you sure you want to delete this page?")}, method: :delete, class: "btn btn-danger" do
Delete = _("Delete")
= render 'form' = render 'form'
......
- page_title "Wiki" - page_title _("Wiki")
%h3.page-title Empty page %h3.page-title= _("Wiki|Empty page")
%hr %hr
.error_message .error_message
You are not allowed to create wiki pages = s_("WikiEmptyPageError|You are not allowed to create wiki pages")
- @content_class = "limit-container-width limit-container-width-sm" unless fluid_layout - @content_class = "limit-container-width limit-container-width-sm" unless fluid_layout
- page_title "Git Access", "Wiki" - page_title s_("WikiClone|Git Access"), _("Wiki")
.wiki-page-header.has-sidebar-toggle .wiki-page-header.has-sidebar-toggle
%button.btn.btn-default.visible-xs.visible-sm.pull-right.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" } %button.btn.btn-default.visible-xs.visible-sm.pull-right.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
= icon('angle-double-left') = icon('angle-double-left')
.git-access-header .git-access-header
Clone repository = _("Clone repository")
%strong= @project_wiki.full_path %strong= @project_wiki.full_path
= render "shared/clone_panel", project: @project_wiki = render "shared/clone_panel", project: @project_wiki
.wiki-git-access .wiki-git-access
%h3 Install Gollum %h3= s_("WikiClone|Install Gollum")
%pre.dark %pre.dark
:preserve :preserve
gem install gollum gem install gollum
%p %p
It is recommended to install = (s_("WikiClone|It is recommended to install %{markdown} so that GFM features render locally:") % { markdown: "<code>github-markdown</code>" }).html_safe
%code github-markdown
so that GFM features render locally:
%pre.dark %pre.dark
:preserve :preserve
gem install github-markdown gem install github-markdown
%h3 Clone your wiki %h3= s_("WikiClone|Clone your wiki")
%pre.dark %pre.dark
:preserve :preserve
git clone #{ content_tag(:span, h(default_url_to_repo(@project_wiki)), class: 'clone')} git clone #{ content_tag(:span, h(default_url_to_repo(@project_wiki)), class: 'clone')}
cd #{h @project_wiki.path} cd #{h @project_wiki.path}
%h3 Start Gollum and edit locally %h3= s_("WikiClone|Start Gollum and edit locally")
%pre.dark %pre.dark
:preserve :preserve
gollum gollum
......
- page_title "History", @page.title.capitalize, "Wiki" - page_title _("History"), @page.title.capitalize, _("Wiki")
.wiki-page-header.has-sidebar-toggle .wiki-page-header.has-sidebar-toggle
%button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" } %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
...@@ -9,17 +9,17 @@ ...@@ -9,17 +9,17 @@
= link_to @page.title.capitalize, project_wiki_path(@project, @page) = link_to @page.title.capitalize, project_wiki_path(@project, @page)
%span.light %span.light
&middot; &middot;
History = _("History")
.table-holder .table-holder
%table.table %table.table
%thead %thead
%tr %tr
%th Page version %th= s_("Wiki|Page version")
%th Author %th= _("Author")
%th Commit Message %th= _("Commit Message")
%th Last updated %th= _("Last updated")
%th Format %th= _("Format")
%tbody %tbody
- @page.versions.each_with_index do |version, index| - @page.versions.each_with_index do |version, index|
- commit = version - commit = version
......
- @no_container = true - @no_container = true
- add_to_breadcrumbs "Wiki", get_project_wiki_path(@project) - add_to_breadcrumbs "Wiki", get_project_wiki_path(@project)
- breadcrumb_title "Pages" - breadcrumb_title s_("Wiki|Pages")
- page_title "Pages", "Wiki" - page_title s_("Wiki|Pages"), _("Wiki")
%div{ class: container_class } %div{ class: container_class }
.wiki-page-header .wiki-page-header
.nav-text .nav-text
%h2.wiki-page-title %h2.wiki-page-title
Wiki Pages = s_("Wiki|Wiki Pages")
.nav-controls .nav-controls
= link_to project_wikis_git_access_path(@project), class: 'btn' do = link_to project_wikis_git_access_path(@project), class: 'btn' do
= icon('cloud-download') = icon('cloud-download')
Clone repository = _("Clone repository")
%ul.wiki-pages-list.content-list %ul.wiki-pages-list.content-list
= render @wiki_entries, context: 'pages' = render @wiki_entries, context: 'pages'
......
- @content_class = "limit-container-width limit-container-width-sm" unless fluid_layout - @content_class = "limit-container-width limit-container-width-sm" unless fluid_layout
- breadcrumb_title @page.title.capitalize - breadcrumb_title @page.title.capitalize
- wiki_breadcrumb_dropdown_links(@page.slug) - wiki_breadcrumb_dropdown_links(@page.slug)
- page_title @page.title.capitalize, "Wiki" - page_title @page.title.capitalize, _("Wiki")
- add_to_breadcrumbs "Wiki", get_project_wiki_path(@project) - add_to_breadcrumbs _("Wiki"), get_project_wiki_path(@project)
.wiki-page-header.has-sidebar-toggle .wiki-page-header.has-sidebar-toggle
%button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" } %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
...@@ -11,9 +11,7 @@ ...@@ -11,9 +11,7 @@
.nav-text .nav-text
%h2.wiki-page-title= @page.title.capitalize %h2.wiki-page-title= @page.title.capitalize
%span.wiki-last-edit-by %span.wiki-last-edit-by
Last edited by = (_("Last edited by %{name}") % { name: "<strong>#{@page.commit.author.name}</strong>" }).html_safe
%strong
#{@page.commit.author.name}
#{time_ago_with_tooltip(@page.commit.authored_date)} #{time_ago_with_tooltip(@page.commit.authored_date)}
.nav-controls .nav-controls
...@@ -21,8 +19,10 @@ ...@@ -21,8 +19,10 @@
- if @page.historical? - if @page.historical?
.warning_message .warning_message
This is an old version of this page. = s_("WikiHistoricalPage|This is an old version of this page.")
You can view the #{link_to "most recent version", project_wiki_path(@project, @page)} or browse the #{link_to "history", project_wiki_history_path(@project, @page)}. - most_recent_link = link_to s_("WikiHistoricalPage|most recent version"), project_wiki_path(@project, @page)
- history_link = link_to s_("WikiHistoricalPage|history"), project_wiki_history_path(@project, @page)
= (s_("WikiHistoricalPage|You can view the %{most_recent_link} or browse the %{history_link}.") % { most_recent_link: most_recent_link, history_link: history_link }).html_safe
.wiki-holder.prepend-top-default.append-bottom-default .wiki-holder.prepend-top-default.append-bottom-default
.wiki .wiki
......
%a.toggle-sidebar-button.js-toggle-sidebar{ role: "button", type: "button", title: "Toggle sidebar" } %a.toggle-sidebar-button.js-toggle-sidebar{ role: "button", type: "button", title: "Toggle sidebar" }
= icon('angle-double-left') = sprite_icon('angle-double-left', css_class: 'icon-angle-double-left')
= icon('angle-double-right') = sprite_icon('angle-double-right', css_class: 'icon-angle-double-right')
%span.collapse-text Collapse sidebar %span.collapse-text Collapse sidebar
= button_tag class: 'close-nav-button', type: 'button' do = button_tag class: 'close-nav-button', type: 'button' do
= icon ('times') = sprite_icon('close', size: 16)
%span.collapse-text Close sidebar %span.collapse-text Close sidebar
- dropdown_toggle_text = @ref || @project.default_branch
= form_tag nil, method: :get, class: "project-refs-form project-refs-target-form" do
= hidden_field_tag :destination, destination
- if defined?(path)
= hidden_field_tag :path, path
- @options && @options.each do |key, value|
= hidden_field_tag key, value, id: nil
.dropdown
= dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_project_path(@project, find: ['branches']), field_name: 'ref', input_field_name: 'new-branch', submit_form_on_click: true, visit: false }, { toggle_class: "js-project-refs-dropdown" }
.dropdown-menu.dropdown-menu-selectable.git-revision-dropdown{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) }
= dropdown_title _("Create a new branch")
= dropdown_input _("Create a new branch")
= dropdown_title _("Select existing branch"), options: {close: false}
= dropdown_filter _("Search branches and tags")
= dropdown_content
= dropdown_loading
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
.hide-collapsed.participants-list .hide-collapsed.participants-list
- participants.each do |participant| - participants.each do |participant|
.participants-author.js-participants-author .participants-author.js-participants-author
= link_to_member(@project, participant, name: false, size: 24) = link_to_member(@project, participant, name: false, size: 24, lazy_load: true)
- if participants_extra > 0 - if participants_extra > 0
.hide-collapsed.participants-more .hide-collapsed.participants-more
%a.js-participants-more{ href: "#", data: { original_text: "+ #{participants_size - 7} more", less_text: "- show less" } } %a.js-participants-more{ href: "#", data: { original_text: "+ #{participants_size - 7} more", less_text: "- show less" } }
......
---
title: "Fix v3 api project_hooks POST and PUT operations for build_events"
merge_request: 12673
author: Richard Clamp
---
title: "reset text-align to initial to let elements with dir="auto" align texts to right in RTL languages ( default is left )"
merge_request: 12892
author: goshhob
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
title: Allow to use same periods for different housekeeping tasks (effectively title: Allow to use same periods for different housekeeping tasks (effectively
skipping the lesser task) skipping the lesser task)
merge_request: 13711 merge_request: 13711
author: @cernvcs author: cernvcs
type: added type: added
---
title: Handle unsubscribe from email notifications via replying to reply+%{key}+unsubscribe@ address
merge_request: 6597
author:
---
title: Refactor Timelogs structure to use foreign keys.
merge_request: 8769
author:
---
title: "Correction to documention for manual steps on the Jobs API"
merge_request: 11411
author: Zac Sturgess
\ No newline at end of file
---
title: Load sidebar participants avatars only when visible
merge_request: 14270
author:
type: other
---
title: "Fix API to serve binary diffs that are treated as text."
merge_request: 14038
---
title: Reschedule merge request diff background migrations to catch failures from
9.5 run
merge_request:
author:
type: fixed
--- ---
title: Add GitLab-Pages version to Admin Dashboard title: Add GitLab-Pages version to Admin Dashboard
merge_request: 14040 merge_request: 14040
author: @travismiller author: travismiller
type: added type: added
---
title: Add active states to nav bar counters
merge_request:
author:
type: changed
---
title: Use `simple=true` for projects API in Projects dropdown for better search performance
merge_request:
author:
type: other
---
title: Fix notes type created from import. This should fix some missing notes issues
from imported projects
merge_request: 14524
author:
type: fixed
---
title: Fixes data parameter not being sent in ajax request for jobs log
merge_request:
author:
type: fixed
---
title: Ensure no exception is raised when Raven tries to get the current user in API
context
merge_request: 14580
author:
type: fixed
---
title: Improves UX of autodevops popover to match gpg one
merge_request:
author:
type: fixed
---
title: Add index for merge_requests.merge_commit_sha
merge_request:
author:
type: other
---
title: Added mock deployment and monitoring service with environments fixtures
merge_request:
author:
---
title: Fixed issue/merge request breadcrumb titles not having links
merge_request:
author:
type: fixed
---
title: Fixed fork button being disabled for users who can fork to a group
merge_request:
author:
type: fixed
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment