diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-04 12:11:20 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-04 12:11:20 +0300 |
commit | 266aad4e70f3c642583ab60894b27b2622095cd8 (patch) | |
tree | ca0959c1c5bf9a11d0ce2ae6f736504b4a48ebbb /app/assets/javascripts/vue_shared/components/user_deletion_obstacles | |
parent | 87e82d6f2cc282a2c70535b4a7fb44b5a6dc8bf0 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/user_deletion_obstacles')
4 files changed, 152 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/constants.js b/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/constants.js new file mode 100644 index 00000000000..256db2ea1ce --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/constants.js @@ -0,0 +1,5 @@ +// Types of obstacles to user deletion +export const OBSTACLE_TYPES = Object.freeze({ + oncallSchedules: 'ONCALL_SCHEDULE', + escalationPolicies: 'ESCALATION_POLICY', +}); diff --git a/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.stories.js b/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.stories.js new file mode 100644 index 00000000000..d2030c14029 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.stories.js @@ -0,0 +1,37 @@ +/* eslint-disable @gitlab/require-i18n-strings */ + +import { OBSTACLE_TYPES } from './constants'; +import UserDeletionObstaclesList from './user_deletion_obstacles_list.vue'; + +export default { + component: UserDeletionObstaclesList, + title: 'vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list', +}; + +const Template = (args, { argTypes }) => ({ + components: { UserDeletionObstaclesList }, + props: Object.keys(argTypes), + template: '<user-deletion-obstacles-list v-bind="$props" v-on="$props" />', +}); + +export const Default = Template.bind({}); +Default.args = { + obstacles: [ + { + type: OBSTACLE_TYPES.oncallSchedules, + name: 'APAC', + url: 'https://domain.com/group/main-application/oncall_schedules', + projectName: 'main-application', + projectUrl: 'https://domain.com/group/main-application', + }, + { + type: OBSTACLE_TYPES.escalationPolicies, + name: 'Engineering On-call', + url: 'https://domain.com/group/microservice-backend/escalation_policies', + projectName: 'Microservice Backend', + projectUrl: 'https://domain.com/group/microservice-backend', + }, + ], + userName: 'Thomspon Smith', + isCurrentUser: false, +}; diff --git a/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.vue b/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.vue new file mode 100644 index 00000000000..1eea660d527 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.vue @@ -0,0 +1,91 @@ +<script> +import { GlSprintf, GlLink } from '@gitlab/ui'; +import { sprintf, s__ } from '~/locale'; +import { OBSTACLE_TYPES } from './constants'; + +const OBSTACLE_TEXT = { + [OBSTACLE_TYPES.oncallSchedules]: s__( + 'OnCallSchedules|On-call schedule %{obstacle} in Project %{project}', + ), + [OBSTACLE_TYPES.escalationPolicies]: s__( + 'EscalationPolicies|Escalation policy %{obstacle} in Project %{project}', + ), +}; + +export default { + components: { + GlSprintf, + GlLink, + }, + props: { + obstacles: { + type: Array, + required: true, + }, + userName: { + type: String, + required: false, + default: null, + }, + isCurrentUser: { + type: Boolean, + required: false, + default: false, + }, + }, + computed: { + title() { + return this.isCurrentUser + ? s__('OnCallSchedules|You are currently a part of:') + : sprintf( + s__('OnCallSchedules|User %{name} is currently part of:'), + { + name: this.userName, + }, + false, + ); + }, + footer() { + return this.isCurrentUser + ? s__( + 'OnCallSchedules|Removing yourself may put your on-call team at risk of missing a notification.', + ) + : s__( + 'OnCallSchedules|Removing this user may put their on-call team at risk of missing a notification.', + ); + }, + }, + methods: { + textForObstacle(obstacle) { + return OBSTACLE_TEXT[obstacle.type]; + }, + urlForObstacle(obstacle) { + // Fallback to scheduleUrl for backwards compatibility + return obstacle.url || obstacle.scheduleUrl; + }, + }, +}; +</script> + +<template> + <div> + <p data-testid="title">{{ title }}</p> + + <ul data-testid="obstacles-list"> + <li v-for="(obstacle, index) in obstacles" :key="`${obstacle.name}-${index}`"> + <gl-sprintf :message="textForObstacle(obstacle)"> + <template #obstacle> + <gl-link :href="urlForObstacle(obstacle)" target="_blank">{{ obstacle.name }}</gl-link> + </template> + <template #project> + <gl-link :href="obstacle.projectUrl" target="_blank">{{ + obstacle.projectName + }}</gl-link> + </template> + </gl-sprintf> + </li> + </ul> + + <p data-testid="footer">{{ footer }}</p> + </div> +</template> diff --git a/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/utils.js b/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/utils.js new file mode 100644 index 00000000000..502302a1ef2 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/user_deletion_obstacles/utils.js @@ -0,0 +1,19 @@ +import { OBSTACLE_TYPES } from './constants'; + +const addTypeToObstacles = (obstacles, type) => { + if (!obstacles) return []; + + return obstacles?.map((obstacle) => ({ type, ...obstacle })); +}; + +// For use with user objects formatted via internal REST API. +// If the removal/deletion of a user could cause critical +// problems, return a single array containing all affected +// associations including their type. +export const parseUserDeletionObstacles = (user) => { + if (!user) return []; + + return Object.keys(OBSTACLE_TYPES).flatMap((type) => { + return addTypeToObstacles(user[type], OBSTACLE_TYPES[type]); + }); +}; |