Merge remote-tracking branch 'origin/master' into 35616-move-gke-form-1st-iteration

This commit is contained in:
Kamil Trzcinski 2017-11-06 22:38:44 +01:00
commit df333a9380
245 changed files with 8187 additions and 3221 deletions

View file

@ -14,7 +14,7 @@ linters:
# Whether or not to prefer `border: 0` over `border: none`. # Whether or not to prefer `border: 0` over `border: none`.
BorderZero: BorderZero:
enabled: false enabled: true
# Reports when you define a rule set using a selector with chained classes # Reports when you define a rule set using a selector with chained classes
# (a.k.a. adjoining classes). # (a.k.a. adjoining classes).

View file

@ -1 +1 @@
{"iconCount":164,"spriteSize":72823,"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","collapse","comment-dots","comment-next","comment","comments","commit","credit-card","dashboard","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","image-comment-dark","import","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","menu","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","scroll_down","scroll_up","search","settings","shield","slight-frown","slight-smile","smile","smiley","snippet","spam","star-o","star","status_canceled_borderless","status_canceled","status_closed","status_created_borderless","status_created","status_failed_borderless","status_failed","status_manual_borderless","status_manual","status_notfound_borderless","status_open","status_pending_borderless","status_pending","status_running_borderless","status_running","status_skipped_borderless","status_skipped","status_success_borderless","status_success_solid","status_success","status_warning_borderless","status_warning","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":173,"spriteSize":75815,"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","bullhorn","calendar","cancel","chart","chevron-down","chevron-left","chevron-right","chevron-up","clock","close","code","collapse","comment-dots","comment-next","comment","comments","commit","credit-card","cut","dashboard","disk","doc_code","doc_image","doc_text","double-headed-arrow","download","duplicate","earth","external-link","eye-slash","eye","file-addition","file-deletion","file-modified","filter","folder","fork","geo-nodes","git-merge","group","history","home","hook","hourglass","image-comment-dark","import","issue-block","issue-child","issue-close","issue-duplicate","issue-new","issue-open-m","issue-open","issue-parent","issues","italic","key-2","key","label","labels","leave","level-up","license","link","list-bulleted","list-numbered","location-dot","location","lock-open","lock","log","mail","menu","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","scroll_down","scroll_up","search","settings","shield","slight-frown","slight-smile","smile","smiley","snippet","spam","spinner","star-o","star","status_canceled_borderless","status_canceled","status_closed","status_created_borderless","status_created","status_failed_borderless","status_failed","status_manual_borderless","status_manual","status_notfound_borderless","status_open","status_pending_borderless","status_pending","status_running_borderless","status_running","status_skipped_borderless","status_skipped","status_success_borderless","status_success_solid","status_success","status_warning_borderless","status_warning","stop","task-done","template","terminal","thumb-down","thumb-up","thumbtack","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: 71 KiB

After

Width:  |  Height:  |  Size: 74 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="492.509" height="453.68" viewBox="0 0 492.50943 453.67966"><g fill="none" fill-rule="evenodd"><path d="M491.589 259.398l-27.559-84.814L409.413 6.486c-2.81-8.648-15.045-8.648-17.856 0l-54.619 168.098H155.572L100.952 6.486c-2.81-8.648-15.046-8.648-17.856 0L28.478 174.584.921 259.398a18.775 18.775 0 0 0 6.82 20.992l238.513 173.29L484.77 280.39a18.777 18.777 0 0 0 6.82-20.992" fill="#fc6d26"/><path d="M246.255 453.68l90.684-279.096H155.57z" fill="#e24329"/><path d="M246.255 453.68L155.57 174.583H28.479z" fill="#fc6d26"/><path d="M28.479 174.584L.92 259.4a18.773 18.773 0 0 0 6.821 20.99l238.514 173.29z" fill="#fca326"/><path d="M28.479 174.584H155.57L100.952 6.487c-2.81-8.65-15.047-8.65-17.856 0z" fill="#e24329"/><path d="M246.255 453.68l90.684-279.096H464.03z" fill="#fc6d26"/><path d="M464.03 174.584l27.56 84.815a18.773 18.773 0 0 1-6.822 20.99L246.255 453.68z" fill="#fca326"/><path d="M464.03 174.584H336.94L391.557 6.487c2.811-8.65 15.047-8.65 17.856 0z" fill="#e24329"/></g></svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="430" height="220" viewBox="0 0 430 220"><g fill="none" fill-rule="evenodd"><path fill="#EEE" fill-rule="nonzero" d="M189.8 182l2.4-12H114c-5.523 0-10-4.477-10-10V34c0-5.523 4.477-10 10-10h200c5.523 0 10 4.477 10 10v126c0 5.523-4.477 10-10 10h-78.2l2.4 12h22.52a9.651 9.651 0 0 1 9.28 7 5.491 5.491 0 0 1-5.28 7H164.159a5.787 5.787 0 0 1-5.659-7 8.855 8.855 0 0 1 8.659-7H189.8zM114 28a6 6 0 0 0-6 6v126a6 6 0 0 0 6 6h200a6 6 0 0 0 6-6V34a6 6 0 0 0-6-6H114zm5 6h190a5 5 0 0 1 5 5v116a5 5 0 0 1-5 5H119a5 5 0 0 1-5-5V39a5 5 0 0 1 5-5zm0 4a1 1 0 0 0-1 1v116a1 1 0 0 0 1 1h190a1 1 0 0 0 1-1V39a1 1 0 0 0-1-1H119zm112.72 132h-35.44l-2.4 12h40.24l-2.4-12zm-64.561 16c-2.29 0-4.268 1.6-4.748 3.838A1.787 1.787 0 0 0 164.16 192h100.56a1.491 1.491 0 0 0 1.435-1.901A5.651 5.651 0 0 0 260.72 186h-93.561z"/><path fill="#FEF0E8" d="M177.965 99H194a2 2 0 1 1 0 4h-16.322c-1.374 6.29-6.976 11-13.678 11-6.702 0-12.304-4.71-13.678-11h-3.365l-7.395 9.249a2 2 0 0 1-3.049.089L128.11 103h-5.844a2 2 0 1 1 0-4H129a2 2 0 0 1 1.487.662l7.423 8.248 6.523-8.159a2 2 0 0 1 1.562-.751h4.04c.513-7.265 6.57-13 13.965-13 7.396 0 13.452 5.735 13.965 13zM164 110c5.523 0 10-4.477 10-10s-4.477-10-10-10-10 4.477-10 10 4.477 10 10 10z"/><path fill="#EFEDF8" d="M273.847 103c-.962 6.23-6.347 11-12.847 11-6.5 0-11.885-4.77-12.847-11H232a2 2 0 0 1 0-4h16.153c.962-6.23 6.347-11 12.847-11 6.5 0 11.885 4.77 12.847 11h3.998l8.404-9.338a2 2 0 0 1 3.048.09L296.692 99H305a2 2 0 0 1 0 4h-9.27a2 2 0 0 1-1.562-.751l-6.523-8.16-7.423 8.249a2 2 0 0 1-1.487.662h-4.888zM261 110a9 9 0 1 0 0-18 9 9 0 0 0 0 18z"/><path fill="#FEE1D3" fill-rule="nonzero" d="M213 119c-10.493 0-19-8.507-19-19s8.507-19 19-19 19 8.507 19 19-8.507 19-19 19zm0-4c8.284 0 15-6.716 15-15 0-8.284-6.716-15-15-15-8.284 0-15 6.716-15 15 0 8.284 6.716 15 15 15z"/><path fill="#FC6D26" d="M211.586 101.828L208.757 99a2 2 0 1 0-2.828 2.828l4.243 4.243c.39.39.902.586 1.414.586.512 0 1.023-.195 1.414-.586L220.071 99a2 2 0 1 0-2.828-2.828l-5.657 5.656z"/><path fill="#FDC4A8" d="M162.95 101.07l-1.768-1.767a1.5 1.5 0 0 0-2.121 2.121l2.828 2.829c.293.293.677.439 1.06.439.385 0 .769-.146 1.062-.44l4.242-4.242a1.5 1.5 0 1 0-2.121-2.121l-3.182 3.182z"/><path fill="#6B4FBB" d="M256.39 104.841A6 6 0 1 0 261 95v6l-4.61 3.841z"/><path fill="#FEF0E8" fill-rule="nonzero" d="M99 99h-5a2 2 0 1 0 0 4h5a2 2 0 1 0 0-4zm-16 0h-5a2 2 0 1 0 0 4h5a2 2 0 1 0 0-4zm-14.384-.078l-3.643-3.425a2 2 0 1 0-2.74 2.914l3.643 3.425a2 2 0 1 0 2.74-2.914zm-11.657-10.96l-3.642-3.425a2 2 0 1 0-2.74 2.914l3.642 3.425a2 2 0 0 0 2.74-2.914zm-11.656-10.96l-3.643-3.425a2 2 0 0 0-2.74 2.914l3.643 3.425a2 2 0 1 0 2.74-2.914zm-14.367-3.885l-3.593 3.477a2 2 0 0 0 2.782 2.875l3.593-3.477a2 2 0 0 0-2.782-2.875zM19.44 84.244l-3.593 3.477a2 2 0 1 0 2.781 2.874l3.593-3.477a2 2 0 0 0-2.781-2.874zM7.94 95.371l-3.593 3.477a2 2 0 1 0 2.782 2.874l3.593-3.477a2 2 0 1 0-2.782-2.874z"/><path fill="#E1DBF1" fill-rule="nonzero" d="M423.611 99.56l-3.598 3.472a2 2 0 0 0 2.777 2.879l3.599-3.472a2 2 0 0 0-2.778-2.878zm-11.514 11.11l-3.598 3.472a2 2 0 0 0 2.777 2.878l3.598-3.471a2 2 0 0 0-2.777-2.879zm-11.514 11.11l-3.599 3.471a2 2 0 1 0 2.778 2.879l3.598-3.472a2 2 0 1 0-2.777-2.879zm-8.799 4.48l-3.642-3.426a2 2 0 0 0-2.74 2.915l3.642 3.425a2 2 0 0 0 2.74-2.915zm-11.656-10.96l-3.643-3.426a2 2 0 1 0-2.74 2.914l3.643 3.426a2 2 0 1 0 2.74-2.915zm-11.657-10.96l-3.643-3.426a2 2 0 1 0-2.74 2.914l3.643 3.425a2 2 0 1 0 2.74-2.914zM353.001 99h-5a2 2 0 1 0 0 4h5a2 2 0 0 0 0-4zm-16 0h-5a2 2 0 1 0 0 4h5a2 2 0 0 0 0-4z"/></g></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" viewBox="0 0 121.94154 121.84154" width="121.942" height="121.842"><style id="style200">.st0{fill:#ecb32d}.st1{fill:#63c1a0}.st2{fill:#e01a59}.st3{fill:#331433}.st4{fill:#d62027}.st5{fill:#89d3df}.st6{fill:#258b74}.st7{fill:#819c3c}</style><path class="st0" d="M79.03 7.511c-1.9-5.7-8-8.8-13.7-7-5.7 1.9-8.8 8-7 13.7l28.1 86.4c1.9 5.3 7.7 8.3 13.2 6.7 5.8-1.7 9.3-7.8 7.4-13.4 0-.2-28-86.4-28-86.4z" id="path202" fill="#ecb32d"/><path class="st1" d="M35.53 21.611c-1.9-5.7-8-8.8-13.7-7-5.7 1.9-8.8 8-7 13.7l28.1 86.4c1.9 5.3 7.7 8.3 13.2 6.7 5.8-1.7 9.3-7.8 7.4-13.4 0-.2-28-86.4-28-86.4z" id="path204" fill="#63c1a0"/><path class="st2" d="M114.43 79.011c5.7-1.9 8.8-8 7-13.7-1.9-5.7-8-8.8-13.7-7l-86.5 28.2c-5.3 1.9-8.3 7.7-6.7 13.2 1.7 5.8 7.8 9.3 13.4 7.4.2 0 86.5-28.1 86.5-28.1z" id="path206" fill="#e01a59"/><path class="st3" d="M39.23 103.511c5.6-1.8 12.9-4.2 20.7-6.7-1.8-5.6-4.2-12.9-6.7-20.7l-20.7 6.7z" id="path208" fill="#331433"/><path class="st4" d="M82.83 89.311c7.8-2.5 15.1-4.9 20.7-6.7-1.8-5.6-4.2-12.9-6.7-20.7l-20.7 6.7z" id="path210" fill="#d62027"/><path class="st5" d="M100.23 35.511c5.7-1.9 8.8-8 7-13.7-1.9-5.7-8-8.8-13.7-7l-86.4 28.1c-5.3 1.9-8.3 7.7-6.7 13.2 1.7 5.8 7.8 9.3 13.4 7.4.2 0 86.4-28 86.4-28z" id="path212" fill="#89d3df"/><path class="st6" d="M25.13 59.911c5.6-1.8 12.9-4.2 20.7-6.7-2.5-7.8-4.9-15.1-6.7-20.7l-20.7 6.7z" id="path214" fill="#258b74"/><path class="st7" d="M68.63 45.811c7.8-2.5 15.1-4.9 20.7-6.7-2.5-7.8-4.9-15.1-6.7-20.7l-20.7 6.7z" id="path216" fill="#819c3c"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6 KiB

View file

@ -3,6 +3,7 @@
import GLForm from '../../../gl_form'; import GLForm from '../../../gl_form';
import markdownHeader from './header.vue'; import markdownHeader from './header.vue';
import markdownToolbar from './toolbar.vue'; import markdownToolbar from './toolbar.vue';
import icon from '../icon.vue';
export default { export default {
props: { props: {
@ -37,6 +38,7 @@
components: { components: {
markdownHeader, markdownHeader,
markdownToolbar, markdownToolbar,
icon,
}, },
computed: { computed: {
shouldShowReferencedUsers() { shouldShowReferencedUsers() {
@ -45,8 +47,10 @@
}, },
}, },
methods: { methods: {
toggleMarkdownPreview() { showPreviewTab() {
this.previewMarkdown = !this.previewMarkdown; if (this.previewMarkdown) return;
this.previewMarkdown = true;
/* /*
Can't use `$refs` as the component is technically in the parent component Can't use `$refs` as the component is technically in the parent component
@ -54,20 +58,22 @@
*/ */
const text = this.$slots.textarea[0].elm.value; const text = this.$slots.textarea[0].elm.value;
if (!this.previewMarkdown) { if (text) {
this.markdownPreview = '';
} else if (text) {
this.markdownPreviewLoading = true; this.markdownPreviewLoading = true;
this.$http.post(this.markdownPreviewPath, { text }) this.$http.post(this.markdownPreviewPath, { text })
.then(resp => resp.json()) .then(resp => resp.json())
.then((data) => { .then(data => this.renderMarkdown(data))
this.renderMarkdown(data);
})
.catch(() => new Flash('Error loading markdown preview')); .catch(() => new Flash('Error loading markdown preview'));
} else { } else {
this.renderMarkdown(); this.renderMarkdown();
} }
}, },
showWriteTab() {
this.markdownPreview = '';
this.previewMarkdown = false;
},
renderMarkdown(data = {}) { renderMarkdown(data = {}) {
this.markdownPreviewLoading = false; this.markdownPreviewLoading = false;
this.markdownPreview = data.body || 'Nothing to preview.'; this.markdownPreview = data.body || 'Nothing to preview.';
@ -104,7 +110,8 @@
ref="gl-form"> ref="gl-form">
<markdown-header <markdown-header
:preview-markdown="previewMarkdown" :preview-markdown="previewMarkdown"
@toggle-markdown="toggleMarkdownPreview" /> @preview-markdown="showPreviewTab"
@write-markdown="showWriteTab" />
<div <div
class="md-write-holder" class="md-write-holder"
v-show="!previewMarkdown"> v-show="!previewMarkdown">
@ -114,10 +121,10 @@
class="zen-control zen-control-leave js-zen-leave" class="zen-control zen-control-leave js-zen-leave"
href="#" href="#"
aria-label="Enter zen mode"> aria-label="Enter zen mode">
<i <icon
class="fa fa-compress" name="screen-normal"
aria-hidden="true"> :size="32">
</i> </icon>
</a> </a>
<markdown-toolbar <markdown-toolbar
:markdown-docs-path="markdownDocsPath" :markdown-docs-path="markdownDocsPath"

View file

@ -1,6 +1,7 @@
<script> <script>
import tooltip from '../../directives/tooltip'; import tooltip from '../../directives/tooltip';
import toolbarButton from './toolbar_button.vue'; import toolbarButton from './toolbar_button.vue';
import icon from '../icon.vue';
export default { export default {
props: { props: {
@ -14,25 +15,34 @@
}, },
components: { components: {
toolbarButton, toolbarButton,
icon,
}, },
methods: { methods: {
toggleMarkdownPreview(e, form) { isMarkdownForm(form) {
if (form && !form.find('.js-vue-markdown-field').length) { return form && !form.find('.js-vue-markdown-field').length;
return; },
} else if (e.target.blur) {
e.target.blur();
}
this.$emit('toggle-markdown'); previewMarkdownTab(event, form) {
if (event.target.blur) event.target.blur();
if (this.isMarkdownForm(form)) return;
this.$emit('preview-markdown');
},
writeMarkdownTab(event, form) {
if (event.target.blur) event.target.blur();
if (this.isMarkdownForm(form)) return;
this.$emit('write-markdown');
}, },
}, },
mounted() { mounted() {
$(document).on('markdown-preview:show.vue', this.toggleMarkdownPreview); $(document).on('markdown-preview:show.vue', this.previewMarkdownTab);
$(document).on('markdown-preview:hide.vue', this.toggleMarkdownPreview); $(document).on('markdown-preview:hide.vue', this.writeMarkdownTab);
}, },
beforeDestroy() { beforeDestroy() {
$(document).on('markdown-preview:show.vue', this.toggleMarkdownPreview); $(document).off('markdown-preview:show.vue', this.previewMarkdownTab);
$(document).off('markdown-preview:hide.vue', this.toggleMarkdownPreview); $(document).off('markdown-preview:hide.vue', this.writeMarkdownTab);
}, },
}; };
</script> </script>
@ -42,17 +52,19 @@
<ul class="nav-links clearfix"> <ul class="nav-links clearfix">
<li :class="{ active: !previewMarkdown }"> <li :class="{ active: !previewMarkdown }">
<a <a
class="js-write-link"
href="#md-write-holder" href="#md-write-holder"
tabindex="-1" tabindex="-1"
@click.prevent="toggleMarkdownPreview($event)"> @click.prevent="writeMarkdownTab($event)">
Write Write
</a> </a>
</li> </li>
<li :class="{ active: previewMarkdown }"> <li :class="{ active: previewMarkdown }">
<a <a
class="js-preview-link"
href="#md-preview-holder" href="#md-preview-holder"
tabindex="-1" tabindex="-1"
@click.prevent="toggleMarkdownPreview($event)"> @click.prevent="previewMarkdownTab($event)">
Preview Preview
</a> </a>
</li> </li>
@ -70,7 +82,7 @@
tag="> " tag="> "
:prepend="true" :prepend="true"
button-title="Insert a quote" button-title="Insert a quote"
icon="quote-right" /> icon="quote" />
<toolbar-button <toolbar-button
tag="`" tag="`"
tag-block="```" tag-block="```"
@ -80,17 +92,17 @@
tag="* " tag="* "
:prepend="true" :prepend="true"
button-title="Add a bullet list" button-title="Add a bullet list"
icon="list-ul" /> icon="list-bulleted" />
<toolbar-button <toolbar-button
tag="1. " tag="1. "
:prepend="true" :prepend="true"
button-title="Add a numbered list" button-title="Add a numbered list"
icon="list-ol" /> icon="list-numbered" />
<toolbar-button <toolbar-button
tag="* [ ] " tag="* [ ] "
:prepend="true" :prepend="true"
button-title="Add a task list" button-title="Add a task list"
icon="check-square-o" /> icon="task-done" />
</div> </div>
<div class="toolbar-group"> <div class="toolbar-group">
<button <button
@ -101,10 +113,9 @@
tabindex="-1" tabindex="-1"
title="Go full screen" title="Go full screen"
type="button"> type="button">
<i <icon
aria-hidden="true" name="screen-full">
class="fa fa-arrows-alt fa-fw"> </icon>
</i>
</button> </button>
</div> </div>
</li> </li>

View file

@ -1,5 +1,6 @@
<script> <script>
import tooltip from '../../directives/tooltip'; import tooltip from '../../directives/tooltip';
import icon from '../icon.vue';
export default { export default {
props: { props: {
@ -26,14 +27,12 @@
default: false, default: false,
}, },
}, },
components: {
icon,
},
directives: { directives: {
tooltip, tooltip,
}, },
computed: {
iconClass() {
return `fa-${this.icon}`;
},
},
}; };
</script> </script>
@ -49,10 +48,8 @@
:data-md-prepend="prepend" :data-md-prepend="prepend"
:title="buttonTitle" :title="buttonTitle"
:aria-label="buttonTitle"> :aria-label="buttonTitle">
<i <icon
aria-hidden="true" :name="icon">
class="fa fa-fw" </icon>
:class="iconClass">
</i>
</button> </button>
</template> </template>

View file

@ -59,7 +59,7 @@
&.avatar-tile { &.avatar-tile {
border-radius: 0; border-radius: 0;
border: none; border: 0;
} }
&:not([href]):hover { &:not([href]):hover {
@ -96,7 +96,7 @@
.avatar { .avatar {
border-radius: 0; border-radius: 0;
border: none; border: 0;
height: auto; height: auto;
width: 100%; width: 100%;
margin: 0; margin: 0;

View file

@ -39,7 +39,7 @@
} }
&.top-block { &.top-block {
border-top: none; border-top: 0;
.container-fluid { .container-fluid {
background-color: inherit; background-color: inherit;
@ -63,7 +63,7 @@
&.footer-block { &.footer-block {
margin-top: 0; margin-top: 0;
border-bottom: none; border-bottom: 0;
margin-bottom: -$gl-padding; margin-bottom: -$gl-padding;
} }
@ -100,7 +100,7 @@
&.build-content { &.build-content {
background-color: $white-light; background-color: $white-light;
border-top: none; border-top: 0;
} }
} }
@ -287,12 +287,12 @@
cursor: pointer; cursor: pointer;
color: $blue-300; color: $blue-300;
z-index: 1; z-index: 1;
border: none; border: 0;
background-color: transparent; background-color: transparent;
&:hover, &:hover,
&:focus { &:focus {
border: none; border: 0;
color: $blue-400; color: $blue-400;
} }
} }

View file

@ -304,7 +304,7 @@
} }
.btn-clipboard { .btn-clipboard {
border: none; border: 0;
padding: 0 5px; padding: 0 5px;
} }

View file

@ -28,7 +28,7 @@
pre { pre {
&.clean { &.clean {
background: none; background: none;
border: none; border: 0;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
@ -142,7 +142,7 @@ li.note {
img { max-width: 100%; } img { max-width: 100%; }
.note-title { .note-title {
li { li {
border-bottom: none !important; border-bottom: 0 !important;
} }
} }
} }
@ -187,7 +187,7 @@ li.note {
pre { pre {
background: $white-light; background: $white-light;
border: none; border: 0;
font-size: 12px; font-size: 12px;
} }
} }
@ -386,7 +386,7 @@ img.emoji {
} }
.hide-bottom-border { .hide-bottom-border {
border-bottom: none !important; border-bottom: 0 !important;
} }
.gl-accessibility { .gl-accessibility {

View file

@ -142,7 +142,7 @@
*/ */
&.blame { &.blame {
table { table {
border: none; border: 0;
margin: 0; margin: 0;
} }
@ -150,20 +150,20 @@
border-bottom: 1px solid $blame-border; border-bottom: 1px solid $blame-border;
&:last-child { &:last-child {
border-bottom: none; border-bottom: 0;
} }
} }
td { td {
border-top: none; border-top: 0;
border-bottom: none; border-bottom: 0;
&:first-child { &:first-child {
border-left: none; border-left: 0;
} }
&:last-child { &:last-child {
border-right: none; border-right: 0;
} }
&.blame-commit { &.blame-commit {

View file

@ -255,7 +255,7 @@
.clear-search { .clear-search {
width: 35px; width: 35px;
background-color: $white-light; background-color: $white-light;
border: none; border: 0;
outline: none; outline: none;
z-index: 1; z-index: 1;
@ -418,7 +418,7 @@
.droplab-dropdown .dropdown-menu .filter-dropdown-item { .droplab-dropdown .dropdown-menu .filter-dropdown-item {
.btn { .btn {
border: none; border: 0;
width: 100%; width: 100%;
text-align: left; text-align: left;
padding: 8px 16px; padding: 8px 16px;

View file

@ -10,7 +10,7 @@
z-index: 1000; z-index: 1000;
margin-bottom: 0; margin-bottom: 0;
min-height: $header-height; min-height: $header-height;
border: none; border: 0;
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
position: fixed; position: fixed;
top: 0; top: 0;
@ -169,7 +169,7 @@
.navbar-collapse { .navbar-collapse {
flex: 0 0 auto; flex: 0 0 auto;
border-top: none; border-top: 0;
padding: 0; padding: 0;
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
@ -352,77 +352,7 @@
.header-user .dropdown-menu-nav, .header-user .dropdown-menu-nav,
.header-new .dropdown-menu-nav { .header-new .dropdown-menu-nav {
margin-top: 4px; margin-top: $dropdown-vertical-offset;
}
.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-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 {
form {
background-color: rgba($indigo-200, .3);
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;
}
}
}
.location-badge {
background-color: $nav-badge-bg;
border-color: $border-color;
}
.search-input-wrap {
.clear-icon {
color: $white-light;
}
}
}
} }
.breadcrumbs { .breadcrumbs {

View file

@ -1,5 +1,5 @@
.file-content.code { .file-content.code {
border: none; border: 0;
box-shadow: none; box-shadow: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -7,7 +7,7 @@
pre { pre {
padding: 10px 0; padding: 10px 0;
border: none; border: 0;
border-radius: 0; border-radius: 0;
font-family: $monospace_font; font-family: $monospace_font;
font-size: $code_font_size; font-size: $code_font_size;

View file

@ -42,7 +42,7 @@
} }
&:last-child { &:last-child {
border-bottom: none; border-bottom: 0;
&.bottom { &.bottom {
background: $gray-light; background: $gray-light;
@ -92,7 +92,7 @@ ul.unstyled-list {
} }
ul.unstyled-list > li { ul.unstyled-list > li {
border-bottom: none; border-bottom: 0;
} }
// Generic content list // Generic content list
@ -178,7 +178,7 @@ ul.content-list {
// When dragging a list item // When dragging a list item
&.ui-sortable-helper { &.ui-sortable-helper {
border-bottom: none; border-bottom: 0;
} }
&.list-placeholder { &.list-placeholder {
@ -295,7 +295,7 @@ ul.indent-list {
} }
> .group-list-tree > .group-row.has-children:first-child { > .group-list-tree > .group-row.has-children:first-child {
border-top: none; border-top: 0;
} }
} }
@ -413,7 +413,7 @@ ul.indent-list {
padding: 0; padding: 0;
&.has-children { &.has-children {
border-top: none; border-top: 0;
} }
&:first-child { &:first-child {

View file

@ -138,15 +138,23 @@
.toolbar-btn { .toolbar-btn {
float: left; float: left;
padding: 0 5px; padding: 0 7px;
color: $gl-text-color-secondary;
background: transparent; background: transparent;
border: 0; border: 0;
outline: 0; outline: 0;
svg {
width: 14px;
height: 14px;
margin-top: 3px;
fill: $gl-text-color-secondary;
}
&:hover, &:hover,
&:focus { &:focus {
color: $gl-link-color; svg {
fill: $gl-link-color;
}
} }
} }

View file

@ -36,7 +36,7 @@
margin: 0; margin: 0;
&:last-child { &:last-child {
border-bottom: none; border-bottom: 0;
} }
&.active { &.active {

View file

@ -24,7 +24,7 @@
@media (min-width: $screen-md-min) { @media (min-width: $screen-md-min) {
margin: 0; margin: 0;
padding: $gl-padding 0; padding: $gl-padding 0;
border: none; border: 0;
&:not(:last-child) { &:not(:last-child) {
border-bottom: 1px solid $white-normal; border-bottom: 1px solid $white-normal;

View file

@ -63,7 +63,7 @@
.nav-links { .nav-links {
margin-bottom: 0; margin-bottom: 0;
border-bottom: none; border-bottom: 0;
float: left; float: left;
&.wide { &.wide {
@ -335,69 +335,16 @@
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
.nav-links { .nav-links {
border-bottom: none; border-bottom: 0;
} }
} }
} }
.page-with-layout-nav { .project-item-select-holder.btn-group {
.right-sidebar {
top: ($header-height + 1) * 2;
}
&.page-with-sub-nav {
.right-sidebar {
top: ($header-height + 1) * 3;
&.affix {
top: $header-height;
}
}
}
}
.with-performance-bar .page-with-layout-nav {
.right-sidebar {
top: ($header-height + 1) * 2 + $performance-bar-height;
}
&.page-with-sub-nav {
.right-sidebar {
top: ($header-height + 1) * 3 + $performance-bar-height;
&.affix {
top: $header-height + $performance-bar-height;
}
}
}
}
@media (max-width: $screen-xs-max) {
.top-area {
flex-flow: row wrap;
.nav-controls {
$controls-margin: $btn-xs-side-margin - 2px;
flex: 0 0 100%;
&.controls-flex {
display: flex; display: flex;
flex-flow: row wrap; max-width: 350px;
align-items: center; overflow: hidden;
justify-content: center; float: right;
padding: 0 0 $gl-padding-top;
}
.controls-item,
.controls-item-full,
.controls-item:last-child {
flex: 1 1 35%;
display: block;
width: 100%;
margin: $controls-margin;
}
}
}
.new-project-item-link { .new-project-item-link {
white-space: nowrap; white-space: nowrap;

View file

@ -17,7 +17,7 @@
.select2-arrow { .select2-arrow {
background-image: none; background-image: none;
background-color: transparent; background-color: transparent;
border: none; border: 0;
padding-top: 12px; padding-top: 12px;
padding-right: 20px; padding-right: 20px;
font-size: 10px; font-size: 10px;
@ -60,12 +60,17 @@
border-radius: $border-radius-base; border-radius: $border-radius-base;
border: 1px solid $dropdown-border-color; border: 1px solid $dropdown-border-color;
min-width: 175px; min-width: 175px;
color: $gl-grayish-blue; color: $gl-text-color;
z-index: 999;
} }
.select2-results .select2-result-label, .select2-drop-mask {
.select2-more-results { z-index: 998;
padding: 10px 15px; }
.select2-drop.select2-drop-above.select2-drop-active {
border-top: 1px solid $dropdown-border-color;
margin-top: -6px;
} }
.select2-container-active { .select2-container-active {
@ -158,18 +163,35 @@
} }
} }
.select2-results .select2-no-results,
.select2-results .select2-searching,
.select2-results .select2-ajax-error,
.select2-results .select2-selection-limit {
background: $gray-light;
display: list-item;
padding: 10px 15px;
}
.select2-results { .select2-results {
margin: 0; margin: 0;
padding: 10px 0; padding: #{$gl-padding / 2} 0;
.select2-no-results,
.select2-searching,
.select2-ajax-error,
.select2-selection-limit {
background: transparent;
padding: #{$gl-padding / 2} $gl-padding;
}
.select2-result-label,
.select2-more-results {
padding: #{$gl-padding / 2} $gl-padding;
}
.select2-highlighted {
background: transparent;
color: $gl-text-color;
.select2-result-label {
background: $dropdown-item-hover-bg;
}
}
.select2-result {
padding: 0 1px;
}
li.select2-result-with-children > .select2-result-label { li.select2-result-with-children > .select2-result-label {
font-weight: $gl-font-weight-bold; font-weight: $gl-font-weight-bold;
@ -190,8 +212,6 @@
} }
.select2-highlighted { .select2-highlighted {
background: $gl-link-color !important;
.group-result { .group-result {
.group-path { .group-path {
color: $white-light; color: $white-light;

View file

@ -9,7 +9,7 @@
&.container-blank { &.container-blank {
background: none; background: none;
padding: 0; padding: 0;
border: none; border: 0;
} }
} }
} }
@ -111,7 +111,7 @@
} }
.block:last-of-type { .block:last-of-type {
border: none; border: 0;
} }
} }

View file

@ -33,7 +33,7 @@ table {
th { th {
background-color: $gray-light; background-color: $gray-light;
font-weight: $gl-font-weight-normal; font-weight: $gl-font-weight-normal;
border-bottom: none; border-bottom: 0;
&.wide { &.wide {
width: 55%; width: 55%;

View file

@ -21,7 +21,7 @@
} }
&.text-file .diff-file { &.text-file .diff-file {
border-bottom: none; border-bottom: 0;
} }
} }
@ -66,5 +66,5 @@
.discussion .timeline-entry { .discussion .timeline-entry {
margin: 0; margin: 0;
border-right: none; border-right: 0;
} }

View file

@ -167,7 +167,7 @@
&.plain-readme { &.plain-readme {
background: none; background: none;
border: none; border: 0;
padding: 0; padding: 0;
margin: 0; margin: 0;
font-size: 14px; font-size: 14px;

View file

@ -9,7 +9,7 @@
z-index: 1031; z-index: 1031;
textarea { textarea {
border: none; border: 0;
box-shadow: none; box-shadow: none;
border-radius: 0; border-radius: 0;
color: $black; color: $black;
@ -57,7 +57,15 @@
padding: 5px; padding: 5px;
font-size: 36px; font-size: 36px;
svg {
fill: $gl-text-color;
}
&:hover { &:hover {
color: $black; color: $black;
svg {
fill: $black;
}
} }
} }

View file

@ -48,7 +48,7 @@
overflow-x: auto; overflow-x: auto;
font-size: 12px; font-size: 12px;
border-radius: 0; border-radius: 0;
border: none; border: 0;
.bash { .bash {
display: block; display: block;

View file

@ -36,7 +36,7 @@
pre.commit-message { pre.commit-message {
background: none; background: none;
padding: 0; padding: 0;
border: none; border: 0;
margin: 20px 0; margin: 20px 0;
border-radius: 0; border-radius: 0;
} }

View file

@ -1,6 +1,6 @@
.commit-description { .commit-description {
background: none; background: none;
border: none; border: 0;
padding: 0; padding: 0;
margin-top: 10px; margin-top: 10px;
word-break: normal; word-break: normal;
@ -247,7 +247,7 @@
word-break: normal; word-break: normal;
pre { pre {
border: none; border: 0;
background: inherit; background: inherit;
padding: 0; padding: 0;
margin: 0; margin: 0;

View file

@ -80,7 +80,7 @@
.panel { .panel {
.content-block { .content-block {
padding: 24px 0; padding: 24px 0;
border-bottom: none; border-bottom: 0;
position: relative; position: relative;
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
@ -222,11 +222,11 @@
} }
&:first-child { &:first-child {
border-top: none; border-top: 0;
} }
&:last-child { &:last-child {
border-bottom: none; border-bottom: 0;
} }
.stage-nav-item-cell { .stage-nav-item-cell {
@ -290,7 +290,7 @@
border-bottom: 1px solid $gray-darker; border-bottom: 1px solid $gray-darker;
&:last-child { &:last-child {
border-bottom: none; border-bottom: 0;
margin-bottom: 0; margin-bottom: 0;
} }

View file

@ -47,7 +47,7 @@
table { table {
width: 100%; width: 100%;
font-family: $monospace_font; font-family: $monospace_font;
border: none; border: 0;
border-collapse: separate; border-collapse: separate;
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -105,7 +105,7 @@
.new_line { .new_line {
@include user-select(none); @include user-select(none);
margin: 0; margin: 0;
border: none; border: 0;
padding: 0 5px; padding: 0 5px;
border-right: 1px solid; border-right: 1px solid;
text-align: right; text-align: right;
@ -133,7 +133,7 @@
display: block; display: block;
margin: 0; margin: 0;
padding: 0 1.5em; padding: 0 1.5em;
border: none; border: 0;
position: relative; position: relative;
&.parallel { &.parallel {
@ -359,7 +359,7 @@
cursor: pointer; cursor: pointer;
&:first-child { &:first-child {
border-left: none; border-left: 0;
} }
&:hover { &:hover {
@ -388,7 +388,7 @@
.file-content .diff-file { .file-content .diff-file {
margin: 0; margin: 0;
border: none; border: 0;
} }
.diff-wrap-lines .line_content { .diff-wrap-lines .line_content {
@ -400,7 +400,7 @@
} }
.files-changed { .files-changed {
border-bottom: none; border-bottom: 0;
} }
.diff-stats-summary-toggler { .diff-stats-summary-toggler {

View file

@ -3,13 +3,13 @@
border-top: 1px solid $border-color; border-top: 1px solid $border-color;
border-right: 1px solid $border-color; border-right: 1px solid $border-color;
border-left: 1px solid $border-color; border-left: 1px solid $border-color;
border-bottom: none; border-bottom: 0;
border-radius: $border-radius-small $border-radius-small 0 0; border-radius: $border-radius-small $border-radius-small 0 0;
background: $gray-normal; background: $gray-normal;
} }
#editor { #editor {
border: none; border: 0;
border-radius: 0; border-radius: 0;
height: 500px; height: 500px;
margin: 0; margin: 0;
@ -171,7 +171,7 @@
width: 100%; width: 100%;
margin: 5px 0; margin: 5px 0;
padding: 0; padding: 0;
border-left: none; border-left: 0;
} }
} }

View file

@ -117,7 +117,7 @@
} }
.no-btn { .no-btn {
border: none; border: 0;
background: none; background: none;
outline: none; outline: none;
width: 100%; width: 100%;
@ -133,11 +133,11 @@
} }
.folder-row { .folder-row {
border-left: none; border-left: 0;
border-right: none; border-right: 0;
@media (min-width: $screen-sm-max) { @media (min-width: $screen-sm-max) {
border-top: none; border-top: 0;
} }
} }
@ -256,12 +256,6 @@
padding: 0; padding: 0;
padding-bottom: 100%; padding-bottom: 100%;
.label-axis-text {
fill: $black;
font-weight: $gl-font-weight-normal;
font-size: 10px;
}
.text-metric-usage, .text-metric-usage,
.legend-metric-title { .legend-metric-title {
fill: $black; fill: $black;
@ -276,20 +270,34 @@
left: 0; left: 0;
top: 0; top: 0;
.label-axis-text, text {
.text-metric-usage { fill: $gl-text-color;
stroke-width: 0;
}
.text-metric-bold {
font-weight: $gl-font-weight-bold;
}
.label-axis-text {
fill: $black; fill: $black;
font-weight: $gl-font-weight-normal; font-weight: $gl-font-weight-normal;
font-size: 12px; font-size: 10px;
} }
.legend-axis-text { .legend-axis-text {
fill: $black; fill: $black;
} }
.tick > text { .tick {
> line {
stroke: $gray-darker;
}
> text {
font-size: 12px; font-size: 12px;
} }
}
.text-metric-title { .text-metric-title {
font-size: 12px; font-size: 12px;

View file

@ -85,7 +85,7 @@
} }
pre { pre {
border: none; border: 0;
background: $gray-light; background: $gray-light;
border-radius: 0; border-radius: 0;
color: $events-pre-color; color: $events-pre-color;
@ -128,14 +128,14 @@
} }
} }
&:last-child { border: none; } &:last-child { border: 0; }
.event_commits { .event_commits {
li { li {
&.commit { &.commit {
background: transparent; background: transparent;
padding: 0; padding: 0;
border: none; border: 0;
.commit-row-title { .commit-row-title {
font-size: $gl-font-size; font-size: $gl-font-size;

View file

@ -79,7 +79,7 @@
.title { .title {
padding: 0; padding: 0;
margin-bottom: 16px; margin-bottom: 16px;
border-bottom: none; border-bottom: 0;
} }
.btn-edit { .btn-edit {
@ -131,12 +131,12 @@
top: $header-height; top: $header-height;
bottom: 0; bottom: 0;
right: 0; right: 0;
transition: width .3s; transition: width $right-sidebar-transition-duration;
background: $gray-light; background: $gray-light;
z-index: 200; z-index: 200;
overflow: hidden; overflow: hidden;
a, a:not(.btn-retry),
.btn-link { .btn-link {
color: inherit; color: inherit;
} }
@ -164,7 +164,7 @@
} }
&:last-child { &:last-child {
border: none; border: 0;
} }
span { span {
@ -338,7 +338,7 @@
.block { .block {
width: $gutter_collapsed_width - 2px; width: $gutter_collapsed_width - 2px;
padding: 15px 0 0; padding: 15px 0 0;
border-bottom: none; border-bottom: 0;
overflow: hidden; overflow: hidden;
} }
@ -399,7 +399,7 @@
} }
.btn-clipboard { .btn-clipboard {
border: none; border: 0;
color: $issuable-sidebar-color; color: $issuable-sidebar-color;
&:hover { &:hover {

View file

@ -139,7 +139,7 @@
border-left: 1px solid $border-color; border-left: 1px solid $border-color;
&:first-of-type { &:first-of-type {
border-left: none; border-left: 0;
border-top-left-radius: $border-radius-default; border-top-left-radius: $border-radius-default;
} }
@ -165,7 +165,7 @@
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
a { a {
border: none; border: 0;
border-bottom: 2px solid $link-underline-blue; border-bottom: 2px solid $link-underline-blue;
margin-right: 0; margin-right: 0;
color: $black; color: $black;

View file

@ -262,7 +262,7 @@ $colors: (
.editor { .editor {
pre { pre {
height: 350px; height: 350px;
border: none; border: 0;
border-radius: 0; border-radius: 0;
margin-bottom: 0; margin-bottom: 0;
} }

View file

@ -150,18 +150,6 @@
display: block; display: block;
} }
.mr-widget-body {
@include clearfix;
&.media > *:first-child {
margin-right: 10px;
}
.approve-btn {
margin-right: 5px;
}
}
.mr-widget-pipeline-graph { .mr-widget-pipeline-graph {
padding: 0 4px; padding: 0 4px;
@ -169,9 +157,8 @@
z-index: 300; z-index: 300;
} }
.ci-action-icon-wrapper svg { .ci-action-icon-wrapper {
width: 16px; line-height: 16px;
height: 16px;
} }
} }
@ -195,10 +182,6 @@
overflow: hidden; overflow: hidden;
word-break: break-all; word-break: break-all;
&.media > *:first-child {
margin-right: 10px;
}
&.label-truncated { &.label-truncated {
position: relative; position: relative;
display: inline-block; display: inline-block;
@ -216,6 +199,18 @@
background-color: $gray-light; background-color: $gray-light;
} }
} }
}
.mr-widget-body {
@include clearfix;
&.media > *:first-child {
margin-right: 10px;
}
.approve-btn {
margin-right: 5px;
}
h4 { h4 {
float: left; float: left;
@ -239,10 +234,6 @@
margin-right: 7px; margin-right: 7px;
} }
.approve-btn {
margin-right: 5px;
}
label { label {
font-weight: $gl-font-weight-normal; font-weight: $gl-font-weight-normal;
} }
@ -342,17 +333,6 @@
} }
} }
.mini-pipeline-graph-dropdown-menu .mini-pipeline-graph-dropdown-item {
display: flex;
align-items: center;
.ci-status-text,
.ci-status-icon {
top: 0;
margin-right: 10px;
}
}
.mr-widget-help { .mr-widget-help {
padding: 10px 16px 10px 48px; padding: 10px 16px 10px 48px;
font-style: italic; font-style: italic;

View file

@ -16,7 +16,7 @@
.discussion { .discussion {
.new-note { .new-note {
margin: 0; margin: 0;
border: none; border: 0;
} }
} }
@ -106,15 +106,35 @@
background-color: $orange-100; background-color: $orange-100;
border-radius: $border-radius-default $border-radius-default 0 0; border-radius: $border-radius-default $border-radius-default 0 0;
border: 1px solid $border-gray-normal; border: 1px solid $border-gray-normal;
border-bottom: none; border-bottom: 0;
padding: 3px 12px; padding: 3px 12px;
margin: auto; margin: auto;
align-items: center; align-items: center;
.icon {
margin-right: $issuable-warning-icon-margin;
}
+ .md-area { + .md-area {
border-top-left-radius: 0; border-top-left-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
} }
.disabled-comment {
border: none;
border-radius: $label-border-radius;
padding-top: $gl-vert-padding;
padding-bottom: $gl-vert-padding;
.icon svg {
position: relative;
top: 2px;
margin-right: $btn-xs-side-margin;
width: $gl-font-size;
height: $gl-font-size;
fill: $orange-600;
}
}
} }
.sidebar-item-value { .sidebar-item-value {

View file

@ -331,7 +331,7 @@ ul.notes {
td { td {
border: 1px solid $white-normal; border: 1px solid $white-normal;
border-left: none; border-left: 0;
&.notes_line { &.notes_line {
vertical-align: middle; vertical-align: middle;
@ -476,6 +476,10 @@ ul.notes {
float: none; float: none;
margin-left: 0; margin-left: 0;
} }
.btn-group > .discussion-next-btn {
margin-left: -1px;
}
} }
.note-actions { .note-actions {
@ -666,7 +670,7 @@ ul.notes {
.timeline-entry-inner { .timeline-entry-inner {
padding-left: $gl-padding; padding-left: $gl-padding;
padding-right: $gl-padding; padding-right: $gl-padding;
border-bottom: none; border-bottom: 0;
} }
} }
} }
@ -679,7 +683,7 @@ ul.notes {
padding: 90px 0; padding: 90px 0;
&.discussion-locked { &.discussion-locked {
border: none; border: 0;
background-color: $white-light; background-color: $white-light;
} }
@ -759,7 +763,7 @@ ul.notes {
top: 0; top: 0;
padding: 0; padding: 0;
background-color: transparent; background-color: transparent;
border: none; border: 0;
outline: 0; outline: 0;
color: $gray-darkest; color: $gray-darkest;
transition: color $general-hover-transition-duration $general-hover-transition-curve; transition: color $general-hover-transition-duration $general-hover-transition-curve;

View file

@ -179,7 +179,7 @@
* Play button with icon in dropdowns * Play button with icon in dropdowns
*/ */
.no-btn { .no-btn {
border: none; border: 0;
background: none; background: none;
outline: none; outline: none;
width: 100%; width: 100%;
@ -288,7 +288,7 @@
.pipeline-actions { .pipeline-actions {
@include new-style-dropdown; @include new-style-dropdown;
border-bottom: none; border-bottom: 0;
} }
.tab-pane { .tab-pane {
@ -318,7 +318,7 @@
} }
.build-log { .build-log {
border: none; border: 0;
line-height: initial; line-height: initial;
} }
} }
@ -386,13 +386,13 @@
// Remove right connecting horizontal line from first build in last stage // Remove right connecting horizontal line from first build in last stage
&:first-child { &:first-child {
&::after { &::after {
border: none; border: 0;
} }
} }
// Remove right curved connectors from all builds in last stage // Remove right curved connectors from all builds in last stage
&:not(:first-child) { &:not(:first-child) {
&::after { &::after {
border: none; border: 0;
} }
} }
// Remove opposite curve // Remove opposite curve
@ -409,7 +409,7 @@
// Remove left curved connectors from all builds in first stage // Remove left curved connectors from all builds in first stage
&:not(:first-child) { &:not(:first-child) {
&::before { &::before {
border: none; border: 0;
} }
} }
// Remove opposite curve // Remove opposite curve
@ -518,7 +518,7 @@
.dropdown-menu-toggle { .dropdown-menu-toggle {
background-color: transparent; background-color: transparent;
border: none; border: 0;
padding: 0; padding: 0;
&:focus { &:focus {
@ -823,6 +823,11 @@ button.mini-pipeline-graph-dropdown-toggle {
margin-left: 2px; margin-left: 2px;
display: inline-block; display: inline-block;
&::after {
content: '';
display: block;
}
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
max-width: 60%; max-width: 60%;
} }
@ -951,7 +956,7 @@ button.mini-pipeline-graph-dropdown-toggle {
.terminal-container { .terminal-container {
.content-block { .content-block {
border-bottom: none; border-bottom: 0;
} }
#terminal { #terminal {

View file

@ -113,7 +113,7 @@
li { li {
padding: 3px 0; padding: 3px 0;
border: none; border: 0;
} }
} }

View file

@ -80,7 +80,7 @@
.project-feature-settings { .project-feature-settings {
background: $gray-lighter; background: $gray-lighter;
border-top: none; border-top: 0;
margin-bottom: 16px; margin-bottom: 16px;
} }
@ -128,7 +128,7 @@
.project-feature-toggle { .project-feature-toggle {
position: relative; position: relative;
border: none; border: 0;
outline: 0; outline: 0;
display: block; display: block;
width: 100px; width: 100px;
@ -483,7 +483,7 @@ a.deploy-project-label {
flex: 1; flex: 1;
padding: 0; padding: 0;
background: transparent; background: transparent;
border: none; border: 0;
line-height: 34px; line-height: 34px;
margin: 0; margin: 0;
@ -1012,7 +1012,7 @@ pre.light-well {
margin: 0; margin: 0;
border-radius: 0 0 1px 1px; border-radius: 0 0 1px 1px;
padding: 20px 0; padding: 20px 0;
border: none; border: 0;
} }
.table-bordered { .table-bordered {
@ -1165,7 +1165,7 @@ pre.light-well {
table-layout: fixed; table-layout: fixed;
&.table-responsive { &.table-responsive {
border: none; border: 0;
} }
.variable-key { .variable-key {

View file

@ -64,7 +64,7 @@
.monaco-editor.vs { .monaco-editor.vs {
.current-line { .current-line {
border: none; border: 0;
background: $well-light-border; background: $well-light-border;
} }
@ -139,7 +139,7 @@
&.active { &.active {
background: $white-light; background: $white-light;
border-bottom: none; border-bottom: 0;
} }
a { a {
@ -181,7 +181,7 @@
&.tabs-divider { &.tabs-divider {
width: 100%; width: 100%;
background-color: $white-light; background-color: $white-light;
border-right: none; border-right: 0;
border-top-right-radius: 2px; border-top-right-radius: 2px;
} }
} }

View file

@ -5,7 +5,7 @@
margin-bottom: $gl-padding; margin-bottom: $gl-padding;
&:last-child { &:last-child {
border-bottom: none; border-bottom: 0;
} }
} }
@ -57,7 +57,7 @@ input[type="checkbox"]:hover {
} }
.search-input { .search-input {
border: none; border: 0;
font-size: 14px; font-size: 14px;
padding: 0 20px 0 0; padding: 0 20px 0 0;
margin-left: 5px; margin-left: 5px;
@ -78,10 +78,6 @@ input[type="checkbox"]:hover {
} }
.search-input-wrap { .search-input-wrap {
// Fallback if flexbox is not supported
display: inline-block;
width: 100%;
.search-icon, .search-icon,
.clear-icon { .clear-icon {
position: absolute; position: absolute;

View file

@ -141,7 +141,7 @@
} }
pre { pre {
border: none; border: 0;
background: $gray-light; background: $gray-light;
border-radius: 0; border-radius: 0;
color: $todo-body-pre-color; color: $todo-body-pre-color;

View file

@ -252,7 +252,7 @@
margin-top: 20px; margin-top: 20px;
padding: 0; padding: 0;
border-top: 1px solid $white-dark; border-top: 1px solid $white-dark;
border-bottom: none; border-bottom: 0;
} }
.commit-stats li { .commit-stats li {

View file

@ -57,12 +57,11 @@ module IssuableActions
def destroy def destroy
issuable.destroy issuable.destroy
destroy_method = "destroy_#{issuable.class.name.underscore}".to_sym TodoService.new.destroy_issuable(issuable, current_user)
TodoService.new.public_send(destroy_method, issuable, current_user) # rubocop:disable GitlabSecurity/PublicSend
name = issuable.human_class_name name = issuable.human_class_name
flash[:notice] = "The #{name} was successfully deleted." flash[:notice] = "The #{name} was successfully deleted."
index_path = polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable.class]) index_path = polymorphic_path([parent, issuable.class])
respond_to do |format| respond_to do |format|
format.html { redirect_to index_path } format.html { redirect_to index_path }
@ -164,4 +163,8 @@ module IssuableActions
def update_service def update_service
raise NotImplementedError raise NotImplementedError
end end
def parent
@project || @group
end
end end

View file

@ -39,7 +39,7 @@ module NotesActions
@note = Notes::CreateService.new(note_project, current_user, create_params).execute @note = Notes::CreateService.new(note_project, current_user, create_params).execute
if @note.is_a?(Note) if @note.is_a?(Note)
Banzai::NoteRenderer.render([@note], @project, current_user) Notes::RenderService.new(current_user).execute([@note], @project)
end end
respond_to do |format| respond_to do |format|
@ -52,7 +52,7 @@ module NotesActions
@note = Notes::UpdateService.new(project, current_user, note_params).execute(note) @note = Notes::UpdateService.new(project, current_user, note_params).execute(note)
if @note.is_a?(Note) if @note.is_a?(Note)
Banzai::NoteRenderer.render([@note], @project, current_user) Notes::RenderService.new(current_user).execute([@note], @project)
end end
respond_to do |format| respond_to do |format|

View file

@ -3,7 +3,7 @@ module RendersNotes
preload_noteable_for_regular_notes(notes) preload_noteable_for_regular_notes(notes)
preload_max_access_for_authors(notes, @project) preload_max_access_for_authors(notes, @project)
preload_first_time_contribution_for_authors(noteable, notes) preload_first_time_contribution_for_authors(noteable, notes)
Banzai::NoteRenderer.render(notes, @project, current_user) Notes::RenderService.new(current_user).execute(notes, @project)
notes notes
end end

View file

@ -57,5 +57,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
@events = EventCollection @events = EventCollection
.new(projects, offset: params[:offset].to_i, filter: event_filter) .new(projects, offset: params[:offset].to_i, filter: event_filter)
.to_a .to_a
Events::RenderService.new(current_user).execute(@events, atom_request: request.format.atom?)
end end
end end

View file

@ -32,6 +32,8 @@ class DashboardController < Dashboard::ApplicationController
@events = EventCollection @events = EventCollection
.new(projects, offset: params[:offset].to_i, filter: @event_filter) .new(projects, offset: params[:offset].to_i, filter: @event_filter)
.to_a .to_a
Events::RenderService.new(current_user).execute(@events)
end end
def set_show_full_reference def set_show_full_reference

View file

@ -155,6 +155,8 @@ class GroupsController < Groups::ApplicationController
@events = EventCollection @events = EventCollection
.new(@projects, offset: params[:offset].to_i, filter: event_filter) .new(@projects, offset: params[:offset].to_i, filter: event_filter)
.to_a .to_a
Events::RenderService.new(current_user).execute(@events, atom_request: request.format.atom?)
end end
def user_actions def user_actions

View file

@ -3,10 +3,16 @@ class MetricsController < ActionController::Base
protect_from_forgery with: :exception protect_from_forgery with: :exception
before_action :validate_prometheus_metrics
def index def index
render text: metrics_service.metrics_text, content_type: 'text/plain; version=0.0.4' response = if Gitlab::Metrics.prometheus_metrics_enabled?
metrics_service.metrics_text
else
help_page = help_page_url('administration/monitoring/prometheus/gitlab_metrics',
anchor: 'gitlab-prometheus-metrics'
)
"# Metrics are disabled, see: #{help_page}\n"
end
render text: response, content_type: 'text/plain; version=0.0.4'
end end
private private
@ -14,8 +20,4 @@ class MetricsController < ActionController::Base
def metrics_service def metrics_service
@metrics_service ||= MetricsService.new @metrics_service ||= MetricsService.new
end end
def validate_prometheus_metrics
render_404 unless Gitlab::Metrics.prometheus_metrics_enabled?
end
end end

View file

@ -2,7 +2,6 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont
before_action :check_merge_requests_available! before_action :check_merge_requests_available!
before_action :merge_request before_action :merge_request
before_action :authorize_read_merge_request! before_action :authorize_read_merge_request!
before_action :ensure_ref_fetched
private private
@ -10,12 +9,6 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont
@issuable = @merge_request ||= @project.merge_requests.find_by!(iid: params[:id]) @issuable = @merge_request ||= @project.merge_requests.find_by!(iid: params[:id])
end end
# Make sure merge requests created before 8.0
# have head file in refs/merge-requests/
def ensure_ref_fetched
@merge_request.ensure_ref_fetched if Gitlab::Database.read_write?
end
def merge_request_params def merge_request_params
params.require(:merge_request).permit(merge_request_params_attributes) params.require(:merge_request).permit(merge_request_params_attributes)
end end

View file

@ -4,7 +4,6 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
include RendersCommits include RendersCommits
skip_before_action :merge_request skip_before_action :merge_request
skip_before_action :ensure_ref_fetched
before_action :authorize_create_merge_request! before_action :authorize_create_merge_request!
before_action :apply_diff_view_cookie!, only: [:diffs, :diff_for_path] before_action :apply_diff_view_cookie!, only: [:diffs, :diff_for_path]
before_action :build_merge_request, except: [:create] before_action :build_merge_request, except: [:create]

View file

@ -7,7 +7,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
include IssuableCollections include IssuableCollections
skip_before_action :merge_request, only: [:index, :bulk_update] skip_before_action :merge_request, only: [:index, :bulk_update]
skip_before_action :ensure_ref_fetched, only: [:index, :bulk_update]
before_action :authorize_update_issuable!, only: [:close, :edit, :update, :remove_wip, :sort] before_action :authorize_update_issuable!, only: [:close, :edit, :update, :remove_wip, :sort]
@ -52,7 +51,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
def show def show
validates_merge_request validates_merge_request
ensure_ref_fetched
close_merge_request_without_source_project close_merge_request_without_source_project
check_if_can_be_merged check_if_can_be_merged

View file

@ -300,6 +300,8 @@ class ProjectsController < Projects::ApplicationController
@events = EventCollection @events = EventCollection
.new(projects, offset: params[:offset].to_i, filter: event_filter) .new(projects, offset: params[:offset].to_i, filter: event_filter)
.to_a .to_a
Events::RenderService.new(current_user).execute(@events, atom_request: request.format.atom?)
end end
def project_params def project_params

View file

@ -108,6 +108,8 @@ class UsersController < ApplicationController
.references(:project) .references(:project)
.with_associations .with_associations
.limit_recent(20, params[:offset]) .limit_recent(20, params[:offset])
Events::RenderService.new(current_user).execute(@events, atom_request: request.format.atom?)
end end
def load_projects def load_projects

View file

@ -172,16 +172,6 @@ module EventsHelper
end end
end end
def event_note(text, options = {})
text = first_line_in_markdown(text, 150, options)
sanitize(
text,
tags: %w(a img gl-emoji b pre code p span),
attributes: Rails::Html::WhiteListSanitizer.allowed_attributes + ['style', 'data-src', 'data-name', 'data-unicode-version']
)
end
def event_commit_title(message) def event_commit_title(message)
message ||= '' message ||= ''
(message.split("\n").first || "").truncate(70) (message.split("\n").first || "").truncate(70)

View file

@ -69,10 +69,16 @@ module MarkupHelper
# as Markdown. HTML tags in the parsed output are not counted toward the # as Markdown. HTML tags in the parsed output are not counted toward the
# +max_chars+ limit. If the length limit falls within a tag's contents, then # +max_chars+ limit. If the length limit falls within a tag's contents, then
# the tag contents are truncated without removing the closing tag. # the tag contents are truncated without removing the closing tag.
def first_line_in_markdown(text, max_chars = nil, options = {}) def first_line_in_markdown(object, attribute, max_chars = nil, options = {})
md = markdown(text, options).strip md = markdown_field(object, attribute, options)
truncate_visible(md, max_chars || md.length) if md.present? text = truncate_visible(md, max_chars || md.length) if md.present?
sanitize(
text,
tags: %w(a img gl-emoji b pre code p span),
attributes: Rails::Html::WhiteListSanitizer.allowed_attributes + ['style', 'data-src', 'data-name', 'data-unicode-version']
)
end end
def markdown(text, context = {}) def markdown(text, context = {})
@ -83,15 +89,17 @@ module MarkupHelper
prepare_for_rendering(html, context) prepare_for_rendering(html, context)
end end
def markdown_field(object, field) def markdown_field(object, field, context = {})
object = object.for_display if object.respond_to?(:for_display) object = object.for_display if object.respond_to?(:for_display)
redacted_field_html = object.try(:"redacted_#{field}_html") redacted_field_html = object.try(:"redacted_#{field}_html")
return '' unless object.present? return '' unless object.present?
return redacted_field_html if redacted_field_html return redacted_field_html if redacted_field_html
html = Banzai.render_field(object, field) html = Banzai.render_field(object, field, context)
prepare_for_rendering(html, object.banzai_render_context(field)) context.reverse_merge!(object.banzai_render_context(field)) if object.respond_to?(:banzai_render_context)
prepare_for_rendering(html, context)
end end
def markup(file_name, text, context = {}) def markup(file_name, text, context = {})
@ -218,7 +226,7 @@ module MarkupHelper
data: data, data: data,
title: options[:title], title: options[:title],
aria: { label: options[:title] } do aria: { label: options[:title] } do
icon(options[:icon]) sprite_icon(options[:icon])
end end
end end

View file

@ -55,7 +55,7 @@ module Clusters
before_transition any => [:creating] do |provider, transition| before_transition any => [:creating] do |provider, transition|
operation_id = transition.args.first operation_id = transition.args.first
raise 'operation_id is required' unless operation_id raise ArgumentError.new('operation_id is required') unless operation_id.present?
provider.operation_id = operation_id provider.operation_id = operation_id
end end

View file

@ -21,8 +21,8 @@ module IgnorableColumn
@ignored_columns ||= Set.new @ignored_columns ||= Set.new
end end
def ignore_column(name) def ignore_column(*names)
ignored_columns << name.to_s ignored_columns.merge(names.map(&:to_s))
end end
end end
end end

View file

@ -8,7 +8,8 @@ class MergeRequest < ActiveRecord::Base
include CreatedAtFilterable include CreatedAtFilterable
include TimeTrackable include TimeTrackable
ignore_column :locked_at ignore_column :locked_at,
:ref_fetched
belongs_to :target_project, class_name: "Project" belongs_to :target_project, class_name: "Project"
belongs_to :source_project, class_name: "Project" belongs_to :source_project, class_name: "Project"
@ -426,7 +427,7 @@ class MergeRequest < ActiveRecord::Base
end end
def create_merge_request_diff def create_merge_request_diff
fetch_ref fetch_ref!
# n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/37435 # n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/37435
Gitlab::GitalyClient.allow_n_plus_1_calls do Gitlab::GitalyClient.allow_n_plus_1_calls do
@ -811,29 +812,14 @@ class MergeRequest < ActiveRecord::Base
end end
end end
def fetch_ref def fetch_ref!
write_ref target_project.repository.fetch_source_branch!(source_project.repository, source_branch, ref_path)
update_column(:ref_fetched, true)
end end
def ref_path def ref_path
"refs/#{Repository::REF_MERGE_REQUEST}/#{iid}/head" "refs/#{Repository::REF_MERGE_REQUEST}/#{iid}/head"
end end
def ref_fetched?
super ||
begin
computed_value = project.repository.ref_exists?(ref_path)
update_column(:ref_fetched, true) if computed_value
computed_value
end
end
def ensure_ref_fetched
fetch_ref unless ref_fetched?
end
def in_locked_state def in_locked_state
begin begin
lock_mr lock_mr
@ -975,10 +961,4 @@ class MergeRequest < ActiveRecord::Base
project.merge_requests.merged.where(author_id: author_id).empty? project.merge_requests.merged.where(author_id: author_id).empty?
end end
private
def write_ref
target_project.repository.fetch_source_branch(source_project.repository, source_branch, ref_path)
end
end end

View file

@ -36,7 +36,7 @@ class Namespace < ActiveRecord::Base
validates :path, validates :path,
presence: true, presence: true,
length: { maximum: 255 }, length: { maximum: 255 },
dynamic_path: true namespace_path: true
validate :nesting_level_allowed validate :nesting_level_allowed

View file

@ -242,10 +242,8 @@ class Project < ActiveRecord::Base
message: Gitlab::Regex.project_name_regex_message } message: Gitlab::Regex.project_name_regex_message }
validates :path, validates :path,
presence: true, presence: true,
dynamic_path: true, project_path: true,
length: { maximum: 255 }, length: { maximum: 255 },
format: { with: Gitlab::PathRegex.project_path_format_regex,
message: Gitlab::PathRegex.project_path_format_message },
uniqueness: { scope: :namespace_id } uniqueness: { scope: :namespace_id }
validates :namespace, presence: true validates :namespace, presence: true

View file

@ -969,8 +969,8 @@ class Repository
gitlab_shell.fetch_remote(raw_repository, remote, ssh_auth: ssh_auth, forced: forced, no_tags: no_tags) gitlab_shell.fetch_remote(raw_repository, remote, ssh_auth: ssh_auth, forced: forced, no_tags: no_tags)
end end
def fetch_source_branch(source_repository, source_branch, local_ref) def fetch_source_branch!(source_repository, source_branch, local_ref)
raw_repository.fetch_source_branch(source_repository.raw_repository, source_branch, local_ref) raw_repository.fetch_source_branch!(source_repository.raw_repository, source_branch, local_ref)
end end
def compare_source_branch(target_branch_name, source_repository, source_branch_name, straight:) def compare_source_branch(target_branch_name, source_repository, source_branch_name, straight:)

View file

@ -146,7 +146,7 @@ class User < ActiveRecord::Base
presence: true, presence: true,
numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: Gitlab::Database::MAX_INT_VALUE } numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: Gitlab::Database::MAX_INT_VALUE }
validates :username, validates :username,
dynamic_path: true, user_path: true,
presence: true, presence: true,
uniqueness: { case_sensitive: false } uniqueness: { case_sensitive: false }
@ -164,7 +164,7 @@ class User < ActiveRecord::Base
before_validation :set_notification_email, if: :email_changed? before_validation :set_notification_email, if: :email_changed?
before_validation :set_public_email, if: :public_email_changed? before_validation :set_public_email, if: :public_email_changed?
before_save :ensure_incoming_email_token before_save :ensure_incoming_email_token
before_save :ensure_user_rights_and_limits, if: :external_changed? before_save :ensure_user_rights_and_limits, if: ->(user) { user.new_record? || user.external_changed? }
before_save :skip_reconfirmation!, if: ->(user) { user.email_changed? && user.read_only_attribute?(:email) } before_save :skip_reconfirmation!, if: ->(user) { user.email_changed? && user.read_only_attribute?(:email) }
before_save :check_for_verified_email, if: ->(user) { user.email_changed? && !user.new_record? } before_save :check_for_verified_email, if: ->(user) { user.email_changed? && !user.new_record? }
after_save :ensure_namespace_correct after_save :ensure_namespace_correct
@ -1139,8 +1139,9 @@ class User < ActiveRecord::Base
self.can_create_group = false self.can_create_group = false
self.projects_limit = 0 self.projects_limit = 0
else else
self.can_create_group = gitlab_config.default_can_create_group # Only revert these back to the default if they weren't specifically changed in this update.
self.projects_limit = current_application_settings.default_projects_limit self.can_create_group = gitlab_config.default_can_create_group unless can_create_group_changed?
self.projects_limit = current_application_settings.default_projects_limit unless projects_limit_changed?
end end
end end

View file

@ -0,0 +1,7 @@
class BaseRenderer
attr_reader :current_user
def initialize(current_user = nil)
@current_user = current_user
end
end

View file

@ -0,0 +1,21 @@
module Events
class RenderService < BaseRenderer
def execute(events, atom_request: false)
events.map(&:note).compact.group_by(&:project).each do |project, notes|
render_notes(notes, project, atom_request)
end
end
private
def render_notes(notes, project, atom_request)
Notes::RenderService.new(current_user).execute(notes, project, render_options(atom_request))
end
def render_options(atom_request)
return {} unless atom_request
{ only_path: false, xhtml: true }
end
end
end

View file

@ -0,0 +1,21 @@
module Notes
class RenderService < BaseRenderer
# Renders a collection of Note instances.
#
# notes - The notes to render.
# project - The project to use for redacting.
# user - The user viewing the notes.
# Possible options:
# requested_path - The request path.
# project_wiki - The project's wiki.
# ref - The current Git reference.
# only_path - flag to turn relative paths into absolute ones.
# xhtml - flag to save the html in XHTML
def execute(notes, project, **opts)
renderer = Banzai::ObjectRenderer.new(project, current_user, **opts)
renderer.render(notes, :note)
end
end
end

View file

@ -31,12 +31,12 @@ class TodoService
mark_pending_todos_as_done(issue, current_user) mark_pending_todos_as_done(issue, current_user)
end end
# When we destroy an issue we should: # When we destroy an issuable we should:
# #
# * refresh the todos count cache for the current user # * refresh the todos count cache for the current user
# #
def destroy_issue(issue, current_user) def destroy_issuable(issuable, user)
destroy_issuable(issue, current_user) user.update_todos_count_cache
end end
# When we reassign an issue we should: # When we reassign an issue we should:
@ -72,14 +72,6 @@ class TodoService
mark_pending_todos_as_done(merge_request, current_user) mark_pending_todos_as_done(merge_request, current_user)
end end
# When we destroy a merge request we should:
#
# * refresh the todos count cache for the current user
#
def destroy_merge_request(merge_request, current_user)
destroy_issuable(merge_request, current_user)
end
# When we reassign a merge request we should: # When we reassign a merge request we should:
# #
# * creates a pending todo for new assignee if merge request is assigned # * creates a pending todo for new assignee if merge request is assigned
@ -234,10 +226,6 @@ class TodoService
create_mention_todos(issuable.project, issuable, author, nil, skip_users) create_mention_todos(issuable.project, issuable, author, nil, skip_users)
end end
def destroy_issuable(issuable, user)
user.update_todos_count_cache
end
def toggling_tasks?(issuable) def toggling_tasks?(issuable)
issuable.previous_changes.include?('description') && issuable.previous_changes.include?('description') &&
issuable.tasks? && issuable.updated_tasks.any? issuable.tasks? && issuable.updated_tasks.any?

View file

@ -25,7 +25,7 @@ module Users
user.block user.block
# Reverse the user block if record migration fails # Reverse the user block if record migration fails
if !migrate_records && transition if !migrate_records_in_transaction && transition
transition.rollback transition.rollback
user.save! user.save!
end end
@ -36,17 +36,21 @@ module Users
private private
def migrate_records def migrate_records_in_transaction
user.transaction(requires_new: true) do user.transaction(requires_new: true) do
@ghost_user = User.ghost @ghost_user = User.ghost
migrate_records
end
end
def migrate_records
migrate_issues migrate_issues
migrate_merge_requests migrate_merge_requests
migrate_notes migrate_notes
migrate_abuse_reports migrate_abuse_reports
migrate_award_emojis migrate_award_emojis
end end
end
def migrate_issues def migrate_issues
user.issues.update_all(author_id: ghost_user.id) user.issues.update_all(author_id: ghost_user.id)

View file

@ -0,0 +1,38 @@
class AbstractPathValidator < ActiveModel::EachValidator
extend Gitlab::EncodingHelper
def self.path_regex
raise NotImplementedError
end
def self.format_regex
raise NotImplementedError
end
def self.format_error_message
raise NotImplementedError
end
def self.full_path(record, value)
value
end
def self.valid_path?(path)
encode!(path)
"#{path}/" =~ path_regex
end
def validate_each(record, attribute, value)
unless value =~ self.class.format_regex
record.errors.add(attribute, self.class.format_error_message)
return
end
full_path = self.class.full_path(record, value)
return unless full_path
unless self.class.valid_path?(full_path)
record.errors.add(attribute, "#{value} is a reserved name")
end
end
end

View file

@ -1,53 +0,0 @@
# DynamicPathValidator
#
# Custom validator for GitLab path values.
# These paths are assigned to `Namespace` (& `Group` as a subclass) & `Project`
#
# Values are checked for formatting and exclusion from a list of illegal path
# names.
class DynamicPathValidator < ActiveModel::EachValidator
extend Gitlab::EncodingHelper
class << self
def valid_user_path?(path)
encode!(path)
"#{path}/" =~ Gitlab::PathRegex.root_namespace_path_regex
end
def valid_group_path?(path)
encode!(path)
"#{path}/" =~ Gitlab::PathRegex.full_namespace_path_regex
end
def valid_project_path?(path)
encode!(path)
"#{path}/" =~ Gitlab::PathRegex.full_project_path_regex
end
end
def path_valid_for_record?(record, value)
full_path = record.respond_to?(:build_full_path) ? record.build_full_path : value
return true unless full_path
case record
when Project
self.class.valid_project_path?(full_path)
when Group
self.class.valid_group_path?(full_path)
else # User or non-Group Namespace
self.class.valid_user_path?(full_path)
end
end
def validate_each(record, attribute, value)
unless value =~ Gitlab::PathRegex.namespace_format_regex
record.errors.add(attribute, Gitlab::PathRegex.namespace_format_message)
return
end
unless path_valid_for_record?(record, value)
record.errors.add(attribute, "#{value} is a reserved name")
end
end
end

View file

@ -0,0 +1,19 @@
class NamespacePathValidator < AbstractPathValidator
extend Gitlab::EncodingHelper
def self.path_regex
Gitlab::PathRegex.full_namespace_path_regex
end
def self.format_regex
Gitlab::PathRegex.namespace_format_regex
end
def self.format_error_message
Gitlab::PathRegex.namespace_format_message
end
def self.full_path(record, value)
record.build_full_path
end
end

View file

@ -0,0 +1,19 @@
class ProjectPathValidator < AbstractPathValidator
extend Gitlab::EncodingHelper
def self.path_regex
Gitlab::PathRegex.full_project_path_regex
end
def self.format_regex
Gitlab::PathRegex.project_path_format_regex
end
def self.format_error_message
Gitlab::PathRegex.project_path_format_message
end
def self.full_path(record, value)
record.build_full_path
end
end

View file

@ -0,0 +1,15 @@
class UserPathValidator < AbstractPathValidator
extend Gitlab::EncodingHelper
def self.path_regex
Gitlab::PathRegex.root_namespace_path_regex
end
def self.format_regex
Gitlab::PathRegex.namespace_format_regex
end
def self.format_error_message
Gitlab::PathRegex.namespace_format_message
end
end

View file

@ -42,4 +42,4 @@
.panel.panel-default .panel.panel-default
%iframe{ src: sidekiq_path, width: '100%', height: 970, style: "border: none" } %iframe{ src: sidekiq_path, width: '100%', height: 970, style: "border: 0" }

View file

@ -36,7 +36,7 @@
.todo-body .todo-body
.todo-note .todo-note
.md .md
= event_note(todo.body, project: todo.project) = first_line_in_markdown(todo, :body, 150, project: todo.project)
- if todo.pending? - if todo.pending?
.todo-actions .todo-actions

View file

@ -1,2 +1,2 @@
%div{ xmlns: "http://www.w3.org/1999/xhtml" } %div{ xmlns: "http://www.w3.org/1999/xhtml" }
= markdown(note.note, pipeline: :atom, project: note.project, author: note.author) = markdown_field(note, :note)

View file

@ -10,7 +10,7 @@
.event-body .event-body
.event-note .event-note
.md .md
= event_note(event.target.note, project: event.project) = first_line_in_markdown(event.target, :note, 150, project: event.project)
- note = event.target - note = event.target
- if note.attachment.url - if note.attachment.url
- if note.attachment.image? - if note.attachment.image?

View file

@ -19,16 +19,16 @@
%li.pull-right %li.pull-right
.toolbar-group .toolbar-group
= markdown_toolbar_button({ icon: "bold fw", data: { "md-tag" => "**" }, title: "Add bold text" }) = markdown_toolbar_button({ icon: "bold", data: { "md-tag" => "**" }, title: "Add bold text" })
= markdown_toolbar_button({ icon: "italic fw", data: { "md-tag" => "*" }, title: "Add italic text" }) = markdown_toolbar_button({ icon: "italic", data: { "md-tag" => "*" }, title: "Add italic text" })
= markdown_toolbar_button({ icon: "quote-right fw", data: { "md-tag" => "> ", "md-prepend" => true }, title: "Insert a quote" }) = markdown_toolbar_button({ icon: "quote", data: { "md-tag" => "> ", "md-prepend" => true }, title: "Insert a quote" })
= markdown_toolbar_button({ icon: "code fw", data: { "md-tag" => "`", "md-block" => "```" }, title: "Insert code" }) = markdown_toolbar_button({ icon: "code", data: { "md-tag" => "`", "md-block" => "```" }, title: "Insert code" })
= markdown_toolbar_button({ icon: "list-ul fw", data: { "md-tag" => "* ", "md-prepend" => true }, title: "Add a bullet list" }) = markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "* ", "md-prepend" => true }, title: "Add a bullet list" })
= markdown_toolbar_button({ icon: "list-ol fw", data: { "md-tag" => "1. ", "md-prepend" => true }, title: "Add a numbered list" }) = markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: "Add a numbered list" })
= markdown_toolbar_button({ icon: "check-square-o fw", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: "Add a task list" }) = markdown_toolbar_button({ icon: "task-done", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: "Add a task list" })
.toolbar-group .toolbar-group
%button.toolbar-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, aria: { label: "Go full screen" }, title: "Go full screen", data: { container: "body" } } %button.toolbar-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, aria: { label: "Go full screen" }, title: "Go full screen", data: { container: "body" } }
= icon("arrows-alt fw") = sprite_icon("screen-full")
.md-write-holder .md-write-holder
= yield = yield

View file

@ -1,2 +1,2 @@
- if commit.has_signature? - if commit.has_signature?
%button{ class: commit_signature_badge_classes('js-loading-gpg-badge'), data: { toggle: 'tooltip', placement: 'auto top', title: 'GPG signature (loading...)', 'commit-sha' => commit.sha } } %a{ href: '#', tabindex: 0, class: commit_signature_badge_classes('js-loading-gpg-badge'), data: { toggle: 'tooltip', placement: 'auto top', title: 'GPG signature (loading...)', 'commit-sha' => commit.sha } }

View file

@ -24,5 +24,5 @@
= link_to('Learn more about signing commits', help_page_path('user/project/repository/gpg_signed_commits/index.md'), class: 'gpg-popover-help-link') = link_to('Learn more about signing commits', help_page_path('user/project/repository/gpg_signed_commits/index.md'), class: 'gpg-popover-help-link')
%button{ class: css_classes, data: { toggle: 'popover', html: 'true', placement: 'auto top', title: title, content: content } } %a{ href: '#', tabindex: 0, class: css_classes, data: { toggle: 'popover', html: 'true', placement: 'auto top', title: title, content: content } }
= label = label

View file

@ -1,3 +1,7 @@
- can_create_merge_request = can?(current_user, :create_merge_request, @project)
- data_action = can_create_merge_request ? 'create-mr' : 'create-branch'
- value = can_create_merge_request ? 'Create a merge request' : 'Create a branch'
- if can?(current_user, :push_code, @project) - if can?(current_user, :push_code, @project)
.create-mr-dropdown-wrap{ data: { can_create_path: can_create_branch_project_issue_path(@project, @issue), create_mr_path: create_merge_request_project_issue_path(@project, @issue), create_branch_path: project_branches_path(@project, branch_name: @issue.to_branch_name, issue_iid: @issue.iid) } } .create-mr-dropdown-wrap{ data: { can_create_path: can_create_branch_project_issue_path(@project, @issue), create_mr_path: create_merge_request_project_issue_path(@project, @issue), create_branch_path: project_branches_path(@project, branch_name: @issue.to_branch_name, issue_iid: @issue.iid) } }
.btn-group.unavailable .btn-group.unavailable
@ -6,10 +10,11 @@
%span.text %span.text
Checking branch availability… Checking branch availability…
.btn-group.available.hide .btn-group.available.hide
%input.btn.js-create-merge-request.btn-inverted.btn-success{ type: 'button', value: 'Create a merge request', data: { action: 'create-mr' } } %input.btn.js-create-merge-request.btn-inverted.btn-success{ type: 'button', value: value, data: { action: data_action } }
%button.btn.btn-inverted.dropdown-toggle.btn-inverted.btn-success.js-dropdown-toggle{ type: 'button', data: { 'dropdown-trigger' => '#create-merge-request-dropdown' } } %button.btn.btn-inverted.dropdown-toggle.btn-inverted.btn-success.js-dropdown-toggle{ type: 'button', data: { 'dropdown-trigger' => '#create-merge-request-dropdown' } }
= icon('caret-down') = icon('caret-down')
%ul#create-merge-request-dropdown.dropdown-menu.dropdown-menu-align-right{ data: { dropdown: true } } %ul#create-merge-request-dropdown.dropdown-menu.dropdown-menu-align-right{ data: { dropdown: true } }
- if can_create_merge_request
%li.droplab-item-selected{ role: 'button', data: { value: 'create-mr', 'text' => 'Create a merge request' } } %li.droplab-item-selected{ role: 'button', data: { value: 'create-mr', 'text' => 'Create a merge request' } }
.menu-item .menu-item
.icon-container .icon-container
@ -19,7 +24,7 @@
%span %span
Creates a merge request named after this issue, with source branch created from '#{@project.default_branch}'. Creates a merge request named after this issue, with source branch created from '#{@project.default_branch}'.
%li.divider.droplab-item-ignore %li.divider.droplab-item-ignore
%li{ role: 'button', data: { value: 'create-branch', 'text' => 'Create a branch' } } %li{ class: [!can_create_merge_request && 'droplab-item-selected'], role: 'button', data: { value: 'create-branch', 'text' => 'Create a branch' } }
.menu-item .menu-item
.icon-container .icon-container
= icon('check') = icon('check')

View file

@ -7,7 +7,7 @@
- if protected_tag?(@project, tag) - if protected_tag?(@project, tag)
%span.label.label-success.prepend-left-4 %span.label.label-success.prepend-left-4
protected = s_('TagsPage|protected')
- if tag.message.present? - if tag.message.present?
&nbsp; &nbsp;
@ -18,7 +18,7 @@
= render 'projects/branches/commit', commit: commit, project: @project = render 'projects/branches/commit', commit: commit, project: @project
- else - else
%p %p
Cant find HEAD commit for this tag = s_("TagsPage|Can't find HEAD commit for this tag")
- if release && release.description.present? - if release && release.description.present?
.description.prepend-top-default .description.prepend-top-default
.wiki .wiki
@ -28,9 +28,9 @@
= render 'projects/buttons/download', project: @project, ref: tag.name, pipeline: @tags_pipelines[tag.name] = render 'projects/buttons/download', project: @project, ref: tag.name, pipeline: @tags_pipelines[tag.name]
- if can?(current_user, :push_code, @project) - if can?(current_user, :push_code, @project)
= link_to edit_project_tag_release_path(@project, tag.name), class: 'btn has-tooltip', title: "Edit release notes", data: { container: "body" } do = link_to edit_project_tag_release_path(@project, tag.name), class: 'btn has-tooltip', title: s_('TagsPage|Edit release notes'), data: { container: "body" } do
= icon("pencil") = icon("pencil")
- if can?(current_user, :admin_project, @project) - if can?(current_user, :admin_project, @project)
= link_to project_tag_path(@project, tag.name), class: "btn btn-remove remove-row has-tooltip #{protected_tag?(@project, tag) ? 'disabled' : ''}", title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{tag.name}' tag cannot be undone. Are you sure?", container: 'body' }, remote: true do = link_to project_tag_path(@project, tag.name), class: "btn btn-remove remove-row has-tooltip #{protected_tag?(@project, tag) ? 'disabled' : ''}", title: s_('TagsPage|Delete tag'), method: :delete, data: { confirm: s_('TagsPage|Deleting the %{tag_name} tag cannot be undone. Are you sure?') % { tag_name: tag.name }, container: 'body' }, remote: true do
= icon("trash-o") = icon("trash-o")

View file

@ -1,16 +1,16 @@
- @no_container = true - @no_container = true
- @sort ||= sort_value_recently_updated - @sort ||= sort_value_recently_updated
- page_title "Tags" - page_title _('TagsPage|Tags')
- add_to_breadcrumbs("Repository", project_tree_path(@project)) - add_to_breadcrumbs("Repository", project_tree_path(@project))
.flex-list{ class: container_class } .flex-list{ class: container_class }
.top-area.adjust .top-area.adjust
.nav-text.row-main-content .nav-text.row-main-content
Tags give the ability to mark specific points in history as being important = s_('TagsPage|Tags give the ability to mark specific points in history as being important')
.nav-controls.row-fixed-content .nav-controls.row-fixed-content
= form_tag(filter_tags_path, method: :get) do = form_tag(filter_tags_path, method: :get) do
= search_field_tag :search, params[:search], { placeholder: 'Filter by tag name', id: 'tag-search', class: 'form-control search-text-input input-short', spellcheck: false } = search_field_tag :search, params[:search], { placeholder: s_('TagsPage|Filter by tag name'), id: 'tag-search', class: 'form-control search-text-input input-short', spellcheck: false }
.dropdown .dropdown
%button.dropdown-toggle{ type: 'button', data: { toggle: 'dropdown'} } %button.dropdown-toggle{ type: 'button', data: { toggle: 'dropdown'} }
@ -19,13 +19,13 @@
= icon('chevron-down') = icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-selectable %ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-selectable
%li.dropdown-header %li.dropdown-header
Sort by = s_('TagsPage|Sort by')
- tags_sort_options_hash.each do |value, title| - tags_sort_options_hash.each do |value, title|
%li %li
= link_to title, filter_tags_path(sort: value), class: ("is-active" if @sort == value) = link_to title, filter_tags_path(sort: value), class: ("is-active" if @sort == value)
- if can?(current_user, :push_code, @project) - if can?(current_user, :push_code, @project)
= link_to new_project_tag_path(@project), class: 'btn btn-create new-tag-btn' do = link_to new_project_tag_path(@project), class: 'btn btn-create new-tag-btn' do
New tag = s_('TagsPage|New tag')
.tags .tags
- if @tags.any? - if @tags.any?
@ -36,9 +36,9 @@
- else - else
.nothing-here-block .nothing-here-block
Repository has no tags yet. = s_('TagsPage|Repository has no tags yet.')
%br %br
%small %small
Use git tag command to add a new one: = s_('TagsPage|Use git tag command to add a new one:')
%br %br
%span.monospace git tag -a v1.4 -m 'version 1.4' %span.monospace git tag -a v1.4 -m 'version 1.4'

View file

@ -1,4 +1,4 @@
- page_title "New Tag" - page_title s_('TagsPage|New Tag')
- default_ref = params[:ref] || @project.default_branch - default_ref = params[:ref] || @project.default_branch
- if @error - if @error
@ -7,7 +7,7 @@
= @error = @error
%h3.page-title %h3.page-title
New Tag = s_('TagsPage|New Tag')
%hr %hr
= form_tag namespace_project_tags_path, method: :post, id: "new-tag-form", class: "form-horizontal common-note-form tag-form js-quick-submit js-requires-input" do = form_tag namespace_project_tags_path, method: :post, id: "new-tag-form", class: "form-horizontal common-note-form tag-form js-quick-submit js-requires-input" do
@ -23,20 +23,23 @@
= button_tag type: 'button', title: default_ref, class: 'dropdown-menu-toggle wide form-control js-branch-select', required: true, data: { toggle: 'dropdown', selected: default_ref, field_name: 'ref' } do = button_tag type: 'button', title: default_ref, class: 'dropdown-menu-toggle wide form-control js-branch-select', required: true, data: { toggle: 'dropdown', selected: default_ref, field_name: 'ref' } do
.text-left.dropdown-toggle-text= default_ref .text-left.dropdown-toggle-text= default_ref
= render 'shared/ref_dropdown', dropdown_class: 'wide' = render 'shared/ref_dropdown', dropdown_class: 'wide'
.help-block Existing branch name, tag, or commit SHA .help-block
= s_('TagsPage|Existing branch name, tag, or commit SHA')
.form-group .form-group
= label_tag :message, nil, class: 'control-label' = label_tag :message, nil, class: 'control-label'
.col-sm-10 .col-sm-10
= text_area_tag :message, @message, required: false, tabindex: 3, class: 'form-control', rows: 5 = text_area_tag :message, @message, required: false, tabindex: 3, class: 'form-control', rows: 5
.help-block Optionally, add a message to the tag. .help-block
= s_('TagsPage|Optionally, add a message to the tag.')
%hr %hr
.form-group .form-group
= label_tag :release_description, 'Release notes', class: 'control-label' = label_tag :release_description, 'Release notes', class: 'control-label'
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do = render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
= render 'projects/zen', attr: :release_description, classes: 'note-textarea', placeholder: "Write your release notes or drag files here...", current_text: @release_description = render 'projects/zen', attr: :release_description, classes: 'note-textarea', placeholder: s_('TagsPage|Write your release notes or drag files here...'), current_text: @release_description
= render 'shared/notes/hints' = render 'shared/notes/hints'
.help-block Optionally, add release notes to the tag. They will be stored in the GitLab database and displayed on the tags page. .help-block
= s_('TagsPage|Optionally, add release notes to the tag. They will be stored in the GitLab database and displayed on the tags page.')
.form-actions .form-actions
= button_tag 'Create tag', class: 'btn btn-create', tabindex: 3 = button_tag 'Create tag', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel' = link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel'

View file

@ -1,7 +1,7 @@
- @no_container = true - @no_container = true
- add_to_breadcrumbs "Tags", project_tags_path(@project) - add_to_breadcrumbs s_('TagsPage|Tags'), project_tags_path(@project)
- breadcrumb_title @tag.name - breadcrumb_title @tag.name
- page_title @tag.name, "Tags" - page_title @tag.name, s_('TagsPage|Tags')
%div{ class: container_class } %div{ class: container_class }
.top-area.multi-line .top-area.multi-line
@ -12,25 +12,25 @@
= @tag.name = @tag.name
- if protected_tag?(@project, @tag) - if protected_tag?(@project, @tag)
%span.label.label-success %span.label.label-success
protected = s_('TagsPage|protected')
- if @commit - if @commit
= render 'projects/branches/commit', commit: @commit, project: @project = render 'projects/branches/commit', commit: @commit, project: @project
- else - else
Cant find HEAD commit for this tag = s_("TagsPage|Can't find HEAD commit for this tag")
.nav-controls.controls-flex .nav-controls.controls-flex
- if can?(current_user, :push_code, @project) - if can?(current_user, :push_code, @project)
= link_to edit_project_tag_release_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: 'Edit release notes' do = link_to edit_project_tag_release_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: s_('TagsPage|Edit release notes') do
= icon("pencil") = icon("pencil")
= link_to project_tree_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: 'Browse files' do = link_to project_tree_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: s_('TagsPage|Browse files') do
= icon('files-o') = icon('files-o')
= link_to project_commits_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: 'Browse commits' do = link_to project_commits_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: s_('TagsPage|Browse commits') do
= icon('history') = icon('history')
.btn-container.controls-item .btn-container.controls-item
= render 'projects/buttons/download', project: @project, ref: @tag.name = render 'projects/buttons/download', project: @project, ref: @tag.name
- if can?(current_user, :admin_project, @project) - if can?(current_user, :admin_project, @project)
.btn-container.controls-item-full .btn-container.controls-item-full
= link_to project_tag_path(@project, @tag.name), class: "btn btn-remove remove-row has-tooltip #{protected_tag?(@project, @tag) ? 'disabled' : ''}", title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{@tag.name}' tag cannot be undone. Are you sure?" } do = link_to project_tag_path(@project, @tag.name), class: "btn btn-remove remove-row has-tooltip #{protected_tag?(@project, @tag) ? 'disabled' : ''}", title: s_('TagsPage|Delete tag'), method: :delete, data: { confirm: s_('TagsPage|Deleting the %{tag_name} tag cannot be undone. Are you sure?') % { tag_name: @tag.name } } do
%i.fa.fa-trash-o %i.fa.fa-trash-o
- if @tag.message.present? - if @tag.message.present?
@ -43,4 +43,4 @@
.wiki .wiki
= markdown_field(@release, :description) = markdown_field(@release, :description)
- else - else
This tag has no release notes. = s_('TagsPage|This tag has no release notes.')

View file

@ -0,0 +1,5 @@
---
title: Improve DashboardController#activity.json performance
merge_request: 14985
author:
type: performance

View file

@ -0,0 +1,5 @@
---
title: Remove create MR button from issues when MRs are disabled
merge_request: 15071
author: George Andrinopoulos
type: fixed

View file

@ -0,0 +1,5 @@
---
title: Fix GPG signature popup info in Safari and Firefox
merge_request: 15228
author:
type: fixed

View file

@ -0,0 +1,5 @@
---
title: Internationalized tags page
merge_request: 38589
author:
type: other

View file

@ -0,0 +1,5 @@
---
title: Remove native title tooltip in pipeline jobs dropdown in Safari
merge_request:
author:
type: fixed

View file

@ -0,0 +1,5 @@
---
title: Enable BorderZero rule in scss-lint
merge_request: 15168
author: Takuya Noguchi
type: other

Some files were not shown because too many files have changed in this diff Show more