Commit 390afc43 authored by Enrique Alcántara's avatar Enrique Alcántara

Merge branch '32692-rename-wip-merge-requests-to-draft' into 'master'

Use Draft as the primary work in progress indicator

See merge request gitlab-org/gitlab!36666
parents fdb23fd6 0b398bcf
......@@ -48,7 +48,19 @@ export default class IssuableForm {
this.renderWipExplanation = this.renderWipExplanation.bind(this);
this.resetAutosave = this.resetAutosave.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.wipRegex = /^\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i;
/* eslint-disable @gitlab/require-i18n-strings */
this.wipRegex = new RegExp(
'^\\s*(' + // Line start, then any amount of leading whitespace
'draft\\s-\\s' + // Draft_-_ where "_" are *exactly* one whitespace
'|\\[(draft|wip)\\]\\s*' + // [Draft] or [WIP] and any following whitespace
'|(draft|wip):\\s*' + // Draft: or WIP: and any following whitespace
'|(draft|wip)\\s+' + // Draft_ or WIP_ where "_" is at least one whitespace
'|\\(draft\\)\\s*' + // (Draft) and any following whitespace
')+' + // At least one repeated match of the preceding parenthetical
'\\s*', // Any amount of trailing whitespace
'i', // Match any case(s)
);
/* eslint-enable @gitlab/require-i18n-strings */
this.gfmAutoComplete = new GfmAutoComplete(
gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources,
......@@ -131,9 +143,18 @@ export default class IssuableForm {
workInProgress() {
return this.wipRegex.test(this.titleField.val());
}
titlePrefixContainsDraft() {
const prefix = this.titleField.val().match(this.wipRegex);
return prefix && prefix[0].match(/draft/i);
}
renderWipExplanation() {
if (this.workInProgress()) {
// These strings are not "translatable" (the code is hard-coded to look for them)
this.$wipExplanation.find('code')[0].textContent = this.titlePrefixContainsDraft()
? 'Draft' /* eslint-disable-line @gitlab/require-i18n-strings */
: 'WIP';
this.$wipExplanation.show();
return this.$noWipExplanation.hide();
}
......@@ -156,7 +177,7 @@ export default class IssuableForm {
}
addWip() {
this.titleField.val(`WIP: ${this.titleField.val()}`);
this.titleField.val(`Draft: ${this.titleField.val()}`);
}
initTargetBranchDropdown() {
......
<script>
import $ from 'jquery';
import { GlDeprecatedButton } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import { GlButton } from '@gitlab/ui';
import { __ } from '~/locale';
import createFlash from '~/flash';
import StatusIcon from '../mr_widget_status_icon.vue';
import tooltip from '../../../vue_shared/directives/tooltip';
......@@ -11,7 +11,7 @@ export default {
name: 'WorkInProgress',
components: {
StatusIcon,
GlDeprecatedButton,
GlButton,
},
directives: {
tooltip,
......@@ -25,13 +25,6 @@ export default {
isMakingRequest: false,
};
},
computed: {
wipInfoTooltip() {
return s__(
'mrWidget|When this merge request is ready, remove the WIP: prefix from the title to allow it to be merged',
);
},
},
methods: {
handleRemoveWIP() {
this.isMakingRequest = true;
......@@ -55,28 +48,25 @@ export default {
<template>
<div class="mr-widget-body media">
<status-icon :show-disabled-button="Boolean(mr.removeWIPPath)" status="warning" />
<div class="media-body space-children">
<span class="bold">
{{ __('This is a Work in Progress') }}
<i
v-tooltip
class="fa fa-question-circle"
:title="wipInfoTooltip"
:aria-label="wipInfoTooltip"
>
</i>
<div class="media-body">
<div class="gl-ml-3 float-left">
<span class="gl-font-weight-bold">
{{ __('This merge request is still a work in progress.') }}
</span>
<gl-deprecated-button
<span class="gl-display-block text-muted">{{
__("Draft merge requests can't be merged.")
}}</span>
</div>
<gl-button
v-if="mr.removeWIPPath"
size="sm"
variant="default"
size="small"
:disabled="isMakingRequest"
:loading="isMakingRequest"
class="js-remove-wip"
class="js-remove-wip gl-ml-3"
@click="handleRemoveWIP"
>
{{ s__('mrWidget|Resolve WIP status') }}
</gl-deprecated-button>
{{ s__('mrWidget|Mark as ready') }}
</gl-button>
</div>
</div>
</template>
......@@ -3,6 +3,13 @@
- form = local_assigns.fetch(:form)
- no_issuable_templates = issuable_templates(issuable).empty?
- div_class = no_issuable_templates ? 'col-sm-10' : 'col-sm-7 col-lg-8'
- toggle_wip_link_start = '<a href="" class="js-toggle-wip">'
- toggle_wip_link_end = '</a>'
- draft_snippet = '<code>Draft:</code>'.html_safe
- wip_snippet = '<code>WIP:</code>'.html_safe
- draft_or_wip_snippet = '<code>Draft/WIP</code>'.html_safe
- add_wip_text = (_('%{link_start}Start the title with %{draft_snippet} or %{wip_snippet}%{link_end} to prevent a merge request that is a work in progress from being merged before it\'s ready.') % { link_start: toggle_wip_link_start, link_end: toggle_wip_link_end, draft_snippet: draft_snippet, wip_snippet: wip_snippet } ).html_safe
- remove_wip_text = (_('%{link_start}Remove the %{draft_or_wip_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it\'s ready.' ) % { link_start: toggle_wip_link_start, link_end: toggle_wip_link_end, draft_or_wip_snippet: draft_or_wip_snippet } ).html_safe
%div{ class: div_class }
= form.text_field :title, required: true, maxlength: 255, autofocus: true,
......@@ -11,23 +18,12 @@
- if issuable.respond_to?(:work_in_progress?)
.form-text.text-muted
.js-wip-explanation
%a.js-toggle-wip{ href: '' }
Remove the
%code WIP:
prefix from the title
to allow this
%strong Work In Progress
merge request to be merged when it's ready.
= remove_wip_text
.js-no-wip-explanation
- if has_wip_commits
It looks like you have some WIP commits in this branch.
= _('It looks like you have some draft commits in this branch.')
%br
%a.js-toggle-wip{ href: '' }
Start the title with
%code WIP:
to prevent a
%strong Work In Progress
merge request from being merged before it's ready.
= add_wip_text
- if no_issuable_templates && can?(current_user, :push_code, issuable.project)
= render 'shared/issuable/form/default_templates'
---
title: Add Draft to WIP for work in progress merge requests
merge_request: 36666
author:
type: added
......@@ -474,6 +474,12 @@ msgstr ""
msgid "%{link_start}Read more%{link_end} about role permissions"
msgstr ""
msgid "%{link_start}Remove the %{draft_or_wip_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it's ready."
msgstr ""
msgid "%{link_start}Start the title with %{draft_snippet} or %{wip_snippet}%{link_end} to prevent a merge request that is a work in progress from being merged before it's ready."
msgstr ""
msgid "%{listToShow}, and %{awardsListLength} more."
msgstr ""
......@@ -8500,6 +8506,9 @@ msgstr ""
msgid "Downvotes"
msgstr ""
msgid "Draft merge requests can't be merged."
msgstr ""
msgid "Drop or %{linkStart}upload%{linkEnd} Designs to attach"
msgstr ""
......@@ -13141,6 +13150,9 @@ msgstr ""
msgid "Issue|Title"
msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
msgid "It must have a header row and at least two columns: the first column is the issue title and the second column is the issue description. The separator is automatically detected."
msgstr ""
......@@ -24155,9 +24167,6 @@ msgstr ""
msgid "This is a Premium feature"
msgstr ""
msgid "This is a Work in Progress"
msgstr ""
msgid "This is a confidential %{noteableTypeText}."
msgstr ""
......@@ -24311,6 +24320,9 @@ msgstr ""
msgid "This merge request is locked."
msgstr ""
msgid "This merge request is still a work in progress."
msgstr ""
msgid "This merge request was merged. To apply this suggestion, edit this file directly."
msgstr ""
......@@ -28412,6 +28424,9 @@ msgstr ""
msgid "mrWidget|Loading deployment statistics"
msgstr ""
msgid "mrWidget|Mark as ready"
msgstr ""
msgid "mrWidget|Mentions"
msgstr ""
......@@ -28469,9 +28484,6 @@ msgstr ""
msgid "mrWidget|Request to merge"
msgstr ""
msgid "mrWidget|Resolve WIP status"
msgstr ""
msgid "mrWidget|Resolve conflicts"
msgstr ""
......@@ -28550,9 +28562,6 @@ msgstr ""
msgid "mrWidget|Use %{linkStart}CI pipelines to test your code%{linkEnd} by simply adding a GitLab CI configuration file to your project. It only takes a minute to make your code more secure and robust."
msgstr ""
msgid "mrWidget|When this merge request is ready, remove the WIP: prefix from the title to allow it to be merged"
msgstr ""
msgid "mrWidget|You are not allowed to edit this project directly. Please fork to make changes."
msgstr ""
......
......@@ -32,9 +32,9 @@ RSpec.describe 'Merge request > User resolves Work in Progress', :js do
it 'retains merge request data after clicking Resolve WIP status' do
expect(page.find('.ci-widget-content')).to have_content("Pipeline ##{pipeline.id}")
expect(page).to have_content "This is a Work in Progress"
expect(page).to have_content "This merge request is still a work in progress."
click_button('Resolve WIP status')
click_button('Mark as ready')
wait_for_requests
......@@ -42,7 +42,7 @@ RSpec.describe 'Merge request > User resolves Work in Progress', :js do
# merge request widget refreshes, which masks missing elements
# that should already be present.
expect(page.find('.ci-widget-content', wait: 0)).to have_content("Pipeline ##{pipeline.id}")
expect(page).not_to have_content('This is a Work in Progress')
expect(page).not_to have_content('This merge request is still a work in progress.')
end
end
end
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe 'Merge request > User sees WIP help message' do
RSpec.describe 'Merge request > User sees draft help message' do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
......@@ -11,8 +11,8 @@ RSpec.describe 'Merge request > User sees WIP help message' do
sign_in(user)
end
context 'with WIP commits' do
it 'shows a specific WIP hint' do
context 'with draft commits' do
it 'shows a specific draft hint' do
visit project_new_merge_request_path(
project,
merge_request: {
......@@ -24,14 +24,14 @@ RSpec.describe 'Merge request > User sees WIP help message' do
within_wip_explanation do
expect(page).to have_text(
'It looks like you have some WIP commits in this branch'
'It looks like you have some draft commits in this branch'
)
end
end
end
context 'without WIP commits' do
it 'shows the regular WIP message' do
context 'without draft commits' do
it 'shows the regular draft message' do
visit project_new_merge_request_path(
project,
merge_request: {
......@@ -43,11 +43,11 @@ RSpec.describe 'Merge request > User sees WIP help message' do
within_wip_explanation do
expect(page).not_to have_text(
'It looks like you have some WIP commits in this branch'
'It looks like you have some draft commits in this branch'
)
expect(page).to have_text(
"Start the title with WIP: to prevent a Work In Progress merge \
request from being merged before it's ready"
"Start the title with Draft: or WIP: to prevent a merge request that is a \
work in progress from being merged before it's ready."
)
end
end
......
import $ from 'jquery';
import IssuableForm from '~/issuable_form';
function createIssuable() {
const instance = new IssuableForm($(document.createElement('form')));
instance.titleField = $(document.createElement('input'));
return instance;
}
describe('IssuableForm', () => {
let instance;
beforeEach(() => {
instance = createIssuable();
});
describe('removeWip', () => {
it.each`
prefix
${'wip '}
${' wIP: '}
${'[WIp] '}
${'wIP:'}
${' [WIp]'}
${'drAft '}
${'draFT: '}
${' [DRaft] '}
${'drAft:'}
${'[draFT]'}
${' dRaFt - '}
${'dRaFt - '}
${'(draft) '}
${' (DrafT)'}
${'wip wip: [wip] draft draft - draft: [draft] (draft)'}
`('removes "$prefix" from the beginning of the title', ({ prefix }) => {
instance.titleField.val(`${prefix}The Issuable's Title Value`);
instance.removeWip();
expect(instance.titleField.val()).toBe("The Issuable's Title Value");
});
});
describe('addWip', () => {
it("properly adds the work in progress prefix to the Issuable's title", () => {
instance.titleField.val("The Issuable's Title Value");
instance.addWip();
expect(instance.titleField.val()).toBe("Draft: The Issuable's Title Value");
});
});
});
......@@ -84,11 +84,11 @@ describe('Wip', () => {
it('should have correct elements', () => {
expect(el.classList.contains('mr-widget-body')).toBeTruthy();
expect(el.innerText).toContain('This is a Work in Progress');
expect(el.innerText).toContain('This merge request is still a work in progress.');
expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy();
expect(el.querySelector('button').innerText).toContain('Merge');
expect(el.querySelector('.js-remove-wip').innerText.replace(/\s\s+/g, ' ')).toContain(
'Resolve WIP status',
'Mark as ready',
);
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment