Browse Source

feat: cloud changelogs

pull/9629/head
DarkPhoenix2704 2 months ago
parent
commit
d45dae6214
  1. 23
      packages/nc-gui/components/feed/Changelog/index.vue
  2. 6
      packages/nc-gui/components/feed/Error.vue
  3. 14
      packages/nc-gui/components/feed/View.vue
  4. 15
      packages/nc-gui/composables/useProductFeed.ts
  5. 2
      packages/nc-gui/lib/types.ts
  6. 3
      packages/nocodb/src/schema/swagger.json

23
packages/nc-gui/components/feed/Changelog/index.vue

@ -1,5 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
const { loadFeed, githubFeed, isErrorOccurred } = useProductFeed() const props = defineProps<{
type: 'github' | 'cloud'
}>()
const { loadFeed, githubFeed, isErrorOccurred, cloudFeed } = useProductFeed()
const scrollContainer = ref<HTMLElement>() const scrollContainer = ref<HTMLElement>()
@ -8,12 +12,16 @@ const { isLoading } = useInfiniteScroll(
async () => { async () => {
if (isLoading.value) return if (isLoading.value) return
await loadFeed({ await loadFeed({
type: 'github', type: props.type,
loadMore: true, loadMore: true,
}) })
}, },
{ distance: 4 }, { distance: 4 },
) )
const feed = computed(() => {
return props.type === 'github' ? githubFeed.value : cloudFeed.value
})
</script> </script>
<template> <template>
@ -24,15 +32,18 @@ const { isLoading } = useInfiniteScroll(
}" }"
class="overflow-y-auto nc-scrollbar-md mx-auto w-full" class="overflow-y-auto nc-scrollbar-md mx-auto w-full"
> >
<div v-if="isErrorOccurred?.github && !githubFeed.length" class="h-full flex justify-center items-center"> <div
<FeedError page="github" /> v-if="(props.type === 'github' ? isErrorOccurred.github : isErrorOccurred.cloud) && !feed.length"
class="h-full flex justify-center items-center"
>
<FeedError :page="type" />
</div> </div>
<div v-else-if="isLoading && !githubFeed.length" class="flex items-center justify-center h-full w-full"> <div v-else-if="isLoading && !feed.length" class="flex items-center justify-center h-full w-full">
<GeneralLoader size="xlarge" /> <GeneralLoader size="xlarge" />
</div> </div>
<div v-else class="mx-auto max-w-[540px] xl:max-w-[638px] justify-around justify-items-center"> <div v-else class="mx-auto max-w-[540px] xl:max-w-[638px] justify-around justify-items-center">
<FeedChangelogItem v-for="(feed, index) in githubFeed" :key="feed.Id" :item="feed" :index="index" /> <FeedChangelogItem v-for="(item, index) in feed" :key="item.Id" :item="item" :index="index" />
</div> </div>
</div> </div>
</template> </template>

6
packages/nc-gui/components/feed/Error.vue

