mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-23 16:24:06 +00:00
feat: add job history and assets sidebar badge behavior (#9050)
## Summary Add sidebar badge behavior for queue/asset visibility updates: - Job History tab icon shows active jobs count (`queued + running`) only when the Job History panel is closed. - Assets tab icon no longer mirrors active jobs; when QPO V2 is enabled it now shows the number of assets added since the last time Assets was opened. - Opening Assets clears the unseen added-assets badge count. ## Changes - Added `iconBadge` logic to Job History sidebar tab. - Replaced Assets sidebar badge source with new unseen-assets counter logic. - Added `assetsSidebarBadgeStore` to track unseen asset additions from history updates and reset on Assets open. - Added/updated unit tests for both sidebar tab composables and the new store behavior. https://github.com/user-attachments/assets/33588a2a-c607-4fcc-8221-e7f11c3d79cc ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9050-fix-add-job-history-and-assets-sidebar-badge-behavior-30e6d73d365081c38297fe6aac9cd34c) by [Unito](https://www.unito.io) --------- Co-authored-by: Johnpaul Chiwetelu <49923152+Myestery@users.noreply.github.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
@@ -2,9 +2,9 @@ import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { useAssetsSidebarTab } from '@/composables/sidebarTabs/useAssetsSidebarTab'
|
||||
|
||||
const { mockGetSetting, mockActiveJobsCount } = vi.hoisted(() => ({
|
||||
const { mockGetSetting, mockUnseenAddedAssetsCount } = vi.hoisted(() => ({
|
||||
mockGetSetting: vi.fn(),
|
||||
mockActiveJobsCount: { value: 0 }
|
||||
mockUnseenAddedAssetsCount: { value: 0 }
|
||||
}))
|
||||
|
||||
vi.mock('@/platform/settings/settingStore', () => ({
|
||||
@@ -17,16 +17,16 @@ vi.mock('@/components/sidebar/tabs/AssetsSidebarTab.vue', () => ({
|
||||
default: {}
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/queueStore', () => ({
|
||||
useQueueStore: () => ({
|
||||
activeJobsCount: mockActiveJobsCount.value
|
||||
vi.mock('@/stores/workspace/assetsSidebarBadgeStore', () => ({
|
||||
useAssetsSidebarBadgeStore: () => ({
|
||||
unseenAddedAssetsCount: mockUnseenAddedAssetsCount.value
|
||||
})
|
||||
}))
|
||||
|
||||
describe('useAssetsSidebarTab', () => {
|
||||
it('hides icon badge when QPO V2 is disabled', () => {
|
||||
mockGetSetting.mockReturnValue(false)
|
||||
mockActiveJobsCount.value = 3
|
||||
mockUnseenAddedAssetsCount.value = 3
|
||||
|
||||
const sidebarTab = useAssetsSidebarTab()
|
||||
|
||||
@@ -34,9 +34,9 @@ describe('useAssetsSidebarTab', () => {
|
||||
expect((sidebarTab.iconBadge as () => string | null)()).toBeNull()
|
||||
})
|
||||
|
||||
it('shows active job count when QPO V2 is enabled', () => {
|
||||
it('shows unseen added assets count when QPO V2 is enabled', () => {
|
||||
mockGetSetting.mockReturnValue(true)
|
||||
mockActiveJobsCount.value = 3
|
||||
mockUnseenAddedAssetsCount.value = 3
|
||||
|
||||
const sidebarTab = useAssetsSidebarTab()
|
||||
|
||||
@@ -44,9 +44,9 @@ describe('useAssetsSidebarTab', () => {
|
||||
expect((sidebarTab.iconBadge as () => string | null)()).toBe('3')
|
||||
})
|
||||
|
||||
it('hides badge when no active jobs', () => {
|
||||
it('hides badge when there are no unseen added assets', () => {
|
||||
mockGetSetting.mockReturnValue(true)
|
||||
mockActiveJobsCount.value = 0
|
||||
mockUnseenAddedAssetsCount.value = 0
|
||||
|
||||
const sidebarTab = useAssetsSidebarTab()
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { markRaw } from 'vue'
|
||||
|
||||
import AssetsSidebarTab from '@/components/sidebar/tabs/AssetsSidebarTab.vue'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useQueueStore } from '@/stores/queueStore'
|
||||
import { useAssetsSidebarBadgeStore } from '@/stores/workspace/assetsSidebarBadgeStore'
|
||||
import type { SidebarTabExtension } from '@/types/extensionTypes'
|
||||
|
||||
export const useAssetsSidebarTab = (): SidebarTabExtension => {
|
||||
@@ -21,8 +21,8 @@ export const useAssetsSidebarTab = (): SidebarTabExtension => {
|
||||
return null
|
||||
}
|
||||
|
||||
const queueStore = useQueueStore()
|
||||
const count = queueStore.activeJobsCount
|
||||
const assetsSidebarBadgeStore = useAssetsSidebarBadgeStore()
|
||||
const count = assetsSidebarBadgeStore.unseenAddedAssetsCount
|
||||
return count > 0 ? count.toString() : null
|
||||
}
|
||||
}
|
||||
|
||||
59
src/composables/sidebarTabs/useJobHistorySidebarTab.test.ts
Normal file
59
src/composables/sidebarTabs/useJobHistorySidebarTab.test.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { useJobHistorySidebarTab } from '@/composables/sidebarTabs/useJobHistorySidebarTab'
|
||||
|
||||
const { mockActiveJobsCount, mockActiveSidebarTabId } = vi.hoisted(() => ({
|
||||
mockActiveJobsCount: { value: 0 },
|
||||
mockActiveSidebarTabId: { value: null as string | null }
|
||||
}))
|
||||
|
||||
vi.mock('@/components/sidebar/tabs/JobHistorySidebarTab.vue', () => ({
|
||||
default: {}
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/queueStore', () => ({
|
||||
useQueueStore: () => ({
|
||||
activeJobsCount: mockActiveJobsCount.value
|
||||
})
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/workspace/sidebarTabStore', () => ({
|
||||
useSidebarTabStore: () => ({
|
||||
activeSidebarTabId: mockActiveSidebarTabId.value
|
||||
})
|
||||
}))
|
||||
|
||||
describe('useJobHistorySidebarTab', () => {
|
||||
beforeEach(() => {
|
||||
mockActiveSidebarTabId.value = null
|
||||
mockActiveJobsCount.value = 0
|
||||
})
|
||||
|
||||
it('shows active jobs count while the panel is closed', () => {
|
||||
mockActiveSidebarTabId.value = 'assets'
|
||||
mockActiveJobsCount.value = 3
|
||||
|
||||
const sidebarTab = useJobHistorySidebarTab()
|
||||
|
||||
expect(typeof sidebarTab.iconBadge).toBe('function')
|
||||
expect((sidebarTab.iconBadge as () => string | null)()).toBe('3')
|
||||
})
|
||||
|
||||
it('hides badge while the job history panel is open', () => {
|
||||
mockActiveSidebarTabId.value = 'job-history'
|
||||
mockActiveJobsCount.value = 3
|
||||
|
||||
const sidebarTab = useJobHistorySidebarTab()
|
||||
|
||||
expect((sidebarTab.iconBadge as () => string | null)()).toBeNull()
|
||||
})
|
||||
|
||||
it('hides badge when there are no active jobs', () => {
|
||||
mockActiveSidebarTabId.value = null
|
||||
mockActiveJobsCount.value = 0
|
||||
|
||||
const sidebarTab = useJobHistorySidebarTab()
|
||||
|
||||
expect((sidebarTab.iconBadge as () => string | null)()).toBeNull()
|
||||
})
|
||||
})
|
||||
@@ -1,6 +1,8 @@
|
||||
import { markRaw } from 'vue'
|
||||
|
||||
import JobHistorySidebarTab from '@/components/sidebar/tabs/JobHistorySidebarTab.vue'
|
||||
import { useQueueStore } from '@/stores/queueStore'
|
||||
import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore'
|
||||
import type { SidebarTabExtension } from '@/types/extensionTypes'
|
||||
|
||||
export const useJobHistorySidebarTab = (): SidebarTabExtension => {
|
||||
@@ -11,6 +13,16 @@ export const useJobHistorySidebarTab = (): SidebarTabExtension => {
|
||||
tooltip: 'queue.jobHistory',
|
||||
label: 'queue.jobHistory',
|
||||
component: markRaw(JobHistorySidebarTab),
|
||||
type: 'vue'
|
||||
type: 'vue',
|
||||
iconBadge: () => {
|
||||
const sidebarTabStore = useSidebarTabStore()
|
||||
if (sidebarTabStore.activeSidebarTabId === 'job-history') {
|
||||
return null
|
||||
}
|
||||
|
||||
const queueStore = useQueueStore()
|
||||
const count = queueStore.activeJobsCount
|
||||
return count > 0 ? count.toString() : null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,6 +535,7 @@ describe('useQueueStore', () => {
|
||||
|
||||
await store.update()
|
||||
const initialTask = store.historyTasks[0]
|
||||
const initialHistoryTasks = store.historyTasks
|
||||
|
||||
// Same job with same outputs_count
|
||||
mockGetHistory.mockResolvedValue([{ ...job }])
|
||||
@@ -543,6 +544,8 @@ describe('useQueueStore', () => {
|
||||
|
||||
// Should reuse the same instance
|
||||
expect(store.historyTasks[0]).toBe(initialTask)
|
||||
// Should preserve array identity when history is unchanged
|
||||
expect(store.historyTasks).toBe(initialHistoryTasks)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -479,6 +479,7 @@ export const useQueueStore = defineStore('queue', () => {
|
||||
const runningTasks = shallowRef<TaskItemImpl[]>([])
|
||||
const pendingTasks = shallowRef<TaskItemImpl[]>([])
|
||||
const historyTasks = shallowRef<TaskItemImpl[]>([])
|
||||
const hasFetchedHistorySnapshot = ref(false)
|
||||
const maxHistoryItems = ref(64)
|
||||
const isLoading = ref(false)
|
||||
|
||||
@@ -557,7 +558,7 @@ export const useQueueStore = defineStore('queue', () => {
|
||||
currentHistory.map((impl) => [impl.jobId, impl])
|
||||
)
|
||||
|
||||
historyTasks.value = sortedHistory.map((job) => {
|
||||
const nextHistoryTasks = sortedHistory.map((job) => {
|
||||
const existing = existingByJobId.get(job.id)
|
||||
if (!existing) return new TaskItemImpl(job)
|
||||
// Recreate if outputs_count changed to ensure lazy loading works
|
||||
@@ -566,6 +567,15 @@ export const useQueueStore = defineStore('queue', () => {
|
||||
}
|
||||
return existing
|
||||
})
|
||||
|
||||
const isHistoryUnchanged =
|
||||
nextHistoryTasks.length === currentHistory.length &&
|
||||
nextHistoryTasks.every((task, index) => task === currentHistory[index])
|
||||
|
||||
if (!isHistoryUnchanged) {
|
||||
historyTasks.value = nextHistoryTasks
|
||||
}
|
||||
hasFetchedHistorySnapshot.value = true
|
||||
} finally {
|
||||
// Only clear loading if this is the latest request.
|
||||
// A stale request completing (success or error) should not touch loading state
|
||||
@@ -595,6 +605,7 @@ export const useQueueStore = defineStore('queue', () => {
|
||||
runningTasks,
|
||||
pendingTasks,
|
||||
historyTasks,
|
||||
hasFetchedHistorySnapshot,
|
||||
maxHistoryItems,
|
||||
isLoading,
|
||||
|
||||
|
||||
187
src/stores/workspace/assetsSidebarBadgeStore.test.ts
Normal file
187
src/stores/workspace/assetsSidebarBadgeStore.test.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
import { createTestingPinia } from '@pinia/testing'
|
||||
import { setActivePinia } from 'pinia'
|
||||
import { nextTick } from 'vue'
|
||||
import { beforeEach, describe, expect, it } from 'vitest'
|
||||
|
||||
import type { JobListItem } from '@/platform/remote/comfyui/jobs/jobTypes'
|
||||
import { TaskItemImpl, useQueueStore } from '@/stores/queueStore'
|
||||
import { useAssetsSidebarBadgeStore } from '@/stores/workspace/assetsSidebarBadgeStore'
|
||||
import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore'
|
||||
|
||||
const createHistoryTask = ({
|
||||
id,
|
||||
outputsCount,
|
||||
hasPreview = true
|
||||
}: {
|
||||
id: string
|
||||
outputsCount?: number
|
||||
hasPreview?: boolean
|
||||
}) =>
|
||||
new TaskItemImpl({
|
||||
id,
|
||||
status: 'completed',
|
||||
create_time: Date.now(),
|
||||
priority: 1,
|
||||
outputs_count: outputsCount,
|
||||
preview_output: hasPreview
|
||||
? {
|
||||
filename: `${id}.png`,
|
||||
subfolder: '',
|
||||
type: 'output',
|
||||
nodeId: '1',
|
||||
mediaType: 'images'
|
||||
}
|
||||
: undefined
|
||||
} as JobListItem)
|
||||
|
||||
describe('useAssetsSidebarBadgeStore', () => {
|
||||
beforeEach(() => {
|
||||
setActivePinia(createTestingPinia({ stubActions: false }))
|
||||
})
|
||||
|
||||
it('does not count initial fetched history when store starts before hydration', async () => {
|
||||
const queueStore = useQueueStore()
|
||||
const assetsSidebarBadgeStore = useAssetsSidebarBadgeStore()
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-1', outputsCount: 2 })
|
||||
]
|
||||
await nextTick()
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(0)
|
||||
|
||||
queueStore.hasFetchedHistorySnapshot = true
|
||||
await nextTick()
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(0)
|
||||
})
|
||||
|
||||
it('counts new history items after baseline hydration while assets tab is closed', async () => {
|
||||
const queueStore = useQueueStore()
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-1', outputsCount: 2 })
|
||||
]
|
||||
queueStore.hasFetchedHistorySnapshot = true
|
||||
|
||||
const assetsSidebarBadgeStore = useAssetsSidebarBadgeStore()
|
||||
await nextTick()
|
||||
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(0)
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-2', hasPreview: true }),
|
||||
...queueStore.historyTasks
|
||||
]
|
||||
await nextTick()
|
||||
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(1)
|
||||
})
|
||||
|
||||
it('does not count preview fallback when server outputsCount is zero', async () => {
|
||||
const queueStore = useQueueStore()
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-1', outputsCount: 2 })
|
||||
]
|
||||
queueStore.hasFetchedHistorySnapshot = true
|
||||
|
||||
const assetsSidebarBadgeStore = useAssetsSidebarBadgeStore()
|
||||
await nextTick()
|
||||
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(0)
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-2', outputsCount: 0, hasPreview: true }),
|
||||
...queueStore.historyTasks
|
||||
]
|
||||
await nextTick()
|
||||
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(0)
|
||||
})
|
||||
|
||||
it('adds only delta when a seen job gains more outputs', async () => {
|
||||
const queueStore = useQueueStore()
|
||||
const assetsSidebarBadgeStore = useAssetsSidebarBadgeStore()
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-1', hasPreview: true })
|
||||
]
|
||||
queueStore.hasFetchedHistorySnapshot = true
|
||||
await nextTick()
|
||||
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(0)
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-1', outputsCount: 3 })
|
||||
]
|
||||
await nextTick()
|
||||
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(2)
|
||||
})
|
||||
|
||||
it('treats a reappearing job as unseen after it aged out of history', async () => {
|
||||
const queueStore = useQueueStore()
|
||||
const assetsSidebarBadgeStore = useAssetsSidebarBadgeStore()
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-1', outputsCount: 2 })
|
||||
]
|
||||
queueStore.hasFetchedHistorySnapshot = true
|
||||
await nextTick()
|
||||
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(0)
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-2', outputsCount: 1 })
|
||||
]
|
||||
await nextTick()
|
||||
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(1)
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-1', outputsCount: 1 }),
|
||||
createHistoryTask({ id: 'job-2', outputsCount: 1 })
|
||||
]
|
||||
await nextTick()
|
||||
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(2)
|
||||
})
|
||||
|
||||
it('clears and suppresses count while assets tab is open', async () => {
|
||||
const queueStore = useQueueStore()
|
||||
const sidebarTabStore = useSidebarTabStore()
|
||||
const assetsSidebarBadgeStore = useAssetsSidebarBadgeStore()
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-1', outputsCount: 2 })
|
||||
]
|
||||
queueStore.hasFetchedHistorySnapshot = true
|
||||
await nextTick()
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(0)
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-2', outputsCount: 4 }),
|
||||
...queueStore.historyTasks
|
||||
]
|
||||
await nextTick()
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(4)
|
||||
|
||||
sidebarTabStore.activeSidebarTabId = 'assets'
|
||||
await nextTick()
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(0)
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-3', outputsCount: 4 }),
|
||||
...queueStore.historyTasks
|
||||
]
|
||||
await nextTick()
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(0)
|
||||
|
||||
sidebarTabStore.activeSidebarTabId = 'node-library'
|
||||
await nextTick()
|
||||
|
||||
queueStore.historyTasks = [
|
||||
createHistoryTask({ id: 'job-4', outputsCount: 1 }),
|
||||
...queueStore.historyTasks
|
||||
]
|
||||
await nextTick()
|
||||
expect(assetsSidebarBadgeStore.unseenAddedAssetsCount).toBe(1)
|
||||
})
|
||||
})
|
||||
99
src/stores/workspace/assetsSidebarBadgeStore.ts
Normal file
99
src/stores/workspace/assetsSidebarBadgeStore.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
import type { TaskItemImpl } from '@/stores/queueStore'
|
||||
import { useQueueStore } from '@/stores/queueStore'
|
||||
import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore'
|
||||
|
||||
const getAddedAssetCount = (task: TaskItemImpl): number => {
|
||||
if (typeof task.outputsCount === 'number') {
|
||||
return Math.max(task.outputsCount, 0)
|
||||
}
|
||||
|
||||
return task.previewOutput ? 1 : 0
|
||||
}
|
||||
|
||||
export const useAssetsSidebarBadgeStore = defineStore(
|
||||
'assetsSidebarBadge',
|
||||
() => {
|
||||
const queueStore = useQueueStore()
|
||||
const sidebarTabStore = useSidebarTabStore()
|
||||
|
||||
const unseenAddedAssetsCount = ref(0)
|
||||
const countedHistoryAssetsByJobId = ref(new Map<string, number>())
|
||||
const hasInitializedHistory = ref(false)
|
||||
|
||||
const markCurrentHistoryAsSeen = () => {
|
||||
countedHistoryAssetsByJobId.value = new Map(
|
||||
queueStore.historyTasks.map((task) => [
|
||||
task.jobId,
|
||||
getAddedAssetCount(task)
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
watch(
|
||||
() =>
|
||||
[
|
||||
queueStore.historyTasks,
|
||||
queueStore.hasFetchedHistorySnapshot
|
||||
] as const,
|
||||
([historyTasks, hasFetchedHistorySnapshot]) => {
|
||||
if (!hasFetchedHistorySnapshot) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!hasInitializedHistory.value) {
|
||||
hasInitializedHistory.value = true
|
||||
markCurrentHistoryAsSeen()
|
||||
return
|
||||
}
|
||||
|
||||
const isAssetsTabOpen = sidebarTabStore.activeSidebarTabId === 'assets'
|
||||
const previousCountedAssetsByJobId = countedHistoryAssetsByJobId.value
|
||||
const nextCountedAssetsByJobId = new Map<string, number>()
|
||||
|
||||
for (const task of historyTasks) {
|
||||
const jobId = task.jobId
|
||||
if (!jobId) {
|
||||
continue
|
||||
}
|
||||
|
||||
const countedAssets = previousCountedAssetsByJobId.get(jobId) ?? 0
|
||||
const currentAssets = getAddedAssetCount(task)
|
||||
const hasSeenJob = previousCountedAssetsByJobId.has(jobId)
|
||||
|
||||
if (!isAssetsTabOpen && !hasSeenJob) {
|
||||
unseenAddedAssetsCount.value += currentAssets
|
||||
} else if (!isAssetsTabOpen && currentAssets > countedAssets) {
|
||||
unseenAddedAssetsCount.value += currentAssets - countedAssets
|
||||
}
|
||||
|
||||
nextCountedAssetsByJobId.set(
|
||||
jobId,
|
||||
Math.max(countedAssets, currentAssets)
|
||||
)
|
||||
}
|
||||
|
||||
countedHistoryAssetsByJobId.value = nextCountedAssetsByJobId
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
() => sidebarTabStore.activeSidebarTabId,
|
||||
(activeSidebarTabId) => {
|
||||
if (activeSidebarTabId !== 'assets') {
|
||||
return
|
||||
}
|
||||
|
||||
unseenAddedAssetsCount.value = 0
|
||||
markCurrentHistoryAsSeen()
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
unseenAddedAssetsCount
|
||||
}
|
||||
}
|
||||
)
|
||||
Reference in New Issue
Block a user