diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-18 03:10:36 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-18 03:10:36 +0300 |
commit | 4eee0fe3f55ecdd5d607202d93508259239b590f (patch) | |
tree | 87bfbb30e6e98ae4135221d562515888e919ec10 /app/assets/javascripts/profile | |
parent | 0ad8135c1feeefa23ec883e409fb65b8b52882a1 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/profile')
3 files changed, 149 insertions, 0 deletions
diff --git a/app/assets/javascripts/profile/components/graphql/get_user_achievements.query.graphql b/app/assets/javascripts/profile/components/graphql/get_user_achievements.query.graphql new file mode 100644 index 00000000000..e60f383ad1c --- /dev/null +++ b/app/assets/javascripts/profile/components/graphql/get_user_achievements.query.graphql @@ -0,0 +1,21 @@ +query getUserAchievements($id: UserID!) { + user(id: $id) { + id + userAchievements { + nodes { + id + createdAt + achievement { + id + name + description + avatarUrl + namespace { + id + fullPath + } + } + } + } + } +} diff --git a/app/assets/javascripts/profile/components/user_achievements.vue b/app/assets/javascripts/profile/components/user_achievements.vue new file mode 100644 index 00000000000..790b0e9f303 --- /dev/null +++ b/app/assets/javascripts/profile/components/user_achievements.vue @@ -0,0 +1,100 @@ +<script> +import { GlPopover, GlSprintf } from '@gitlab/ui'; +import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils'; +import { s__ } from '~/locale'; +import { TYPENAME_USER } from '~/graphql_shared/constants'; +import timeagoMixin from '~/vue_shared/mixins/timeago'; +import getUserAchievements from './graphql/get_user_achievements.query.graphql'; + +export default { + name: 'UserAchievements', + components: { GlPopover, GlSprintf }, + mixins: [timeagoMixin], + inject: ['rootUrl', 'userId'], + apollo: { + userAchievements: { + query: getUserAchievements, + variables() { + return { + id: convertToGraphQLId(TYPENAME_USER, this.userId), + }; + }, + update(data) { + return this.processNodes(data.user.userAchievements.nodes); + }, + error() { + return []; + }, + }, + }, + methods: { + processNodes(nodes) { + return nodes.slice(0, 3).map( + ({ + achievement, + createdAt, + achievement: { + namespace: { fullPath }, + }, + }) => { + return { + id: `user-achievement-${getIdFromGraphQLId(achievement.id)}`, + name: achievement.name, + timeAgo: this.timeFormatted(createdAt), + avatarUrl: achievement.avatarUrl || gon.gitlab_logo, + description: achievement.description, + namespace: { + fullPath, + webUrl: this.rootUrl + fullPath, + }, + }; + }, + ); + }, + }, + i18n: { + awardedBy: s__('Achievements|Awarded %{timeAgo} by %{namespace}'), + }, +}; +</script> + +<template> + <div class="gl-mb-3"> + <div + v-for="userAchievement in userAchievements" + :key="userAchievement.id" + class="gl-display-inline-block" + data-testid="user-achievement" + > + <img + :id="userAchievement.id" + :src="userAchievement.avatarUrl" + :alt="''" + tabindex="0" + class="gl-avatar gl-avatar-s32 gl-mx-2" + /> + <gl-popover triggers="hover focus" placement="top" :target="userAchievement.id"> + <div class="gl-font-weight-bold">{{ userAchievement.name }}</div> + <div> + <gl-sprintf :message="$options.i18n.awardedBy"> + <template #timeAgo> + <span>{{ userAchievement.timeAgo }}</span> + </template> + <template #namespace> + <a :href="userAchievement.namespace.webUrl">{{ + userAchievement.namespace.fullPath + }}</a> + </template> + </gl-sprintf> + </div> + <div + v-if="userAchievement.description" + class="gl-mt-5" + data-testid="achievement-description" + > + {{ userAchievement.description }} + </div> + </gl-popover> + </div> + </div> +</template> diff --git a/app/assets/javascripts/profile/index.js b/app/assets/javascripts/profile/index.js index fe430ccca98..fbe0e3534d8 100644 --- a/app/assets/javascripts/profile/index.js +++ b/app/assets/javascripts/profile/index.js @@ -1,6 +1,12 @@ import Vue from 'vue'; +import VueApollo from 'vue-apollo'; + +import createDefaultClient from '~/lib/graphql'; import ProfileTabs from './components/profile_tabs.vue'; +import UserAchievements from './components/user_achievements.vue'; + +Vue.use(VueApollo); export const initProfileTabs = () => { const el = document.getElementById('js-profile-tabs'); @@ -22,3 +28,25 @@ export const initProfileTabs = () => { }, }); }; + +export const initUserAchievements = () => { + const el = document.getElementById('js-user-achievements'); + + if (!el) return false; + + const { rootUrl, userId } = el.dataset; + + const apolloProvider = new VueApollo({ + defaultClient: createDefaultClient(), + }); + + return new Vue({ + el, + apolloProvider, + name: 'UserAchievements', + provide: { rootUrl, userId: parseInt(userId, 10) }, + render(createElement) { + return createElement(UserAchievements); + }, + }); +}; |