mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-08 06:53:26 +00:00
# Pull Request Template ## Description This PR introduces a new changelog component that can be used in the sidebar. Fixes https://linear.app/chatwoot/issue/CW-5776/changelog-card-ui-component ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? ### Screencast https://github.com/user-attachments/assets/42e77e82-388a-4fc9-9b37-f3d0ea1a9d7f ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Muhsin <muhsinkeramam@gmail.com>
111 lines
3.1 KiB
Vue
111 lines
3.1 KiB
Vue
<script setup>
|
|
import { ref, computed, onMounted } from 'vue';
|
|
import GroupedStackedChangelogCard from 'dashboard/components-next/changelog-card/GroupedStackedChangelogCard.vue';
|
|
import { useUISettings } from 'dashboard/composables/useUISettings';
|
|
import changelogAPI from 'dashboard/api/changelog';
|
|
|
|
const MAX_DISMISSED_SLUGS = 5;
|
|
|
|
const { uiSettings, updateUISettings } = useUISettings();
|
|
const posts = ref([]);
|
|
const currentIndex = ref(0);
|
|
const dismissingCards = ref([]);
|
|
const isLoading = ref(false);
|
|
|
|
// Get current dismissed slugs from ui_settings
|
|
const dismissedSlugs = computed(() => {
|
|
return uiSettings.value.changelog_dismissed_slugs || [];
|
|
});
|
|
|
|
// Get un dismissed posts - these are the changelog posts that should be shown
|
|
const unDismissedPosts = computed(() => {
|
|
return posts.value.filter(post => !dismissedSlugs.value.includes(post.slug));
|
|
});
|
|
|
|
// Fetch changelog posts from API
|
|
const fetchChangelog = async () => {
|
|
isLoading.value = true;
|
|
|
|
try {
|
|
const response = await changelogAPI.fetchFromHub();
|
|
posts.value = response.data.posts || [];
|
|
|
|
// Clean up dismissed slugs - remove any that are no longer in the current feed
|
|
const currentSlugs = posts.value.map(post => post.slug);
|
|
const cleanedDismissedSlugs = dismissedSlugs.value.filter(slug =>
|
|
currentSlugs.includes(slug)
|
|
);
|
|
|
|
// Update ui_settings if cleanup occurred
|
|
if (cleanedDismissedSlugs.length !== dismissedSlugs.value.length) {
|
|
updateUISettings({
|
|
changelog_dismissed_slugs: cleanedDismissedSlugs,
|
|
});
|
|
}
|
|
// eslint-disable-next-line no-empty
|
|
} catch (err) {
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
};
|
|
|
|
// Dismiss a changelog post
|
|
const dismissPost = slug => {
|
|
const currentDismissed = [...dismissedSlugs.value];
|
|
|
|
// Add new slug if not already present
|
|
if (!currentDismissed.includes(slug)) {
|
|
currentDismissed.push(slug);
|
|
|
|
// Keep only the most recent MAX_DISMISSED_SLUGS entries
|
|
if (currentDismissed.length > MAX_DISMISSED_SLUGS) {
|
|
currentDismissed.shift(); // Remove oldest entry
|
|
}
|
|
|
|
updateUISettings({
|
|
changelog_dismissed_slugs: currentDismissed,
|
|
});
|
|
}
|
|
};
|
|
|
|
const handleDismiss = slug => {
|
|
dismissingCards.value.push(slug);
|
|
setTimeout(() => {
|
|
dismissPost(slug);
|
|
dismissingCards.value = dismissingCards.value.filter(s => s !== slug);
|
|
if (currentIndex.value >= unDismissedPosts.value.length)
|
|
currentIndex.value = 0;
|
|
}, 200);
|
|
};
|
|
|
|
const handleReadMore = () => {
|
|
const currentPost = unDismissedPosts.value[currentIndex.value];
|
|
if (currentPost?.slug) {
|
|
window.open(`https://www.chatwoot.com/blog/${currentPost.slug}`, '_blank');
|
|
}
|
|
};
|
|
|
|
const handleImgClick = ({ index }) => {
|
|
currentIndex.value = index;
|
|
handleReadMore();
|
|
};
|
|
|
|
onMounted(() => {
|
|
fetchChangelog();
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<GroupedStackedChangelogCard
|
|
v-if="unDismissedPosts.length > 0"
|
|
:posts="unDismissedPosts"
|
|
:current-index="currentIndex"
|
|
:dismissing-slugs="dismissingCards"
|
|
class="min-h-[240px] z-10"
|
|
@read-more="handleReadMore"
|
|
@dismiss="handleDismiss"
|
|
@img-click="handleImgClick"
|
|
/>
|
|
<template v-else />
|
|
</template>
|