Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-27 21:12:02 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-27 21:12:02 +0300
commit3b060a68f3ca685d0676c2a70e3471dc7ee19d6e (patch)
tree5a3f06014de88fd4564e4f5eb7e6a2ecb1d9e7ce /app/assets/javascripts
parent2977cf67ec27f8ab014bfee852d0ae7b56585242 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/access_tokens/components/expires_at_field.vue30
-rw-r--r--app/assets/javascripts/lib/utils/url_utility.js1
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue8
-rw-r--r--app/assets/javascripts/runner/components/runner_detail.vue9
-rw-r--r--app/assets/javascripts/runner/components/runner_details.vue25
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_participant.vue39
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/queries/get_issue_assignees.query.graphql4
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_assignees.query.graphql7
-rw-r--r--app/assets/javascripts/vue_shared/components/user_select/user_select.vue54
10 files changed, 115 insertions, 66 deletions
diff --git a/app/assets/javascripts/access_tokens/components/expires_at_field.vue b/app/assets/javascripts/access_tokens/components/expires_at_field.vue
index 147de529eea..5516fd0daf6 100644
--- a/app/assets/javascripts/access_tokens/components/expires_at_field.vue
+++ b/app/assets/javascripts/access_tokens/components/expires_at_field.vue
@@ -1,7 +1,8 @@
<script>
-import { GlDatepicker, GlFormInput, GlFormGroup } from '@gitlab/ui';
+import { GlDatepicker, GlFormGroup } from '@gitlab/ui';
import { __ } from '~/locale';
+import { getDateInFuture } from '~/lib/utils/datetime_utility';
export default {
name: 'ExpiresAtField',
@@ -10,7 +11,6 @@ export default {
},
components: {
GlDatepicker,
- GlFormInput,
GlFormGroup,
MaxExpirationDateMessage: () =>
import('ee_component/access_tokens/components/max_expiration_date_message.vue'),
@@ -32,20 +32,28 @@ export default {
default: () => null,
},
},
+ computed: {
+ in30Days() {
+ const today = new Date();
+ return getDateInFuture(today, 30);
+ },
+ },
};
</script>
<template>
<gl-form-group :label="$options.i18n.label" :label-for="inputAttrs.id">
- <gl-datepicker :target="null" :min-date="minDate" :max-date="maxDate">
- <gl-form-input
- v-bind="inputAttrs"
- class="datepicker gl-datepicker-input"
- autocomplete="off"
- inputmode="none"
- data-qa-selector="expiry_date_field"
- />
- </gl-datepicker>
+ <gl-datepicker
+ :target="null"
+ :min-date="minDate"
+ :max-date="maxDate"
+ :default-date="in30Days"
+ show-clear-button
+ :input-name="inputAttrs.name"
+ :input-id="inputAttrs.id"
+ :placeholder="inputAttrs.placeholder"
+ data-qa-selector="expiry_date_field"
+ />
<template #description>
<max-expiration-date-message :max-date="maxDate" />
</template>
diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js
index ff60fd2aecb..597fa49120b 100644
--- a/app/assets/javascripts/lib/utils/url_utility.js
+++ b/app/assets/javascripts/lib/utils/url_utility.js
@@ -397,6 +397,7 @@ export function relativePathToAbsolute(path, basePath) {
const absolute = isAbsolute(basePath);
const base = absolute ? basePath : `file:///${basePath}`;
const url = new URL(path, base);
+ url.pathname = url.pathname.replace(/\/\/+/g, '/');
return absolute ? url.href : decodeURIComponent(url.pathname);
}
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue b/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue
index 29438fba86b..bae6a510993 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue
+++ b/app/assets/javascripts/packages_and_registries/package_registry/pages/details.vue
@@ -208,8 +208,12 @@ export default {
},
handleFileDelete(file) {
this.track(REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION);
- this.fileToDelete = { ...file };
- this.$refs.deleteFileModal.show();
+ if (this.packageFiles.length === 1) {
+ this.$refs.deleteModal.show();
+ } else {
+ this.fileToDelete = { ...file };
+ this.$refs.deleteFileModal.show();
+ }
},
confirmFileDelete() {
this.track(DELETE_PACKAGE_FILE_TRACKING_ACTION);
diff --git a/app/assets/javascripts/runner/components/runner_detail.vue b/app/assets/javascripts/runner/components/runner_detail.vue
index db67acef3db..584f77b7648 100644
--- a/app/assets/javascripts/runner/components/runner_detail.vue
+++ b/app/assets/javascripts/runner/components/runner_detail.vue
@@ -38,11 +38,10 @@ export default {
</script>
<template>
- <div class="gl-display-flex gl-pb-4">
- <dt class="gl-mr-2">{{ label }}</dt>
- <dd class="gl-mb-0">
- <!-- eslint-disable-next-line @gitlab/vue-prefer-dollar-scopedslots -->
- <template v-if="value || $slots.value">
+ <div class="gl-display-contents">
+ <dt class="gl-mb-5 gl-mr-6 gl-max-w-26">{{ label }}</dt>
+ <dd class="gl-mb-5">
+ <template v-if="value || $scopedSlots.value">
<slot name="value">{{ value }}</slot>
</template>
<span v-else class="gl-text-gray-500">{{ emptyValue }}</span>
diff --git a/app/assets/javascripts/runner/components/runner_details.vue b/app/assets/javascripts/runner/components/runner_details.vue
index 60469d26dd5..d5222f39b81 100644
--- a/app/assets/javascripts/runner/components/runner_details.vue
+++ b/app/assets/javascripts/runner/components/runner_details.vue
@@ -51,6 +51,9 @@ export default {
}
return null;
},
+ tagList() {
+ return this.runner.tagList || [];
+ },
isGroupRunner() {
return this.runner?.runnerType === GROUP_TYPE;
},
@@ -66,14 +69,17 @@ export default {
<div>
<runner-upgrade-status-alert class="gl-my-4" :runner="runner" />
<div class="gl-pt-4">
- <dl class="gl-mb-0" data-testid="runner-details-list">
+ <dl
+ class="gl-mb-0 gl-display-grid runner-details-grid-template"
+ data-testid="runner-details-list"
+ >
<runner-detail :label="s__('Runners|Description')" :value="runner.description" />
<runner-detail
:label="s__('Runners|Last contact')"
:empty-value="s__('Runners|Never contacted')"
>
- <template #value>
- <time-ago v-if="runner.contactedAt" :time="runner.contactedAt" />
+ <template v-if="runner.contactedAt" #value>
+ <time-ago :time="runner.contactedAt" />
</template>
</runner-detail>
<runner-detail :label="s__('Runners|Version')">
@@ -87,8 +93,8 @@ export default {
<runner-detail :label="s__('Runners|Architecture')" :value="runner.architectureName" />
<runner-detail :label="s__('Runners|Platform')" :value="runner.platformName" />
<runner-detail :label="s__('Runners|Configuration')">
- <template #value>
- <gl-intersperse v-if="configTextProtected || configTextUntagged">
+ <template v-if="configTextProtected || configTextUntagged" #value>
+ <gl-intersperse>
<span v-if="configTextProtected">{{ configTextProtected }}</span>
<span v-if="configTextUntagged">{{ configTextUntagged }}</span>
</gl-intersperse>
@@ -96,13 +102,8 @@ export default {
</runner-detail>
<runner-detail :label="s__('Runners|Maximum job timeout')" :value="maximumTimeout" />
<runner-detail :label="s__('Runners|Tags')">
- <template #value>
- <runner-tags
- v-if="runner.tagList && runner.tagList.length"
- class="gl-vertical-align-middle"
- :tag-list="runner.tagList"
- size="sm"
- />
+ <template v-if="tagList.length" #value>
+ <runner-tags class="gl-vertical-align-middle" :tag-list="tagList" size="sm" />
</template>
</runner-detail>
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
index 14f6c9d3a15..5c432ca0e03 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
@@ -149,6 +149,9 @@ export default {
signedIn() {
return this.currentUser.username !== undefined;
},
+ issuableAuthor() {
+ return this.issuable?.author;
+ },
},
watch: {
iid(_, oldIid) {
@@ -266,6 +269,7 @@ export default {
:current-user="currentUser"
:issuable-type="issuableType"
:is-editing="edit"
+ :issuable-author="issuableAuthor"
class="gl-w-full dropdown-menu-user gl-mt-n3"
@toggle="collapseWidget"
@error="showError"
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_participant.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_participant.vue
index e9c68008143..0ed40f56bea 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_participant.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_participant.vue
@@ -1,5 +1,5 @@
<script>
-import { GlAvatarLabeled, GlAvatarLink, GlIcon } from '@gitlab/ui';
+import { GlAvatarLabeled, GlIcon } from '@gitlab/ui';
import { IssuableType } from '~/issues/constants';
import { s__, sprintf } from '~/locale';
@@ -11,7 +11,6 @@ const AVAILABILITY_STATUS = {
export default {
components: {
GlAvatarLabeled,
- GlAvatarLink,
GlIcon,
},
props: {
@@ -47,23 +46,21 @@ export default {
</script>
<template>
- <gl-avatar-link>
- <gl-avatar-labeled
- :size="32"
- :label="userLabel"
- :sub-label="`@${user.username}`"
- :src="user.avatarUrl || user.avatar || user.avatar_url"
- class="gl-align-items-center gl-relative"
- >
- <template #meta>
- <gl-icon
- v-if="hasCannotMergeIcon"
- name="warning-solid"
- aria-hidden="true"
- class="merge-icon"
- :size="12"
- />
- </template>
- </gl-avatar-labeled>
- </gl-avatar-link>
+ <gl-avatar-labeled
+ :size="32"
+ :label="userLabel"
+ :sub-label="`@${user.username}`"
+ :src="user.avatarUrl || user.avatar || user.avatar_url"
+ class="gl-align-items-center gl-relative sidebar-participant"
+ >
+ <template #meta>
+ <gl-icon
+ v-if="hasCannotMergeIcon"
+ name="warning-solid"
+ aria-hidden="true"
+ class="merge-icon gl-left-6 gl-bottom-0"
+ :size="12"
+ />
+ </template>
+ </gl-avatar-labeled>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/queries/get_issue_assignees.query.graphql b/app/assets/javascripts/vue_shared/components/sidebar/queries/get_issue_assignees.query.graphql
index be270e440ed..10e6daa1f50 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/queries/get_issue_assignees.query.graphql
+++ b/app/assets/javascripts/vue_shared/components/sidebar/queries/get_issue_assignees.query.graphql
@@ -8,6 +8,10 @@ query issueAssignees($fullPath: ID!, $iid: String!) {
issuable: issue(iid: $iid) {
__typename
id
+ author {
+ ...User
+ ...UserAvailability
+ }
assignees {
nodes {
...User
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_assignees.query.graphql b/app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_assignees.query.graphql
index 7127940bb05..f70cd723f2e 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_assignees.query.graphql
+++ b/app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_assignees.query.graphql
@@ -6,6 +6,13 @@ query getMrAssignees($fullPath: ID!, $iid: String!) {
id
issuable: mergeRequest(iid: $iid) {
id
+ author {
+ ...User
+ ...UserAvailability
+ mergeRequestInteraction {
+ canMerge
+ }
+ }
assignees {
nodes {
...User
diff --git a/app/assets/javascripts/vue_shared/components/user_select/user_select.vue b/app/assets/javascripts/vue_shared/components/user_select/user_select.vue
index 91f20863089..43a590c2367 100644
--- a/app/assets/javascripts/vue_shared/components/user_select/user_select.vue
+++ b/app/assets/javascripts/vue_shared/components/user_select/user_select.vue
@@ -77,6 +77,11 @@ export default {
required: false,
default: null,
},
+ issuableAuthor: {
+ type: Object,
+ required: false,
+ default: null,
+ },
},
data() {
return {
@@ -178,7 +183,7 @@ export default {
[],
);
- return this.moveCurrentUserToStart(mergedSearchResults);
+ return this.moveCurrentUserAndAuthorToStart(mergedSearchResults);
},
isSearchEmpty() {
return this.search === '';
@@ -196,14 +201,21 @@ export default {
showCurrentUser() {
return this.currentUser.username && !this.isCurrentUserInList && this.isSearchEmpty;
},
+ showAuthor() {
+ return (
+ this.issuableAuthor &&
+ !this.users.some((user) => user.id === this.issuableAuthor.id) &&
+ this.isSearchEmpty
+ );
+ },
selectedFiltered() {
if (this.shouldShowParticipants) {
- return this.moveCurrentUserToStart(this.value);
+ return this.moveCurrentUserAndAuthorToStart(this.value);
}
const foundUsernames = this.users.map(({ username }) => username);
const filtered = this.value.filter(({ username }) => foundUsernames.includes(username));
- return this.moveCurrentUserToStart(filtered);
+ return this.moveCurrentUserAndAuthorToStart(filtered);
},
selectedUserNames() {
return this.value.map(({ username }) => username);
@@ -254,20 +266,22 @@ export default {
showDivider(list) {
return list.length > 0 && this.isSearchEmpty;
},
- moveCurrentUserToStart(users) {
- if (!users) {
- return [];
+ moveCurrentUserAndAuthorToStart(users = []) {
+ let sortedUsers = [...users];
+
+ const author = sortedUsers.find((user) => user.id === this.issuableAuthor?.id);
+ if (author) {
+ sortedUsers = [author, ...sortedUsers.filter((user) => user.id !== author.id)];
}
- const usersCopy = [...users];
- const currentUser = usersCopy.find((user) => user.username === this.currentUser.username);
+
+ const currentUser = sortedUsers.find((user) => user.username === this.currentUser.username);
if (currentUser) {
currentUser.canMerge = this.currentUser.canMerge;
- const index = usersCopy.indexOf(currentUser);
- usersCopy.splice(0, 0, usersCopy.splice(index, 1)[0]);
+ sortedUsers = [currentUser, ...sortedUsers.filter((user) => user.id !== currentUser.id)];
}
- return usersCopy;
+ return sortedUsers;
},
setSearchKey(value) {
this.search = value.trim();
@@ -298,7 +312,7 @@ export default {
<gl-loading-icon
v-if="isLoading"
data-testid="loading-participants"
- size="lg"
+ size="md"
class="gl-absolute gl-left-0 gl-top-0 gl-right-0"
/>
<template v-else>
@@ -312,8 +326,8 @@ export default {
>
<span :class="selectedIsEmpty ? 'gl-pl-0' : 'gl-pl-6'" class="gl-font-weight-bold">{{
$options.i18n.unassigned
- }}</span></gl-dropdown-item
- >
+ }}</span>
+ </gl-dropdown-item>
</template>
<gl-dropdown-divider v-if="showDivider(selectedFiltered)" />
<gl-dropdown-item
@@ -342,7 +356,17 @@ export default {
/>
</gl-dropdown-item>
</template>
- <gl-dropdown-divider v-if="showDivider(unselectedFiltered)" />
+ <gl-dropdown-item
+ v-if="showAuthor"
+ data-testid="issuable-author"
+ @click.native.capture.stop="selectAssignee(issuableAuthor)"
+ >
+ <sidebar-participant
+ :user="issuableAuthor"
+ :issuable-type="issuableType"
+ class="gl-pl-6!"
+ />
+ </gl-dropdown-item>
<gl-dropdown-item
v-for="unselectedUser in unselectedFiltered"
:key="unselectedUser.id"