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>2021-10-04 12:11:20 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-10-04 12:11:20 +0300
commit266aad4e70f3c642583ab60894b27b2622095cd8 (patch)
treeca0959c1c5bf9a11d0ce2ae6f736504b4a48ebbb /app/assets/javascripts/vue_shared/components/user_deletion_obstacles
parent87e82d6f2cc282a2c70535b4a7fb44b5a6dc8bf0 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/user_deletion_obstacles')
-rw-r--r--app/assets/javascripts/vue_shared/components/user_deletion_obstacles/constants.js5
-rw-r--r--app/assets/javascripts/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.stories.js37
-rw-r--r--app/assets/javascripts/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.vue91
-rw-r--r--app/assets/javascripts/vue_shared/components/user_deletion_obstacles/utils.js19
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]);
+ });
+};