Skip to content

Commit

Permalink
refactor(editor): Migrate small components to composition API (#11509)
Browse files Browse the repository at this point in the history
  • Loading branch information
RicardoE105 authored Nov 4, 2024
1 parent 5e2e205 commit 2367706
Show file tree
Hide file tree
Showing 12 changed files with 377 additions and 475 deletions.
137 changes: 63 additions & 74 deletions packages/editor-ui/src/components/ContactPromptModal.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<script lang="ts">
import type { PropType } from 'vue';
import { defineComponent } from 'vue';
import { mapStores } from 'pinia';
<script setup lang="ts">
import { computed, ref } from 'vue';
import type { IN8nPromptResponse, ModalKey } from '@/Interface';
import { VALID_EMAIL_REGEX } from '@/constants';
import Modal from '@/components/Modal.vue';
Expand All @@ -10,78 +8,69 @@ import { useRootStore } from '@/stores/root.store';
import { createEventBus } from 'n8n-design-system/utils';
import { useToast } from '@/composables/useToast';
import { useNpsSurveyStore } from '@/stores/npsSurvey.store';
import { useTelemetry } from '@/composables/useTelemetry';
export default defineComponent({
name: 'ContactPromptModal',
components: { Modal },
props: {
modalName: {
type: String as PropType<ModalKey>,
required: true,
},
},
setup() {
return {
...useToast(),
};
},
data() {
return {
email: '',
modalBus: createEventBus(),
};
},
computed: {
...mapStores(useRootStore, useSettingsStore, useNpsSurveyStore),
title(): string {
if (this.npsSurveyStore.promptsData?.title) {
return this.npsSurveyStore.promptsData.title;
}
return 'You’re a power user 💪';
},
description(): string {
if (this.npsSurveyStore.promptsData?.message) {
return this.npsSurveyStore.promptsData.message;
}
return 'Your experience with n8n can help us improve — for you and our entire community.';
},
isEmailValid(): boolean {
return VALID_EMAIL_REGEX.test(String(this.email).toLowerCase());
},
},
methods: {
closeDialog(): void {
if (!this.isEmailValid) {
this.$telemetry.track('User closed email modal', {
instance_id: this.rootStore.instanceId,
email: null,
});
}
},
async send() {
if (this.isEmailValid) {
const response = (await this.settingsStore.submitContactInfo(
this.email,
)) as IN8nPromptResponse;
if (response.updated) {
this.$telemetry.track('User closed email modal', {
instance_id: this.rootStore.instanceId,
email: this.email,
});
this.showMessage({
title: 'Thanks!',
message: "It's people like you that help make n8n better",
type: 'success',
});
}
this.modalBus.emit('close');
}
},
},
defineProps<{
modalName: ModalKey;
}>();
const email = ref('');
const modalBus = createEventBus();
const npsSurveyStore = useNpsSurveyStore();
const rootStore = useRootStore();
const settingsStore = useSettingsStore();
const toast = useToast();
const telemetry = useTelemetry();
const title = computed(() => {
if (npsSurveyStore.promptsData?.title) {
return npsSurveyStore.promptsData.title;
}
return 'You’re a power user 💪';
});
const description = computed(() => {
if (npsSurveyStore.promptsData?.message) {
return npsSurveyStore.promptsData.message;
}
return 'Your experience with n8n can help us improve — for you and our entire community.';
});
const isEmailValid = computed(() => {
return VALID_EMAIL_REGEX.test(String(email.value).toLowerCase());
});
const closeDialog = () => {
if (!isEmailValid.value) {
telemetry.track('User closed email modal', {
instance_id: rootStore.instanceId,
email: null,
});
}
};
const send = async () => {
if (isEmailValid.value) {
const response = (await settingsStore.submitContactInfo(email.value)) as IN8nPromptResponse;
if (response.updated) {
telemetry.track('User closed email modal', {
instance_id: rootStore.instanceId,
email: email.value,
});
toast.showMessage({
title: 'Thanks!',
message: "It's people like you that help make n8n better",
type: 'success',
});
}
modalBus.emit('close');
}
};
</script>

<template>
Expand Down
54 changes: 28 additions & 26 deletions packages/editor-ui/src/components/IntersectionObserved.vue
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
<script lang="ts">
import type { PropType } from 'vue';
import { defineComponent } from 'vue';
<script setup lang="ts">
import { nextTick } from 'vue';
import { onBeforeUnmount, onMounted, ref } from 'vue';
import type { EventBus } from 'n8n-design-system/utils';
import { createEventBus } from 'n8n-design-system/utils';
export default defineComponent({
name: 'IntersectionObserved',
props: {
enabled: {
type: Boolean,
default: false,
},
eventBus: {
type: Object as PropType<EventBus>,
default: () => createEventBus(),
},
const props = withDefaults(
defineProps<{
enabled: boolean;
eventBus: EventBus;
}>(),
{
enabled: false,
default: () => createEventBus(),
},
async mounted() {
if (!this.enabled) {
return;
}
);
await this.$nextTick();
this.eventBus.emit('observe', this.$refs.observed);
},
beforeUnmount() {
if (this.enabled) {
this.eventBus.emit('unobserve', this.$refs.observed);
}
},
const observed = ref<IntersectionObserver | null>(null);
onMounted(async () => {
if (!props.enabled) {
return;
}
await nextTick();
props.eventBus.emit('observe', observed.value);
});
onBeforeUnmount(() => {
if (props.enabled) {
props.eventBus.emit('unobserve', observed.value);
}
});
</script>

Expand Down
104 changes: 51 additions & 53 deletions packages/editor-ui/src/components/IntersectionObserver.vue
Original file line number Diff line number Diff line change
@@ -1,67 +1,65 @@
<script lang="ts">
import type { PropType } from 'vue';
import { defineComponent } from 'vue';
<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue';
import type { EventBus } from 'n8n-design-system/utils';
import { createEventBus } from 'n8n-design-system/utils';
export default defineComponent({
name: 'IntersectionObserver',
props: {
threshold: {
type: Number,
default: 0,
},
enabled: {
type: Boolean,
default: false,
},
eventBus: {
type: Object as PropType<EventBus>,
default: () => createEventBus(),
},
const props = withDefaults(
defineProps<{
threshold: number;
enabled: boolean;
eventBus: EventBus;
}>(),
{
threshold: 0,
enabled: false,
default: () => createEventBus(),
},
data() {
return {
observer: null as IntersectionObserver | null,
};
},
mounted() {
if (!this.enabled) {
return;
}
);
const options = {
root: this.$refs.root as Element,
rootMargin: '0px',
threshold: this.threshold,
};
const emit = defineEmits<{
observed: [{ el: HTMLElement; isIntersecting: boolean }];
}>();
const observer = new IntersectionObserver((entries) => {
entries.forEach(({ target, isIntersecting }) => {
this.$emit('observed', {
el: target,
isIntersecting,
});
});
}, options);
const observer = ref<IntersectionObserver | null>(null);
const root = ref<HTMLElement | null>(null);
this.observer = observer;
onBeforeUnmount(() => {
if (props.enabled && observer.value) {
observer.value.disconnect();
}
});
this.eventBus.on('observe', (observed: Element) => {
if (observed) {
observer.observe(observed);
}
});
onMounted(() => {
if (!props.enabled) {
return;
}
const options = {
root: root.value,
rootMargin: '0px',
threshold: props.threshold,
};
this.eventBus.on('unobserve', (observed: Element) => {
observer.unobserve(observed);
const intersectionObserver = new IntersectionObserver((entries) => {
entries.forEach(({ target, isIntersecting }) => {
emit('observed', {
el: target as HTMLElement,
isIntersecting,
});
});
},
beforeUnmount() {
if (this.enabled && this.observer) {
this.observer.disconnect();
}, options);
observer.value = intersectionObserver;
props.eventBus.on('observe', (observed: Element) => {
if (observed) {
intersectionObserver.observe(observed);
}
},
});
props.eventBus.on('unobserve', (observed: Element) => {
intersectionObserver.unobserve(observed);
});
});
</script>

Expand Down
22 changes: 8 additions & 14 deletions packages/editor-ui/src/components/Logo.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { mapStores } from 'pinia';
<script setup lang="ts">
import { computed } from 'vue';
import { useRootStore } from '@/stores/root.store';
import { useUIStore } from '@/stores/ui.store';
export default defineComponent({
computed: {
...mapStores(useRootStore, useUIStore),
basePath(): string {
return this.rootStore.baseUrl;
},
logoPath(): string {
return this.basePath + this.uiStore.logo;
},
},
});
const rootStore = useRootStore();
const uiStore = useUIStore();
const basePath = computed(() => rootStore.baseUrl);
const logoPath = computed(() => basePath.value + uiStore.logo);
</script>

<template>
Expand Down
Loading

0 comments on commit 2367706

Please sign in to comment.