Skip to content

Commit

Permalink
Add latest changes from gitlab-org/gitlab@master
Browse files Browse the repository at this point in the history
  • Loading branch information
GitLab Bot committed Nov 10, 2020
1 parent 552db97 commit 01c201b
Show file tree
Hide file tree
Showing 49 changed files with 1,294 additions and 644 deletions.
2 changes: 1 addition & 1 deletion .gitlab/ci/test-metadata.gitlab-ci.yml
Expand Up @@ -9,7 +9,7 @@
- knapsack/
- rspec_flaky/
- rspec_profiling/
- crystalball/
- crystalball/packed-mapping.json.gz

retrieve-tests-metadata:
extends:
Expand Down
32 changes: 27 additions & 5 deletions app/assets/javascripts/api.js
Expand Up @@ -34,6 +34,7 @@ const Api = {
mergeRequestsPath: '/api/:version/merge_requests',
groupLabelsPath: '/groups/:namespace_path/-/labels',
issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key',
issuableTemplatesPath: '/:namespace_path/:project_path/templates/:type',
projectTemplatePath: '/api/:version/projects/:id/templates/:type/:key',
projectTemplatesPath: '/api/:version/projects/:id/templates/:type',
userCountsPath: '/api/:version/user_counts',
Expand Down Expand Up @@ -460,17 +461,38 @@ const Api = {
},

issueTemplate(namespacePath, projectPath, key, type, callback) {
const url = Api.buildUrl(Api.issuableTemplatePath)
.replace(':key', encodeURIComponent(key))
.replace(':type', type)
.replace(':project_path', projectPath)
.replace(':namespace_path', namespacePath);
const url = this.buildIssueTemplateUrl(
Api.issuableTemplatePath,
type,
projectPath,
namespacePath,
).replace(':key', encodeURIComponent(key));
return axios
.get(url)
.then(({ data }) => callback(null, data))
.catch(callback);
},

issueTemplates(namespacePath, projectPath, type, callback) {
const url = this.buildIssueTemplateUrl(
Api.issuableTemplatesPath,
type,
projectPath,
namespacePath,
);
return axios
.get(url)
.then(({ data }) => callback(null, data))
.catch(callback);
},

buildIssueTemplateUrl(path, type, projectPath, namespacePath) {
return Api.buildUrl(path)
.replace(':type', type)
.replace(':project_path', projectPath)
.replace(':namespace_path', namespacePath);
},

users(query, options) {
const url = Api.buildUrl(this.usersPath);
return axios.get(url, {
Expand Down
3 changes: 0 additions & 3 deletions app/assets/javascripts/design_management/constants.js
Expand Up @@ -5,9 +5,6 @@ export const VALID_DESIGN_FILE_MIMETYPE = {
regex: /image\/.+/,
};

// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types
export const VALID_DATA_TRANSFER_TYPE = 'Files';

export const ACTIVE_DISCUSSION_SOURCE_TYPES = {
pin: 'pin',
discussion: 'discussion',
Expand Down
67 changes: 57 additions & 10 deletions app/assets/javascripts/design_management/pages/index.vue
@@ -1,17 +1,17 @@
<script>
import { GlLoadingIcon, GlButton, GlAlert } from '@gitlab/ui';
import { GlLoadingIcon, GlButton, GlAlert, GlLink, GlSprintf } from '@gitlab/ui';
import VueDraggable from 'vuedraggable';
import getDesignListQuery from 'shared_queries/design_management/get_design_list.query.graphql';
import permissionsQuery from 'shared_queries/design_management/design_permissions.query.graphql';
import createFlash, { FLASH_TYPES } from '~/flash';
import { s__, sprintf } from '~/locale';
import { __, s__, sprintf } from '~/locale';
import { getFilename } from '~/lib/utils/file_upload';
import UploadButton from '../components/upload/button.vue';
import DeleteButton from '../components/delete_button.vue';
import Design from '../components/list/item.vue';
import DesignDestroyer from '../components/design_destroyer.vue';
import DesignVersionDropdown from '../components/upload/design_version_dropdown.vue';
import DesignDropzone from '../components/upload/design_dropzone.vue';
import DesignDropzone from '~/vue_shared/components/upload_dropzone/upload_dropzone.vue';
import uploadDesignMutation from '../graphql/mutations/upload_design.mutation.graphql';
import moveDesignMutation from '../graphql/mutations/move_design.mutation.graphql';
import allDesignsMixin from '../mixins/all_designs';
Expand All @@ -20,6 +20,7 @@ import {
EXISTING_DESIGN_DROP_MANY_FILES_MESSAGE,
EXISTING_DESIGN_DROP_INVALID_FILENAME_MESSAGE,
MOVE_DESIGN_ERROR,
UPLOAD_DESIGN_INVALID_FILETYPE_ERROR,
designUploadSkippedWarning,
designDeletionError,
} from '../utils/error_messages';
Expand All @@ -34,6 +35,7 @@ import {
} from '../utils/design_management_utils';
import { trackDesignCreate, trackDesignUpdate } from '../utils/tracking';
import { DESIGNS_ROUTE_NAME } from '../router/constants';
import { VALID_DESIGN_FILE_MIMETYPE } from '../constants';
const MAXIMUM_FILE_UPLOAD_LIMIT = 10;
Expand All @@ -42,6 +44,8 @@ export default {
GlLoadingIcon,
GlAlert,
GlButton,
GlSprintf,
GlLink,
UploadButton,
Design,
DesignDestroyer,
Expand All @@ -50,6 +54,11 @@ export default {
DesignDropzone,
VueDraggable,
},
dropzoneProps: {
dropToStartMessage: __('Drop your designs to start your upload.'),
isFileValid: isValidDesignFile,
validFileMimetypes: [VALID_DESIGN_FILE_MIMETYPE.mimetype],
},
mixins: [allDesignsMixin],
apollo: {
permissions: {
Expand Down Expand Up @@ -247,6 +256,9 @@ export default {
const errorMessage = designDeletionError({ singular: this.selectedDesigns.length === 1 });
createFlash({ message: errorMessage });
},
onDesignDropzoneError() {
createFlash({ message: UPLOAD_DESIGN_INVALID_FILETYPE_ERROR });
},
onExistingDesignDropzoneChange(files, existingDesignFilename) {
const filesArr = Array.from(files);
Expand Down Expand Up @@ -325,6 +337,9 @@ export default {
animation: 200,
ghostClass: 'gl-visibility-hidden',
},
i18n: {
dropzoneDescriptionText: __('Drop or %{linkStart}upload%{linkEnd} designs to attach'),
},
};
</script>
Expand All @@ -335,7 +350,11 @@ export default {
@mouseenter="toggleOnPasteListener"
@mouseleave="toggleOffPasteListener"
>
<header v-if="showToolbar" class="row-content-block gl-border-t-0 gl-p-3 gl-display-flex">
<header
v-if="showToolbar"
class="row-content-block gl-border-t-0 gl-p-3 gl-display-flex"
data-testid="design-toolbar-wrapper"
>
<div class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-w-full">
<div>
<span class="gl-font-weight-bold gl-mr-3">{{ s__('DesignManagement|Designs') }}</span>
Expand Down Expand Up @@ -371,7 +390,12 @@ export default {
{{ s__('DesignManagement|Archive selected') }}
</delete-button>
</design-destroyer>
<upload-button v-if="canCreateDesign" :is-saving="isSaving" @upload="onUploadDesign" />
<upload-button
v-if="canCreateDesign"
:is-saving="isSaving"
data-testid="design-upload-button"
@upload="onUploadDesign"
/>
</div>
</div>
</header>
Expand Down Expand Up @@ -414,15 +438,26 @@ export default {
class="col-md-6 col-lg-3 gl-mb-3 gl-bg-transparent gl-shadow-none js-design-tile"
>
<design-dropzone
:has-designs="hasDesigns"
:is-dragging-design="isDraggingDesign"
:display-as-card="hasDesigns"
:enable-drag-behavior="isDraggingDesign"
v-bind="$options.dropzoneProps"
@change="onExistingDesignDropzoneChange($event, design.filename)"
@error="onDesignDropzoneError"
>
<design
v-bind="design"
:is-uploading="isDesignToBeSaved(design.filename)"
class="gl-bg-white"
/>
<template #upload-text="{ openFileUpload }">
<gl-sprintf :message="$options.i18n.dropzoneDescriptionText">
<template #link="{ content }">
<gl-link @click.stop="openFileUpload">
{{ content }}
</gl-link>
</template>
</gl-sprintf>
</template>
</design-dropzone>
<input
Expand All @@ -438,12 +473,24 @@ export default {
<template #header>
<li :class="designDropzoneWrapperClass" data-testid="design-dropzone-wrapper">
<design-dropzone
:is-dragging-design="isDraggingDesign"
:enable-drag-behavior="isDraggingDesign"
:class="{ 'design-list-item design-list-item-new': !isDesignListEmpty }"
:has-designs="hasDesigns"
:display-as-card="hasDesigns"
v-bind="$options.dropzoneProps"
data-qa-selector="design_dropzone_content"
@change="onUploadDesign"
/>
@error="onDesignDropzoneError"
>
<template #upload-text="{ openFileUpload }">
<gl-sprintf :message="$options.i18n.dropzoneDescriptionText">
<template #link="{ content }">
<gl-link @click.stop="openFileUpload">
{{ content }}
</gl-link>
</template>
</gl-sprintf>
</template>
</design-dropzone>
</li>
</template>
</vue-draggable>
Expand Down
77 changes: 56 additions & 21 deletions app/assets/javascripts/issue_show/components/header_actions.vue
Expand Up @@ -2,8 +2,10 @@
import { GlButton, GlDropdown, GlDropdownItem, GlIcon, GlLink, GlModal } from '@gitlab/ui';
import { mapGetters } from 'vuex';
import createFlash from '~/flash';
import { IssuableType } from '~/issuable_show/constants';
import { IssuableStatus, IssueStateEvent } from '~/issue_show/constants';
import { __ } from '~/locale';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
import { __, sprintf } from '~/locale';
import updateIssueMutation from '../queries/update_issue.mutation.graphql';
export default {
Expand All @@ -22,18 +24,41 @@ export default {
text: __('Yes, close issue'),
attributes: [{ variant: 'warning' }],
},
inject: [
'canCreateIssue',
'canReopenIssue',
'canReportSpam',
'canUpdateIssue',
'iid',
'isIssueAuthor',
'newIssuePath',
'projectPath',
'reportAbusePath',
'submitAsSpamPath',
],
inject: {
canCreateIssue: {
default: false,
},
canReopenIssue: {
default: false,
},
canReportSpam: {
default: false,
},
canUpdateIssue: {
default: false,
},
iid: {
default: '',
},
isIssueAuthor: {
default: false,
},
issueType: {
default: IssuableType.Issue,
},
newIssuePath: {
default: '',
},
projectPath: {
default: '',
},
reportAbusePath: {
default: '',
},
submitAsSpamPath: {
default: '',
},
},
data() {
return {
isUpdatingState: false,
Expand All @@ -45,12 +70,22 @@ export default {
return this.getNoteableData.state === IssuableStatus.Closed;
},
buttonText() {
return this.isClosed ? __('Reopen issue') : __('Close issue');
return this.isClosed
? sprintf(__('Reopen %{issueType}'), { issueType: this.issueType })
: sprintf(__('Close %{issueType}'), { issueType: this.issueType });
},
buttonVariant() {
return this.isClosed ? 'default' : 'warning';
},
showToggleIssueButton() {
dropdownText() {
return sprintf(__('%{issueType} actions'), {
issueType: capitalizeFirstCharacter(this.issueType),
});
},
newIssueTypeText() {
return sprintf(__('New %{issueType}'), { issueType: this.issueType });
},
showToggleIssueStateButton() {
const canClose = !this.isClosed && this.canUpdateIssue;
const canReopen = this.isClosed && this.canReopenIssue;
return canClose || canReopen;
Expand Down Expand Up @@ -106,16 +141,16 @@ export default {
<template>
<div class="detail-page-header-actions">
<gl-dropdown class="gl-display-block gl-display-sm-none!" block :text="__('Issue actions')">
<gl-dropdown class="gl-display-block gl-display-sm-none!" block :text="dropdownText">
<gl-dropdown-item
v-if="showToggleIssueButton"
v-if="showToggleIssueStateButton"
:disabled="isUpdatingState"
@click="toggleIssueState"
>
{{ buttonText }}
</gl-dropdown-item>
<gl-dropdown-item v-if="canCreateIssue" :href="newIssuePath">
{{ __('New issue') }}
{{ newIssueTypeText }}
</gl-dropdown-item>
<gl-dropdown-item v-if="!isIssueAuthor" :href="reportAbusePath">
{{ __('Report abuse') }}
Expand All @@ -131,7 +166,7 @@ export default {
</gl-dropdown>
<gl-button
v-if="showToggleIssueButton"
v-if="showToggleIssueStateButton"
class="gl-display-none gl-display-sm-inline-flex!"
category="secondary"
:loading="isUpdatingState"
Expand All @@ -149,11 +184,11 @@ export default {
>
<template #button-content>
<gl-icon name="ellipsis_v" aria-hidden="true" />
<span class="gl-sr-only">{{ __('Actions') }}</span>
<span class="gl-sr-only">{{ dropdownText }}</span>
</template>
<gl-dropdown-item v-if="canCreateIssue" :href="newIssuePath">
{{ __('New issue') }}
{{ newIssueTypeText }}
</gl-dropdown-item>
<gl-dropdown-item v-if="!isIssueAuthor" :href="reportAbusePath">
{{ __('Report abuse') }}
Expand Down
1 change: 1 addition & 0 deletions app/assets/javascripts/issue_show/issue.js
Expand Up @@ -50,6 +50,7 @@ export function initIssueHeaderActions(store) {
canUpdateIssue: parseBoolean(el.dataset.canUpdateIssue),
iid: el.dataset.iid,
isIssueAuthor: parseBoolean(el.dataset.isIssueAuthor),
issueType: el.dataset.issueType,
newIssuePath: el.dataset.newIssuePath,
projectPath: el.dataset.projectPath,
reportAbusePath: el.dataset.reportAbusePath,
Expand Down

0 comments on commit 01c201b

Please sign in to comment.