@ -1,11 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
const props = defineProps<{ const props = defineProps<{
page: 'all' | 'youtube' | 'github' | 'twitter' page: 'all' | 'youtube' | 'github' | 'twitter' | 'cloud'
}>() }>()
const emits = defineEmits(['reload']) const emits = defineEmits(['reload'])
const { loadFeed, socialFeed, youtubeFeed, githubFeed } = useProductFeed() const { loadFeed, socialFeed, youtubeFeed, githubFeed, cloudFeed } = useProductFeed()
const triggerReload = async () => { const triggerReload = async () => {
if (props.page === 'twitter') { if (props.page === 'twitter') {
@ -24,6 +24,8 @@ const triggerReload = async () => {
youtubeFeed.value = data youtubeFeed.value = data
} else if (props.page === 'github') { } else if (props.page === 'github') {
githubFeed.value = data githubFeed.value = data
} else if (props.page === 'cloud') {
cloudFeed.value = data
} }
} }
</script> </script>

14
packages/nc-gui/components/feed/View.vue

@ -21,7 +21,13 @@ const tabs: Array<{
container: FeedRecents, container: FeedRecents,
}, },
{ {
key: 'changelog', key: 'cloud',
icon: 'ncCloud',
title: 'Cloud Changelog',
container: FeedChangelog,
},
{
key: 'github',
icon: 'ncList', icon: 'ncList',
title: 'Changelog', title: 'Changelog',
container: FeedChangelog, container: FeedChangelog,
@ -89,13 +95,13 @@ onMounted(() => {
<div class="relative"> <div class="relative">
<FeedSocial <FeedSocial
:class="{ :class="{
'normal-left': tab.key === 'recents' || tab.key === 'youtube', 'normal-left': ['recents', 'youtube', 'cloud'].includes(tab.key),
'changelog-left': tab.key === 'changelog', 'changelog-left': tab.key === 'github',
'changelog-twitter': tab.key === 'twitter', 'changelog-twitter': tab.key === 'twitter',
}" }"
class="absolute social-card" class="absolute social-card"
/> />
<component :is="tab.container" /> <component :is="tab.container" :type="tab.key" />
</div> </div>
</a-tab-pane> </a-tab-pane>
</NcTabs> </NcTabs>

15
packages/nc-gui/composables/useProductFeed.ts

@ -14,13 +14,16 @@ export const useProductFeed = createSharedComposable(() => {
const socialFeed = ref<ProductFeedItem[]>([]) const socialFeed = ref<ProductFeedItem[]>([])
const cloudFeed = ref<ProductFeedItem[]>([])
const isErrorOccurred = reactive({ const isErrorOccurred = reactive({
youtube: false, youtube: false,
github: false, github: false,
social: false, social: false,
cloud: false,
}) })
const loadFeed = async ({ loadMore, type }: { loadMore: boolean; type: 'youtube' | 'github' | 'all' }) => { const loadFeed = async ({ loadMore, type }: { loadMore: boolean; type: 'youtube' | 'github' | 'all' | 'cloud' }) => {
try { try {
let page = 1 let page = 1
@ -35,6 +38,9 @@ export const useProductFeed = createSharedComposable(() => {
case 'all': case 'all':
page = Math.ceil(socialFeed.value.length / 10) + 1 page = Math.ceil(socialFeed.value.length / 10) + 1
break break
case 'cloud':
page = Math.ceil(cloudFeed.value.length / 10) + 1
break
} }
} }
@ -50,6 +56,9 @@ export const useProductFeed = createSharedComposable(() => {
case 'all': case 'all':
socialFeed.value = [...socialFeed.value, ...response] as ProductFeedItem[] socialFeed.value = [...socialFeed.value, ...response] as ProductFeedItem[]
break break
case 'cloud':
cloudFeed.value = [...cloudFeed.value, ...response] as ProductFeedItem[]
break
} }
} catch (error) { } catch (error) {
switch (type) { switch (type) {
@ -62,6 +71,9 @@ export const useProductFeed = createSharedComposable(() => {
case 'all': case 'all':
isErrorOccurred.social = true isErrorOccurred.social = true
break break
case 'cloud':
isErrorOccurred.cloud = true
break
} }
console.error(error) console.error(error)
return [] return []
@ -113,6 +125,7 @@ export const useProductFeed = createSharedComposable(() => {
youtubeFeed, youtubeFeed,
githubFeed, githubFeed,
socialFeed, socialFeed,
cloudFeed,
loadFeed, loadFeed,
isNewFeedAvailable, isNewFeedAvailable,
} }

2
packages/nc-gui/lib/types.ts

@ -281,7 +281,7 @@ interface ProductFeedItem {
Id: string Id: string
Title: string Title: string
Description: string Description: string
['Feed Source']: 'Youtube' | 'Github' | 'All' ['Feed Source']: 'Youtube' | 'Github' | 'All' | 'Cloud'
Url: string Url: string
Tags?: string Tags?: string
['Published Time']: string ['Published Time']: string

3
packages/nocodb/src/schema/swagger.json

@ -16046,7 +16046,8 @@
"enum": [ "enum": [
"all", "all",
"github", "github",
"youtube" "youtube",
"cloud"
] ]
}, },
"name": "type", "name": "type",

Loading…
Cancel
Save