......@@ -2,6 +2,13 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
## 11.6.3 (2019-01-04)
### Fixed (1 change)
- Fix clone URL not showing if protocol is HTTPS. !24131
## 11.6.2 (2019-01-02)
### Fixed (7 changes)
......
......
......@@ -15,48 +15,6 @@ repository is licensed under Creative Commons:
_This notice should stay as the first item in the CONTRIBUTING.md file._
---
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Contributing Documentation has been moved](#contributing-documentation-has-been-moved)
- [Contribute to GitLab](#contribute-to-gitlab)
- [Security vulnerability disclosure](#security-vulnerability-disclosure)
- [Code of conduct](#code-of-conduct)
- [Closing policy for issues and merge requests](#closing-policy-for-issues-and-merge-requests)
- [Helping others](#helping-others)
- [I want to contribute!](#i-want-to-contribute)
- [Contribution Flow](#contribution-flow)
- [Workflow labels](#workflow-labels)
- [Type labels](#type-labels)
- [Subject labels](#subject-labels)
- [Team labels](#team-labels)
- [Release Scoping labels](#release-scoping-labels)
- [Priority labels](#priority-labels)
- [Severity labels](#severity-labels)
- [Severity impact guidance](#severity-impact-guidance)
- [Label for community contributors](#label-for-community-contributors)
- [Implement design & UI elements](#implement-design--ui-elements)
- [Issue tracker](#issue-tracker)
- [Issue triaging](#issue-triaging)
- [Feature proposals](#feature-proposals)
- [Issue tracker guidelines](#issue-tracker-guidelines)
- [Issue weight](#issue-weight)
- [Regression issues](#regression-issues)
- [Technical and UX debt](#technical-and-ux-debt)
- [Stewardship](#stewardship)
- [Merge requests](#merge-requests)
- [Merge request guidelines](#merge-request-guidelines)
- [Contribution acceptance criteria](#contribution-acceptance-criteria)
- [Definition of done](#definition-of-done)
- [Style guides](#style-guides)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
---
## Contributing Documentation has been moved
As of July 2018, all the documentation for contributing to the GitLab project has been moved to a new location.
......@@ -170,7 +128,6 @@ This [documentation](doc/development/contributing/merge_request_workflow.md) has
This [documentation](doc/development/contributing/merge_request_workflow.md) has been moved.
### Contribution acceptance criteria
This [documentation](doc/development/contributing/merge_request_workflow.md) has been moved.
......
......
......@@ -244,6 +244,7 @@ class List {
issue.project = data.project;
issue.path = data.real_path;
issue.referencePath = data.reference_path;
issue.assignableLabelsEndpoint = data.assignable_labels_endpoint;
if (this.issuesSize > 1) {
const moveBeforeId = this.issues[1].id;
......
......
......@@ -32,6 +32,7 @@ export default class Clusters {
installKnativePath,
installPrometheusPath,
managePrometheusPath,
hasRbac,
clusterType,
clusterStatus,
clusterStatusReason,
......@@ -45,6 +46,7 @@ export default class Clusters {
this.store.setManagePrometheusPath(managePrometheusPath);
this.store.updateStatus(clusterStatus);
this.store.updateStatusReason(clusterStatusReason);
this.store.updateRbac(hasRbac);
this.service = new ClustersService({
endpoint: statusPath,
installHelmEndpoint: installHelmPath,
......@@ -102,6 +104,7 @@ export default class Clusters {
ingressHelpPath: this.state.ingressHelpPath,
managePrometheusPath: this.state.managePrometheusPath,
ingressDnsHelpPath: this.state.ingressDnsHelpPath,
rbac: this.state.rbac,
},
});
},
......
......
......@@ -52,6 +52,11 @@ export default {
required: false,
default: '',
},
rbac: {
type: Boolean,
required: false,
default: false,
},
},
data: () => ({
elasticsearchLogo,
......@@ -442,6 +447,18 @@ export default {
title-link="https://github.com/knative/docs"
>
<div slot="description">
<span v-if="!rbac">
<p v-if="!rbac" class="bs-callout bs-callout-info append-bottom-0">
{{
s__(`ClusterIntegration|You must have an RBAC-enabled cluster
to install Knative.`)
}}
<a :href="helpPath" target="_blank" rel="noopener noreferrer">
{{ __('More information') }}
</a>
</p>
<br />
</span>
<p>
{{
s__(`ClusterIntegration|Knative extends Kubernetes to provide
......@@ -465,7 +482,7 @@ export default {
/>
</div>
</template>
<template v-else-if="helmInstalled">
<template v-else-if="helmInstalled && rbac">
<div class="form-group">
<label for="knative-domainname">
{{ s__('ClusterIntegration|Knative Domain Name:') }}
......
......
import { s__ } from '../../locale';
import { parseBoolean } from '../../lib/utils/common_utils';
import { INGRESS, JUPYTER, KNATIVE, CERT_MANAGER } from '../constants';
export default class ClusterStore {
......@@ -7,6 +8,7 @@ export default class ClusterStore {
helpPath: null,
ingressHelpPath: null,
status: null,
rbac: false,
statusReason: null,
applications: {
helm: {
......@@ -81,6 +83,10 @@ export default class ClusterStore {
this.state.status = status;
}
updateRbac(rbac) {
this.state.rbac = parseBoolean(rbac);
}
updateStatusReason(reason) {
this.state.statusReason = reason;
}
......
......
......@@ -5,6 +5,7 @@ import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import CIIcon from '~/vue_shared/components/ci_icon.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import CommitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
import initUserPopovers from '../../user_popovers';
/**
* CommitItem
......@@ -35,20 +36,30 @@ export default {
},
},
computed: {
author() {
return this.commit.author || {};
},
authorName() {
return (this.commit.author && this.commit.author.name) || this.commit.author_name;
return this.author.name || this.commit.author_name;
},
authorClass() {
return this.author.name ? 'js-user-link' : '';
},
authorId() {
return this.author.id ? this.author.id : '';
},
authorUrl() {
return (
(this.commit.author && this.commit.author.web_url) || `mailto:${this.commit.author_email}`
);
return this.author.web_url || `mailto:${this.commit.author_email}`;
},
authorAvatar() {
return (
(this.commit.author && this.commit.author.avatar_url) || this.commit.author_gravatar_url
);
return this.author.avatar_url || this.commit.author_gravatar_url;
},
},
created() {
this.$nextTick(() => {
initUserPopovers(this.$el.querySelectorAll('.js-user-link'));
});
},
};
</script>
......@@ -81,7 +92,13 @@ export default {
</button>
<div class="commiter">
<a :href="authorUrl" v-text="authorName"></a> {{ s__('CommitWidget|authored') }}
<a
:href="authorUrl"
:class="authorClass"
:data-user-id="authorId"
v-text="authorName"
></a>
{{ s__('CommitWidget|authored') }}
<time-ago-tooltip :time="commit.authored_date" />
</div>
......
......
......@@ -51,8 +51,6 @@ export default class GLForm {
// form and textarea event listeners
this.addEventListeners();
addMarkdownListeners(this.form);
// hide discard button
this.form.find('.js-note-discard').hide();
this.form.show();
if (this.isAutosizeable) this.setupAutosize();
}
......
......
......@@ -138,8 +138,6 @@ export default class Notes {
this.$wrapperEl.on('click', '.js-note-delete', this.removeNote);
// delete note attachment
this.$wrapperEl.on('click', '.js-note-attachment-delete', this.removeAttachment);
// reset main target form when clicking discard
this.$wrapperEl.on('click', '.js-note-discard', this.resetMainTargetForm);
// update the file name when an attachment is selected
this.$wrapperEl.on('change', '.js-note-attachment-input', this.updateFormAttachment);
// reply to diff/discussion notes
......@@ -191,7 +189,6 @@ export default class Notes {
this.$wrapperEl.off('keyup input', '.js-note-text');
this.$wrapperEl.off('click', '.js-note-target-reopen');
this.$wrapperEl.off('click', '.js-note-target-close');
this.$wrapperEl.off('click', '.js-note-discard');
this.$wrapperEl.off('keydown', '.js-note-text');
this.$wrapperEl.off('click', '.js-comment-resolve-button');
this.$wrapperEl.off('click', '.system-note-commit-list-toggler');
......@@ -986,11 +983,9 @@ export default class Notes {
form.find('#note_position').val(dataHolder.attr('data-position'));
form
.find('.js-note-discard')
.find('.js-close-discussion-note-form')
.show()
.removeClass('js-note-discard')
.addClass('js-close-discussion-note-form')
.text(form.find('.js-close-discussion-note-form').data('cancelText'));
.removeClass('hide');
form.find('.js-note-target-close').remove();
form.find('.js-note-new-discussion').remove();
this.setupNoteForm(form);
......@@ -1194,12 +1189,11 @@ export default class Notes {
}
updateTargetButtons(e) {
var closebtn, closetext, discardbtn, form, reopenbtn, reopentext, textarea;
var closebtn, closetext, form, reopenbtn, reopentext, textarea;
textarea = $(e.target);
form = textarea.parents('form');
reopenbtn = form.find('.js-note-target-reopen');
closebtn = form.find('.js-note-target-close');
discardbtn = form.find('.js-note-discard');
if (textarea.val().trim().length > 0) {
reopentext = reopenbtn.attr('data-alternative-text');
......@@ -1216,9 +1210,6 @@ export default class Notes {
if (closebtn.is(':not(.btn-comment-and-close)')) {
closebtn.addClass('btn-comment-and-close');
}
if (discardbtn.is(':hidden')) {
return discardbtn.show();
}
} else {
reopentext = reopenbtn.data('originalText');
closetext = closebtn.data('originalText');
......@@ -1234,9 +1225,6 @@ export default class Notes {
if (closebtn.is('.btn-comment-and-close')) {
closebtn.removeClass('btn-comment-and-close');
}
if (discardbtn.is(':visible')) {
return discardbtn.hide();
}
}
}
......
......
......@@ -431,15 +431,6 @@ append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown"
:label="issueActionButtonTitle"
@click="handleSave(true);"
/>
<button
v-if="note.length"
type="button"
class="btn btn-cancel js-note-discard"
@click="discard"
>
Discard draft
</button>
</div>
</form>
</div>
......
......
......@@ -149,6 +149,9 @@ export default {
return shouldResolve || shouldToggleState;
},
handleKeySubmit() {
this.handleUpdate();
},
handleUpdate(shouldResolve) {
const beforeSubmitDiscussionState = this.discussionResolved;
this.isSubmitting = true;
......@@ -216,8 +219,8 @@ export default {
class="note-textarea js-gfm-input js-note-text js-autosize markdown-area js-vue-issue-note-form js-vue-textarea qa-reply-input"
aria-label="Description"
placeholder="Write a comment or drag your files here…"
@keydown.meta.enter="handleUpdate();"
@keydown.ctrl.enter="handleUpdate();"
@keydown.meta.enter="handleKeySubmit();"
@keydown.ctrl.enter="handleKeySubmit();"
@keydown.up="editMyLastNote();"
@keydown.esc="cancelHandler(true);"
></textarea>
......
......
......@@ -325,8 +325,8 @@ export default {
<project-setting-row
v-if="pagesAvailable && pagesAccessControlEnabled"
:help-path="pagesHelpPath"
label="Pages"
help-text="Static website for the project."
label="Pages access control"
help-text="Access control for the project's static website"
>
<project-feature-setting
v-model="pagesAccessLevel"
......
......
<script>
import { GlLink, GlTooltipDirective } from '@gitlab/ui';
import _ from 'underscore';
import { __, sprintf } from '~/locale';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import popover from '~/vue_shared/directives/popover';
const popoverTitle = sprintf(
_.escape(
__(
`This pipeline makes use of a predefined CI/CD configuration enabled by %{strongStart}Auto DevOps.%{strongEnd}`,
),
),
{ strongStart: '<b>', strongEnd: '</b>' },
false,
);
export default {
components: {
UserAvatarLink,
......@@ -32,14 +44,14 @@ export default {
trigger: 'focus',
placement: 'top',
title: `<div class="autodevops-title">
This pipeline makes use of a predefined CI/CD configuration enabled by <b>Auto DevOps.</b>
${popoverTitle}
</div>`,
content: `<a
class="autodevops-link"
href="${this.autoDevopsHelpPath}"
target="_blank"
rel="noopener noreferrer nofollow">
Learn more about Auto DevOps
${_.escape(__('Learn more about Auto DevOps'))}
</a>`,
};
},
......@@ -54,9 +66,9 @@ export default {
<span>by</span>
<user-avatar-link
v-if="user"
:link-href="pipeline.user.path"
:img-src="pipeline.user.avatar_url"
:tooltip-text="pipeline.user.name"
:link-href="user.path"
:img-src="user.avatar_url"
:tooltip-text="user.name"
class="js-pipeline-url-user"
/>
<span v-if="!user" class="js-pipeline-url-api api"> API </span>
......@@ -64,10 +76,10 @@ export default {
<span
v-if="pipeline.flags.latest"
v-gl-tooltip
class="js-pipeline-url-latest badge badge-success"
:title="__('Latest pipeline for this branch')"
class="js-pipeline-url-latest badge badge-success"
>
latest
{{ __('latest') }}
</span>
<span
v-if="pipeline.flags.yaml_errors"
......@@ -75,7 +87,7 @@ export default {
:title="pipeline.yaml_errors"
class="js-pipeline-url-yaml badge badge-danger"
>
yaml invalid
{{ __('yaml invalid') }}
</span>
<span
v-if="pipeline.flags.failure_reason"
......@@ -83,7 +95,7 @@ export default {
:title="pipeline.failure_reason"
class="js-pipeline-url-failure badge badge-danger"
>
error
{{ __('error') }}
</span>
<gl-link
v-if="pipeline.flags.auto_devops"
......@@ -95,7 +107,7 @@ export default {
Auto DevOps
</gl-link>
<span v-if="pipeline.flags.stuck" class="js-pipeline-url-stuck badge badge-warning">
stuck
{{ __('stuck') }}
</span>
<span
v-if="pipeline.flags.merge_request"
......@@ -103,7 +115,7 @@ export default {
:title="__('This pipeline is run in a merge request context')"
class="js-pipeline-url-mergerequest badge badge-info"
>
merge request
{{ __('merge request') }}
</span>
</div>
</div>
......
......
......@@ -45,7 +45,7 @@ export default {
return this.release.author || {};
},
hasAuthor() {
return _.isEmpty(this.author);
return !_.isEmpty(this.author);
},
},
};
......
......
......@@ -89,7 +89,6 @@ export default {
return this.referencedUsers.length >= referencedUsersThreshold;
},
lineContent() {
const FIRST_CHAR_REGEX = /^(\+|-)/;
const [firstSuggestion] = this.suggestions;
if (firstSuggestion) {
return firstSuggestion.from_content;
......@@ -99,7 +98,7 @@ export default {
const { rich_text: richText, text } = this.line;
if (text) {
return text.replace(FIRST_CHAR_REGEX, '');
return text;
}
return _.unescape(stripHtml(richText).replace(/\n/g, ''));
......
......
......@@ -82,13 +82,12 @@ export default {
// extracts the suggested lines from the markdown
// calculates a line number for each line
const FIRST_CHAR_REGEX = /^(\+|-)/;
const newLines = suggestionEl.querySelectorAll('.line');
const fromLine = this.suggestions.length ? this.suggestions[0].from_line : this.fromLine;
const lines = [];
newLines.forEach((line, i) => {
const content = `${line.innerText.replace(FIRST_CHAR_REGEX, '')}\n`;
const content = `${line.innerText}\n`;
const lineNumber = fromLine + i;
lines.push({ content, lineNumber });
});
......
......
<script>
import { GlButton } from '@gitlab/ui';
import { sprintf, __ } from '~/locale';
import UserAvatarLink from './user_avatar_link.vue';
export default {
components: {
UserAvatarLink,
GlButton,
},
props: {
items: {
type: Array,
required: true,
},
breakpoint: {
type: Number,
required: false,
default: 10,
},
imgSize: {
type: Number,
required: false,
default: 20,
},
},
data() {
return {
isExpanded: false,
};
},
computed: {
visibleItems() {
if (!this.hasHiddenItems) {
return this.items;
}
return this.items.slice(0, this.breakpoint);
},
hasHiddenItems() {
return this.hasBreakpoint && !this.isExpanded && this.items.length > this.breakpoint;
},
hasBreakpoint() {
return this.breakpoint > 0 && this.items.length > this.breakpoint;
},
expandText() {
if (!this.hasHiddenItems) {
return '';
}
const count = this.items.length - this.breakpoint;
return sprintf(__('%{count} more'), { count });
},
},
methods: {
expand() {
this.isExpanded = true;
},
collapse() {
this.isExpanded = false;
},
},
};
</script>
<template>
<div>
<user-avatar-link
v-for="item in visibleItems"
:key="item.id"
:link-href="item.web_url"
:img-src="item.avatar_url"
:img-alt="item.name"
:tooltip-text="item.name"
:img-size="imgSize"
/>
<template v-if="hasBreakpoint">
<gl-button v-if="hasHiddenItems" variant="link" @click="expand"> {{ expandText }} </gl-button>
<gl-button v-else variant="link" @click="collapse"> {{ __('show less') }} </gl-button>
</template>
</div>
</template>
......@@ -384,10 +384,17 @@ img.emoji {
.flex-align-self-center { align-self: center; }
.flex-grow { flex-grow: 1; }
.flex-no-shrink { flex-shrink: 0; }
.mw-460 { max-width: 460px; }
.ws-initial { white-space: initial; }
.overflow-auto { overflow: auto; }
/** COMMON SIZING CLASSES **/
.w-0 { width: 0; }
.h-13em { height: 13em; }
.mw-460 { max-width: 460px; }
.mw-6em { max-width: 6em; }
.min-height-0 { min-height: 0; }
/** COMMON SPACING CLASSES **/
.gl-pl-0 { padding-left: 0; }
.gl-pl-1 { padding-left: #{0.5 * $grid-size}; }
.gl-pl-2 { padding-left: $grid-size; }
......
......
......@@ -36,6 +36,15 @@ label {
}
}
.label-wrapper {
display: block;
margin: 0;
}
.form-label {
@extend label;
}
.form-control-label {
@extend .col-md-2;
}
......
......
......@@ -57,6 +57,16 @@
color: $gl-text-color;
}
}
&.is-invalid {
~ .invalid-feedback {
display: block;
}
.select2-choices {
border-color: $red-500;
}
}
}
.select2-drop,
......@@ -67,10 +77,18 @@
min-width: 175px;
color: $gl-text-color;
z-index: 999;
.modal-open & {
z-index: $zindex-modal + 200;
}
}
.select2-drop-mask {
z-index: 998;
.modal-open & {
z-index: $zindex-modal + 100;
}
}
.select2-drop.select2-drop-above.select2-drop-active {
......
......