refactor(editor): Convert DeleteUserModal to composition api (no-changelog) (#10531)

This commit is contained in:
Tomi Turtiainen 2024-08-23 16:23:31 +03:00 committed by GitHub
parent 29dd153df1
commit 7bcb0be27a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,3 +1,118 @@
<script lang="ts" setup>
import { ref, computed, onBeforeMount } from 'vue';
import { useToast } from '@/composables/useToast';
import Modal from '@/components/Modal.vue';
import ProjectSharing from '@/components/Projects/ProjectSharing.vue';
import { useUsersStore } from '@/stores/users.store';
import { useProjectsStore } from '@/stores/projects.store';
import { createEventBus } from 'n8n-design-system/utils';
import type { ProjectSharingData } from '@/types/projects.types';
import { useI18n } from '@/composables/useI18n';
const props = defineProps<{
modalName: string;
activeId: string;
}>();
const modalBus = createEventBus();
const loading = ref(false);
const operation = ref('');
const deleteConfirmText = ref('');
const selectedProject = ref<ProjectSharingData | null>(null);
const i18n = useI18n();
const usersStore = useUsersStore();
const projectsStore = useProjectsStore();
const userToDelete = computed(() => {
if (!props.activeId) return null;
return usersStore.usersById[props.activeId];
});
const isPending = computed(() => {
return userToDelete.value ? !userToDelete.value.firstName : false;
});
const title = computed(() => {
const user = userToDelete.value?.fullName ?? userToDelete.value?.email ?? '';
return i18n.baseText('settings.users.deleteUser', { interpolate: { user } });
});
const enabled = computed(() => {
if (isPending.value) {
return true;
}
if (
operation.value === 'delete' &&
deleteConfirmText.value === i18n.baseText('settings.users.deleteConfirmationText')
) {
return true;
}
if (operation.value === 'transfer' && selectedProject.value) {
return true;
}
return false;
});
const projects = computed(() => {
return projectsStore.projects.filter(
(project) =>
project.name !==
`${userToDelete.value?.firstName} ${userToDelete.value?.lastName} <${userToDelete.value?.email}>`,
);
});
onBeforeMount(async () => {
await projectsStore.getAllProjects();
});
const { showMessage, showError } = useToast();
async function onSubmit() {
if (!enabled.value) {
return;
}
try {
loading.value = true;
const params = { id: props.activeId } as { id: string; transferId?: string };
if (operation.value === 'transfer' && selectedProject.value) {
params.transferId = selectedProject.value.id;
}
await usersStore.deleteUser(params);
let message = '';
if (params.transferId) {
const transferProject = projects.value.find((project) => project.id === params.transferId);
if (transferProject) {
message = i18n.baseText('settings.users.transferredToUser', {
interpolate: { projectName: transferProject.name ?? '' },
});
}
}
showMessage({
type: 'success',
title: i18n.baseText('settings.users.userDeleted'),
message,
});
modalBus.emit('close');
} catch (error) {
showError(error, i18n.baseText('settings.users.userDeletedError'));
} finally {
loading.value = false;
}
}
</script>
<template>
<Modal
:name="modalName"
@ -11,13 +126,13 @@
<div>
<div v-if="isPending">
<n8n-text color="text-base">{{
$locale.baseText('settings.users.confirmUserDeletion')
i18n.baseText('settings.users.confirmUserDeletion')
}}</n8n-text>
</div>
<div v-else :class="$style.content">
<div>
<n8n-text color="text-base">{{
$locale.baseText('settings.users.confirmDataHandlingAfterDeletion')
i18n.baseText('settings.users.confirmDataHandlingAfterDeletion')
}}</n8n-text>
</div>
<el-radio
@ -26,25 +141,25 @@
@update:model-value="operation = 'transfer'"
>
<n8n-text color="text-dark">{{
$locale.baseText('settings.users.transferWorkflowsAndCredentials')
i18n.baseText('settings.users.transferWorkflowsAndCredentials')
}}</n8n-text>
</el-radio>
<div v-if="operation === 'transfer'" :class="$style.optionInput">
<n8n-text color="text-dark">{{
$locale.baseText('settings.users.transferWorkflowsAndCredentials.user')
i18n.baseText('settings.users.transferWorkflowsAndCredentials.user')
}}</n8n-text>
<ProjectSharing
v-model="selectedProject"
class="pt-2xs"
:projects="projects"
:placeholder="
$locale.baseText('settings.users.transferWorkflowsAndCredentials.placeholder')
i18n.baseText('settings.users.transferWorkflowsAndCredentials.placeholder')
"
/>
</div>
<el-radio v-model="operation" label="delete" @update:model-value="operation = 'delete'">
<n8n-text color="text-dark">{{
$locale.baseText('settings.users.deleteWorkflowsAndCredentials')
i18n.baseText('settings.users.deleteWorkflowsAndCredentials')
}}</n8n-text>
</el-radio>
<div
@ -52,10 +167,10 @@
:class="$style.optionInput"
data-test-id="delete-data-input"
>
<n8n-input-label :label="$locale.baseText('settings.users.deleteConfirmationMessage')">
<n8n-input-label :label="i18n.baseText('settings.users.deleteConfirmationMessage')">
<n8n-input
v-model="deleteConfirmText"
:placeholder="$locale.baseText('settings.users.deleteConfirmationText')"
:placeholder="i18n.baseText('settings.users.deleteConfirmationText')"
/>
</n8n-input-label>
</div>
@ -66,7 +181,7 @@
<n8n-button
:loading="loading"
:disabled="!enabled"
:label="$locale.baseText('settings.users.delete')"
:label="i18n.baseText('settings.users.delete')"
float="right"
data-test-id="confirm-delete-user-button"
@click="onSubmit"
@ -75,130 +190,6 @@
</Modal>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useToast } from '@/composables/useToast';
import Modal from '@/components/Modal.vue';
import type { IUser } from '@/Interface';
import { mapStores } from 'pinia';
import { useUsersStore } from '@/stores/users.store';
import { createEventBus } from 'n8n-design-system/utils';
import { useProjectsStore } from '@/stores/projects.store';
import type { ProjectListItem, ProjectSharingData } from '@/types/projects.types';
import ProjectSharing from '@/components/Projects/ProjectSharing.vue';
export default defineComponent({
name: 'DeleteUserModal',
components: {
Modal,
ProjectSharing,
},
props: {
modalName: {
type: String,
},
activeId: {
type: String,
},
},
setup() {
return {
...useToast(),
};
},
data() {
return {
modalBus: createEventBus(),
loading: false,
operation: '',
deleteConfirmText: '',
selectedProject: null as ProjectSharingData | null,
};
},
computed: {
...mapStores(useUsersStore, useProjectsStore),
userToDelete(): IUser | null {
if (!this.activeId) return null;
return this.usersStore.usersById[this.activeId];
},
isPending(): boolean {
return this.userToDelete ? this.userToDelete && !this.userToDelete.firstName : false;
},
title(): string {
const user =
(this.userToDelete && (this.userToDelete.fullName || this.userToDelete.email)) || '';
return this.$locale.baseText('settings.users.deleteUser', { interpolate: { user } });
},
enabled(): boolean {
if (this.isPending) {
return true;
}
if (
this.operation === 'delete' &&
this.deleteConfirmText === this.$locale.baseText('settings.users.deleteConfirmationText')
) {
return true;
}
if (this.operation === 'transfer' && this.selectedProject) {
return true;
}
return false;
},
projects(): ProjectListItem[] {
return this.projectsStore.projects.filter(
(project) =>
project.name !==
`${this.userToDelete?.firstName} ${this.userToDelete?.lastName} <${this.userToDelete?.email}>`,
);
},
},
async beforeMount() {
await this.projectsStore.getAllProjects();
},
methods: {
async onSubmit() {
try {
if (!this.enabled) {
return;
}
this.loading = true;
const params = { id: this.activeId } as { id: string; transferId?: string };
if (this.operation === 'transfer' && this.selectedProject) {
params.transferId = this.selectedProject.id;
}
await this.usersStore.deleteUser(params);
let message = '';
if (params.transferId) {
const transferProject = this.projects.find((project) => project.id === params.transferId);
if (transferProject) {
message = this.$locale.baseText('settings.users.transferredToUser', {
interpolate: { projectName: transferProject.name ?? '' },
});
}
}
this.showMessage({
type: 'success',
title: this.$locale.baseText('settings.users.userDeleted'),
message,
});
this.modalBus.emit('close');
} catch (error) {
this.showError(error, this.$locale.baseText('settings.users.userDeletedError'));
}
this.loading = false;
},
},
});
</script>
<style lang="scss" module>
.content {
padding-bottom: var(--spacing-2xs);