mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
refactor(editor): Migrate TemplatesInfoCarousel.vue
to composition API (#10919)
This commit is contained in:
parent
39310c01fb
commit
6e0d9d2fd5
|
@ -1,114 +1,106 @@
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { nextTick, onBeforeMount, onMounted, ref, watch } from 'vue';
|
||||||
import type { PropType } from 'vue';
|
|
||||||
import type { ITemplatesCollection } from '@/Interface';
|
import type { ITemplatesCollection } from '@/Interface';
|
||||||
import Card from '@/components/CollectionWorkflowCard.vue';
|
import Card from '@/components/CollectionWorkflowCard.vue';
|
||||||
import TemplatesInfoCard from '@/components/TemplatesInfoCard.vue';
|
import TemplatesInfoCard from '@/components/TemplatesInfoCard.vue';
|
||||||
import { VueAgile } from 'vue-agile';
|
import type { VueAgile } from 'vue-agile';
|
||||||
|
|
||||||
type SliderRef = InstanceType<typeof VueAgile>;
|
type SliderRef = InstanceType<typeof VueAgile>;
|
||||||
|
|
||||||
export default defineComponent({
|
const props = withDefaults(
|
||||||
name: 'TemplatesInfoCarousel',
|
defineProps<{
|
||||||
components: {
|
collections: ITemplatesCollection[];
|
||||||
Card,
|
loading?: boolean;
|
||||||
TemplatesInfoCard,
|
showItemCount?: boolean;
|
||||||
agile: VueAgile,
|
showNavigation?: boolean;
|
||||||
|
cardsWidth?: string;
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
showItemCount: true,
|
||||||
|
showNavigation: true,
|
||||||
|
cardsWidth: '240px',
|
||||||
|
loading: false,
|
||||||
},
|
},
|
||||||
props: {
|
);
|
||||||
collections: {
|
|
||||||
type: Array as PropType<ITemplatesCollection[]>,
|
const emit = defineEmits<{
|
||||||
required: true,
|
openCollection: [payload: { event: MouseEvent; id: number }];
|
||||||
},
|
}>();
|
||||||
loading: {
|
|
||||||
type: Boolean,
|
const carouselScrollPosition = ref(0);
|
||||||
},
|
const cardWidth = ref(parseInt(props.cardsWidth, 10));
|
||||||
showItemCount: {
|
const scrollEnd = ref(false);
|
||||||
type: Boolean,
|
const listElement = ref<null | Element>(null);
|
||||||
default: true,
|
const sliderRef = ref<null | SliderRef>(null);
|
||||||
},
|
|
||||||
showNavigation: {
|
const updateCarouselScroll = () => {
|
||||||
type: Boolean,
|
if (listElement.value) {
|
||||||
default: true,
|
carouselScrollPosition.value = Number(listElement.value.scrollLeft.toFixed());
|
||||||
},
|
|
||||||
cardsWidth: {
|
const width = listElement.value.clientWidth;
|
||||||
type: String,
|
const scrollWidth = listElement.value.scrollWidth;
|
||||||
default: '240px',
|
const scrollLeft = carouselScrollPosition.value;
|
||||||
},
|
scrollEnd.value = scrollWidth - width <= scrollLeft + 7;
|
||||||
},
|
}
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
carouselScrollPosition: 0,
|
|
||||||
cardWidth: parseInt(this.cardsWidth, 10),
|
|
||||||
sliderWidth: 0,
|
|
||||||
scrollEnd: false,
|
|
||||||
listElement: null as null | Element,
|
|
||||||
};
|
};
|
||||||
},
|
|
||||||
watch: {
|
const onCardClick = (event: MouseEvent, id: number) => {
|
||||||
collections() {
|
emit('openCollection', { event, id });
|
||||||
|
};
|
||||||
|
|
||||||
|
const scrollLeft = () => {
|
||||||
|
if (listElement.value) {
|
||||||
|
listElement.value.scrollBy({ left: -(cardWidth.value * 2), top: 0, behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const scrollRight = () => {
|
||||||
|
if (listElement.value) {
|
||||||
|
listElement.value.scrollBy({ left: cardWidth.value * 2, top: 0, behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.collections,
|
||||||
|
() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.updateCarouselScroll();
|
updateCarouselScroll();
|
||||||
}, 0);
|
}, 0);
|
||||||
},
|
},
|
||||||
loading() {
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.loading,
|
||||||
|
() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.updateCarouselScroll();
|
updateCarouselScroll();
|
||||||
}, 0);
|
}, 0);
|
||||||
},
|
},
|
||||||
},
|
);
|
||||||
async mounted() {
|
|
||||||
await this.$nextTick();
|
onMounted(async () => {
|
||||||
const sliderRef = this.$refs.slider as SliderRef | undefined;
|
await nextTick();
|
||||||
if (!sliderRef) {
|
if (!sliderRef.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
listElement.value = sliderRef.value.$el.querySelector('.agile__list');
|
||||||
|
if (listElement.value) {
|
||||||
|
listElement.value.addEventListener('scroll', updateCarouselScroll);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.listElement = sliderRef.$el.querySelector('.agile__list');
|
onBeforeMount(() => {
|
||||||
if (this.listElement) {
|
if (sliderRef.value) {
|
||||||
this.listElement.addEventListener('scroll', this.updateCarouselScroll);
|
sliderRef.value.destroy();
|
||||||
}
|
}
|
||||||
},
|
window.addEventListener('scroll', updateCarouselScroll);
|
||||||
beforeUnmount() {
|
|
||||||
const sliderRef = this.$refs.slider as SliderRef | undefined;
|
|
||||||
if (sliderRef) {
|
|
||||||
sliderRef.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
window.removeEventListener('scroll', this.updateCarouselScroll);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
updateCarouselScroll() {
|
|
||||||
if (this.listElement) {
|
|
||||||
this.carouselScrollPosition = Number(this.listElement.scrollLeft.toFixed());
|
|
||||||
|
|
||||||
const width = this.listElement.clientWidth;
|
|
||||||
const scrollWidth = this.listElement.scrollWidth;
|
|
||||||
const scrollLeft = this.carouselScrollPosition;
|
|
||||||
this.scrollEnd = scrollWidth - width <= scrollLeft + 7;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCardClick(event: MouseEvent, id: number) {
|
|
||||||
this.$emit('openCollection', { event, id });
|
|
||||||
},
|
|
||||||
scrollLeft() {
|
|
||||||
if (this.listElement) {
|
|
||||||
this.listElement.scrollBy({ left: -(this.cardWidth * 2), top: 0, behavior: 'smooth' });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scrollRight() {
|
|
||||||
if (this.listElement) {
|
|
||||||
this.listElement.scrollBy({ left: this.cardWidth * 2, top: 0, behavior: 'smooth' });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-show="loading || collections.length" :class="$style.container">
|
<div v-show="loading || collections.length" :class="$style.container">
|
||||||
<agile
|
<agile
|
||||||
ref="slider"
|
ref="sliderRef"
|
||||||
:dots="false"
|
:dots="false"
|
||||||
:nav-buttons="false"
|
:nav-buttons="false"
|
||||||
:infinite="false"
|
:infinite="false"
|
||||||
|
|
|
@ -160,13 +160,13 @@ export default defineComponent({
|
||||||
this.areCategoriesPrepopulated = true;
|
this.areCategoriesPrepopulated = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onOpenCollection({ event, id }: { event: MouseEvent; id: string }) {
|
onOpenCollection({ event, id }: { event: MouseEvent; id: number }) {
|
||||||
this.navigateTo(event, VIEWS.COLLECTION, id);
|
this.navigateTo(event, VIEWS.COLLECTION, id);
|
||||||
},
|
},
|
||||||
onOpenTemplate({ event, id }: { event: MouseEvent; id: string }) {
|
onOpenTemplate({ event, id }: { event: MouseEvent; id: number }) {
|
||||||
this.navigateTo(event, VIEWS.TEMPLATE, id);
|
this.navigateTo(event, VIEWS.TEMPLATE, id);
|
||||||
},
|
},
|
||||||
navigateTo(e: MouseEvent, page: string, id: string) {
|
navigateTo(e: MouseEvent, page: string, id: number) {
|
||||||
if (e.metaKey || e.ctrlKey) {
|
if (e.metaKey || e.ctrlKey) {
|
||||||
const route = this.$router.resolve({ name: page, params: { id } });
|
const route = this.$router.resolve({ name: page, params: { id } });
|
||||||
window.open(route.href, '_blank');
|
window.open(route.href, '_blank');
|
||||||
|
|
Loading…
Reference in a new issue