debian-mirror-gitlab/app/assets/javascripts/super_sidebar/components/user_menu.vue

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

292 lines
8.6 KiB
Vue
Raw Normal View History

2023-05-27 22:25:52 +05:30
<script>
import {
GlAvatar,
GlBadge,
GlDisclosureDropdown,
GlDisclosureDropdownGroup,
GlDisclosureDropdownItem,
} from '@gitlab/ui';
import SafeHtml from '~/vue_shared/directives/safe_html';
import { s__, __, sprintf } from '~/locale';
import NewNavToggle from '~/nav/components/new_nav_toggle.vue';
import Tracking from '~/tracking';
import PersistentUserCallout from '~/persistent_user_callout';
import UserNameGroup from './user_name_group.vue';
export default {
feedbackUrl: 'https://gitlab.com/gitlab-org/gitlab/-/issues/391533',
i18n: {
newNavigation: {
badgeLabel: s__('NorthstarNavigation|Alpha'),
sectionTitle: s__('NorthstarNavigation|Navigation redesign'),
},
setStatus: s__('SetStatusModal|Set status'),
editStatus: s__('SetStatusModal|Edit status'),
editProfile: s__('CurrentUser|Edit profile'),
preferences: s__('CurrentUser|Preferences'),
buyPipelineMinutes: s__('CurrentUser|Buy Pipeline minutes'),
oneOfGroupsRunningOutOfPipelineMinutes: s__('CurrentUser|One of your groups is running out'),
gitlabNext: s__('CurrentUser|Switch to GitLab Next'),
provideFeedback: s__('NorthstarNavigation|Provide feedback'),
startTrial: s__('CurrentUser|Start an Ultimate trial'),
signOut: __('Sign out'),
},
components: {
GlAvatar,
GlBadge,
GlDisclosureDropdown,
GlDisclosureDropdownGroup,
GlDisclosureDropdownItem,
NewNavToggle,
UserNameGroup,
},
directives: {
SafeHtml,
},
mixins: [Tracking.mixin()],
inject: ['toggleNewNavEndpoint'],
props: {
data: {
required: true,
type: Object,
},
},
computed: {
toggleText() {
return sprintf(__('%{user} users menu'), { user: this.data.name });
},
statusItem() {
const { busy, customized } = this.data.status;
const statusLabel =
busy || customized ? this.$options.i18n.editStatus : this.$options.i18n.setStatus;
return {
text: statusLabel,
extraAttrs: {
class: 'js-set-status-modal-trigger',
},
};
},
trialItem() {
return {
text: this.$options.i18n.startTrial,
href: this.data.trial.url,
};
},
editProfileItem() {
return {
text: this.$options.i18n.editProfile,
href: this.data.settings.profile_path,
extraAttrs: {
'data-qa-selector': 'edit_profile_link',
},
};
},
preferencesItem() {
return {
text: this.$options.i18n.preferences,
href: this.data.settings.profile_preferences_path,
};
},
addBuyPipelineMinutesMenuItem() {
return this.data.pipeline_minutes?.show_buy_pipeline_minutes;
},
buyPipelineMinutesItem() {
return {
text: this.$options.i18n.buyPipelineMinutes,
warningText: this.$options.i18n.oneOfGroupsRunningOutOfPipelineMinutes,
href: this.data.pipeline_minutes?.buy_pipeline_minutes_path,
extraAttrs: {
class: 'js-follow-link',
},
};
},
gitlabNextItem() {
return {
text: this.$options.i18n.gitlabNext,
href: this.data.canary_toggle_com_url,
};
},
feedbackItem() {
return {
text: this.$options.i18n.provideFeedback,
href: this.$options.feedbackUrl,
extraAttrs: {
target: '_blank',
},
};
},
signOutGroup() {
return {
items: [
{
text: this.$options.i18n.signOut,
href: this.data.sign_out_link,
extraAttrs: {
'data-method': 'post',
'data-qa-selector': 'sign_out_link',
class: 'sign-out-link',
},
},
],
};
},
statusModalData() {
const defaultData = {
'data-current-emoji': '',
'data-current-message': '',
'data-default-emoji': 'speech_balloon',
};
if (!this.data.status.customized) {
return defaultData;
}
return {
...defaultData,
'data-current-emoji': this.data.status.emoji,
'data-current-message': this.data.status.message,
'data-current-availability': this.data.status.availability,
'data-current-clear-status-after': this.data.status.clear_after,
};
},
buyPipelineMinutesCalloutData() {
return this.showNotificationDot
? {
'data-feature-id': this.data.pipeline_minutes.callout_attrs.feature_id,
'data-dismiss-endpoint': this.data.pipeline_minutes.callout_attrs.dismiss_endpoint,
}
: {};
},
showNotificationDot() {
return this.data.pipeline_minutes?.show_notification_dot;
},
},
methods: {
onShow() {
this.trackEvents();
this.initCallout();
},
initCallout() {
if (this.showNotificationDot) {
PersistentUserCallout.factory(this.$refs?.buyPipelineMinutesNotificationCallout.$el);
}
},
trackEvents() {
if (this.addBuyPipelineMinutesMenuItem) {
const {
'track-action': trackAction,
'track-label': label,
'track-property': property,
} = this.data.pipeline_minutes.tracking_attrs;
this.track(trackAction, { label, property });
}
},
},
};
</script>
<template>
<div>
<gl-disclosure-dropdown
placement="right"
data-testid="user-dropdown"
data-qa-selector="user_menu"
@shown="onShow"
>
<template #toggle>
<button class="user-bar-item btn-with-notification">
<span class="gl-sr-only">{{ toggleText }}</span>
<gl-avatar
:size="24"
:entity-name="data.name"
:src="data.avatar_url"
aria-hidden="true"
data-qa-selector="user_avatar_content"
/>
<span
v-if="showNotificationDot"
class="notification-dot-warning"
data-testid="buy-pipeline-minutes-notification-dot"
v-bind="data.pipeline_minutes.notification_dot_attrs"
>
</span>
</button>
</template>
<user-name-group :user="data" />
<gl-disclosure-dropdown-group bordered>
<gl-disclosure-dropdown-item
v-if="data.status.can_update"
:item="statusItem"
data-testid="status-item"
/>
<gl-disclosure-dropdown-item
v-if="data.trial.has_start_trial"
:item="trialItem"
data-testid="start-trial-item"
>
<template #list-item>
{{ trialItem.text }}
<gl-emoji data-name="rocket" />
</template>
</gl-disclosure-dropdown-item>
<gl-disclosure-dropdown-item :item="editProfileItem" data-testid="edit-profile-item" />
<gl-disclosure-dropdown-item :item="preferencesItem" data-testid="preferences-item" />
<gl-disclosure-dropdown-item
v-if="addBuyPipelineMinutesMenuItem"
ref="buyPipelineMinutesNotificationCallout"
:item="buyPipelineMinutesItem"
v-bind="buyPipelineMinutesCalloutData"
data-testid="buy-pipeline-minutes-item"
>
<template #list-item>
<span class="gl-display-flex gl-flex-direction-column">
<span>{{ buyPipelineMinutesItem.text }} <gl-emoji data-name="clock9" /></span>
<span
v-if="data.pipeline_minutes.show_with_subtext"
class="gl-font-sm small gl-pt-2 gl-text-orange-800"
>{{ buyPipelineMinutesItem.warningText }}</span
>
</span>
</template>
</gl-disclosure-dropdown-item>
<gl-disclosure-dropdown-item
v-if="data.gitlab_com_but_not_canary"
:item="gitlabNextItem"
data-testid="gitlab-next-item"
/>
</gl-disclosure-dropdown-group>
<gl-disclosure-dropdown-group bordered>
<template #group-label>
<span class="gl-font-sm">{{ $options.i18n.newNavigation.sectionTitle }}</span>
<gl-badge size="sm" variant="info"
>{{ $options.i18n.newNavigation.badgeLabel }}
</gl-badge>
</template>
<new-nav-toggle :endpoint="toggleNewNavEndpoint" enabled new-navigation />
<gl-disclosure-dropdown-item :item="feedbackItem" data-testid="feedback-item" />
</gl-disclosure-dropdown-group>
<gl-disclosure-dropdown-group
v-if="data.can_sign_out"
bordered
:group="signOutGroup"
data-testid="sign-out-group"
/>
</gl-disclosure-dropdown>
<div
v-if="data.status.can_update"
class="js-set-status-modal-wrapper"
v-bind="statusModalData"
></div>
</div>
</template>