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-09-08 15:12:41 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-08 15:12:41 +0300
commit8fea353b907d1fd571f5450a757cafee73cfbfd0 (patch)
tree38cd1edddd3de94d6f743029c164fab5691a7241 /app/assets/javascripts/sidebar
parentdb5097a28b061ef273a058aa64845c79635ea4e7 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/sidebar')
-rw-r--r--app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue75
-rw-r--r--app/assets/javascripts/sidebar/components/sidebar_editable_item.vue18
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue26
-rw-r--r--app/assets/javascripts/sidebar/constants.js20
4 files changed, 133 insertions, 6 deletions
diff --git a/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue b/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue
index b62a2c7bcd1..6c615109bb8 100644
--- a/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue
+++ b/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue
@@ -9,6 +9,8 @@ import {
GlLoadingIcon,
GlIcon,
GlTooltipDirective,
+ GlPopover,
+ GlButton,
} from '@gitlab/ui';
import { kebabCase, snakeCase } from 'lodash';
import createFlash from '~/flash';
@@ -17,6 +19,7 @@ import { IssuableType } from '~/issues/constants';
import { timeFor } from '~/lib/utils/datetime_utility';
import { __ } from '~/locale';
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import {
dropdowni18nText,
Tracking,
@@ -47,7 +50,10 @@ export default {
GlSearchBoxByType,
GlIcon,
GlLoadingIcon,
+ GlPopover,
+ GlButton,
},
+ mixins: [glFeatureFlagMixin()],
inject: {
isClassicSidebar: {
default: false,
@@ -66,6 +72,7 @@ export default {
},
},
},
+
props: {
issuableAttribute: {
type: String,
@@ -111,6 +118,10 @@ export default {
};
},
update(data) {
+ if (this.glFeatures?.epicWidgetEditConfirmation && this.isEpic) {
+ this.hasCurrentAttribute = data?.workspace?.issuable.hasEpic;
+ }
+
return data?.workspace?.issuable.attribute;
},
error(error) {
@@ -179,6 +190,8 @@ export default {
updating: false,
selectedTitle: null,
currentAttribute: null,
+ hasCurrentAttribute: false,
+ editConfirmation: false,
attributesList: [],
tracking: {
event: Tracking.editEvent,
@@ -228,6 +241,15 @@ export default {
snake: snakeCase(this.issuableAttribute),
};
},
+ shouldShowConfirmationPopover() {
+ if (!this.glFeatures?.epicWidgetEditConfirmation) {
+ return false;
+ }
+
+ return this.isEpic && this.currentAttribute === null && this.hasCurrentAttribute
+ ? !this.editConfirmation
+ : false;
+ },
},
methods: {
updateAttribute(attributeId) {
@@ -299,6 +321,17 @@ export default {
setFocus() {
this.$refs.search.focusInput();
},
+ handlePopoverClose() {
+ this.$refs.popover.$emit('close');
+ },
+ handlePopoverConfirm(cb) {
+ this.editConfirmation = true;
+ this.handlePopoverClose();
+ setTimeout(cb, 0);
+ },
+ handleEditConfirmation() {
+ this.$refs.popover.$emit('open');
+ },
},
};
</script>
@@ -308,10 +341,13 @@ export default {
ref="editable"
:title="attributeTypeTitle"
:data-testid="`${formatIssuableAttribute.kebab}-edit`"
+ :button-id="`${formatIssuableAttribute.kebab}-edit`"
:tracking="tracking"
+ :should-show-confirmation-popover="shouldShowConfirmationPopover"
:loading="updating || loading"
@open="handleOpen"
@close="handleClose"
+ @edit-confirm="handleEditConfirmation"
>
<template #collapsed>
<slot name="value-collapsed" :current-attribute="currentAttribute">
@@ -332,6 +368,10 @@ export default {
:class="isClassicSidebar ? 'hide-collapsed' : 'gl-mt-3'"
>
<span v-if="updating">{{ selectedTitle }}</span>
+ <template v-else-if="!currentAttribute && hasCurrentAttribute">
+ <gl-icon name="warning" class="gl-text-orange-500" />
+ <span class="gl-text-gray-500">{{ i18n.noPermissionToView }}</span>
+ </template>
<span v-else-if="!currentAttribute" class="gl-text-gray-500">
{{ $options.i18n.none }}
</span>
@@ -354,7 +394,40 @@ export default {
</slot>
</div>
</template>
- <template #default>
+ <template v-if="shouldShowConfirmationPopover" #default="{ toggle }">
+ <gl-popover
+ ref="popover"
+ :target="`${formatIssuableAttribute.kebab}-edit`"
+ placement="bottomleft"
+ boundary="viewport"
+ triggers="click"
+ >
+ <div class="gl-mb-4 gl-font-base">
+ {{ i18n.editConfirmation }}
+ </div>
+ <div class="gl-display-flex gl-align-items-center">
+ <gl-button
+ size="small"
+ variant="confirm"
+ category="primary"
+ data-testid="confirm-edit-cta"
+ @click.prevent="() => handlePopoverConfirm(toggle)"
+ >{{ i18n.editConfirmationCta }}</gl-button
+ >
+ <gl-button
+ class="gl-ml-auto"
+ size="small"
+ name="cancel"
+ variant="default"
+ category="primary"
+ data-testid="confirm-edit-cancel"
+ @click.prevent="handlePopoverClose"
+ >{{ i18n.editConfirmationCancel }}</gl-button
+ >
+ </div>
+ </gl-popover>
+ </template>
+ <template v-else #default>
<gl-dropdown
ref="newDropdown"
lazy
diff --git a/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue b/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue
index 7551b181a58..cc88812c7b0 100644
--- a/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue
+++ b/app/assets/javascripts/sidebar/components/sidebar_editable_item.vue
@@ -14,6 +14,11 @@ export default {
},
},
props: {
+ buttonId: {
+ type: String,
+ required: false,
+ default: '',
+ },
title: {
type: String,
required: false,
@@ -48,6 +53,11 @@ export default {
required: false,
default: true,
},
+ shouldShowConfirmationPopover: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -97,6 +107,11 @@ export default {
window.removeEventListener('keyup', this.collapseOnEscape);
},
toggle({ emitEvent = true } = {}) {
+ if (this.shouldShowConfirmationPopover) {
+ this.$emit('edit-confirm');
+ return;
+ }
+
if (this.edit) {
this.collapse({ emitEvent });
} else {
@@ -132,6 +147,7 @@ export default {
<slot name="collapsed-right"></slot>
<gl-button
v-if="canUpdate && !initialLoading && canEdit"
+ :id="buttonId"
category="tertiary"
size="small"
class="gl-text-gray-900! gl-ml-auto hide-collapsed gl-mr-n2 shortcut-sidebar-dropdown-toggle"
@@ -151,7 +167,7 @@ export default {
<slot name="collapsed">{{ __('None') }}</slot>
</div>
<div v-show="edit" data-testid="expanded-content" :class="{ 'gl-mt-3': !isClassicSidebar }">
- <slot :edit="edit"></slot>
+ <slot :edit="edit" :toggle="toggle"></slot>
</div>
</template>
</div>
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
index da93c97f07a..13981c477c6 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
@@ -1,8 +1,16 @@
<script>
-import { GlIcon, GlLink, GlModal, GlButton, GlModalDirective, GlLoadingIcon } from '@gitlab/ui';
+import {
+ GlIcon,
+ GlLink,
+ GlModal,
+ GlButton,
+ GlModalDirective,
+ GlLoadingIcon,
+ GlTooltipDirective,
+} from '@gitlab/ui';
import { IssuableType } from '~/issues/constants';
import { s__, __ } from '~/locale';
-import { timeTrackingQueries } from '~/sidebar/constants';
+import { HOW_TO_TRACK_TIME, timeTrackingQueries } from '~/sidebar/constants';
import eventHub from '../../event_hub';
import TimeTrackingCollapsedState from './collapsed_state.vue';
@@ -31,6 +39,7 @@ export default {
},
directives: {
GlModal: GlModalDirective,
+ GlTooltip: GlTooltipDirective,
},
inject: {
issuableType: {
@@ -162,6 +171,12 @@ export default {
this.issuableId
);
},
+ timeTrackingIconTitle() {
+ return this.showHelpState ? '' : HOW_TO_TRACK_TIME;
+ },
+ timeTrackingIconName() {
+ return this.showHelpState ? 'close' : 'question-o';
+ },
},
watch: {
/**
@@ -212,7 +227,12 @@ export default {
class="gl-ml-auto"
@click="toggleHelpState(!showHelpState)"
>
- <gl-icon :name="showHelpState ? 'close' : 'question-o'" class="gl-text-gray-900!" />
+ <gl-icon
+ v-gl-tooltip.left
+ :title="timeTrackingIconTitle"
+ :name="timeTrackingIconName"
+ class="gl-text-gray-900!"
+ />
</gl-button>
</div>
<div v-if="!isTimeTrackingInfoLoading" class="hide-collapsed">
diff --git a/app/assets/javascripts/sidebar/constants.js b/app/assets/javascripts/sidebar/constants.js
index 989dc574bc3..60cb4cff727 100644
--- a/app/assets/javascripts/sidebar/constants.js
+++ b/app/assets/javascripts/sidebar/constants.js
@@ -1,4 +1,4 @@
-import { s__, sprintf } from '~/locale';
+import { s__, __, sprintf } from '~/locale';
import updateIssueLabelsMutation from '~/boards/graphql/issue_set_labels.mutation.graphql';
import userSearchQuery from '~/graphql_shared/queries/users_search.query.graphql';
import userSearchWithMRPermissionsQuery from '~/graphql_shared/queries/users_search_with_mr_permissions.graphql';
@@ -313,8 +313,26 @@ export function dropdowni18nText(issuableAttribute, issuableType) {
),
{ issuableAttribute, issuableType },
),
+ noPermissionToView: sprintf(
+ s__("DropdownWidget|You don't have permission to view this %{issuableAttribute}."),
+ { issuableAttribute },
+ ),
+ editConfirmation: sprintf(
+ s__(
+ 'DropdownWidget|You do not have permission to view the currently assigned %{issuableAttribute} and will not be able to choose it again if you reassign it.',
+ ),
+ {
+ issuableAttribute,
+ },
+ ),
+ editConfirmationCta: sprintf(s__('DropdownWidget|Edit %{issuableAttribute}'), {
+ issuableAttribute,
+ }),
+ editConfirmationCancel: s__('DropdownWidget|Cancel'),
};
}
export const escalationStatusQuery = getEscalationStatusQuery;
export const escalationStatusMutation = updateEscalationStatusMutation;
+
+export const HOW_TO_TRACK_TIME = __('How to track time');