Skip to content

Commit

Permalink
24451 - Add the 'Fetching Data' spinner for downloading business summ…
Browse files Browse the repository at this point in the history
…ary and loading document lists (#115)

* Add the 'Fetching Data' spinner for downloading business summary and loading document lists

* clean up

* PR updates
  • Loading branch information
patrickpeinanw authored Jan 6, 2025
1 parent 5924122 commit 444aa60
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 46 deletions.
3 changes: 0 additions & 3 deletions src/components/bcros/LoadingIcon.vue

This file was deleted.

26 changes: 26 additions & 0 deletions src/components/bcros/LoadingModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script lang="ts" setup>
const open = defineModel('open', { type: Boolean, required: true })
defineProps({ spinnerText: { type: String, required: false, default: undefined } })
</script>

<template>
<UModal
v-model="open"
prevent-close
transition
:ui="{
background: 'bg-transparent',
shadow: 'shadow-none',
overlay: {
background: 'bg-gray-800/75 dark:bg-gray-800/75',
}
}"
>
<div class="w-full h-full text-center items-center">
<UIcon class="text-6xl text-gray-700 animate-spin" name="i-mdi-loading" data-cy="loading-icon" />
<p v-if="spinnerText" class="text-white font-semibold">
{{ spinnerText }}
</p>
</div>
</UModal>
</template>
36 changes: 11 additions & 25 deletions src/components/bcros/businessDetails/Links.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ const { isAllowedToFile, isDisableNonBenCorps } = useBcrosBusiness()
const isCommentOpen = ref(false)
const isDissolutionDialogOpen = ref(false)
const { goToCreatePage } = useBcrosNavigate()
const ui = useBcrosDashboardUi()
const filings = useBcrosFilings()
const isFetchingDataSpinner = ref(false)
const isAllowedBusinessSummary = computed(() =>
!!currentBusinessIdentifier.value &&
Expand Down Expand Up @@ -122,20 +122,24 @@ const promptChangeBusinessInfo = () => {
/** Request and Download Business Summary Document. */
const downloadBusinessSummary = async (): Promise<void> => {
isFetchingDataSpinner.value = true
ui.fetchingData = true
const businessId = currentBusiness.value.identifier
const apiURL = useRuntimeConfig().public.legalApiURL
const summaryDocument: DocumentI = {
title: 'Summary',
filename: `${businessId} Summary - ${todayIsoDateString()}.pdf`,
link: `${apiURL}/businesses/${businessId}/documents/summary`
}
const blob = await fetchDocuments(summaryDocument.link) // todo: show alert box on error
if (blob) {
saveBlob(blob, summaryDocument.filename)
try {
const blob = await fetchDocuments(summaryDocument.link)
if (blob) {
saveBlob(blob, summaryDocument.filename)
}
} catch (error) {
console.error('Failed to download business summary.', error)
// TO-DO: #25125 - show the download error dialog
}
isFetchingDataSpinner.value = false
ui.fetchingData = false
}
/** Creates a draft filing and navigates to the Create UI to file a company dissolution filing. */
Expand Down Expand Up @@ -183,24 +187,6 @@ const contacts = getContactInfo('registries')

<template>
<div class="flex flex-wrap gap-x-3 gap-y-1 items-center max-w-bcros">
<UModal
v-model="isFetchingDataSpinner"
prevent-close
:ui="{
background: 'bg-transparent',
shadow: 'shadow-none',
overlay: {
background: 'bg-gray-800/75 dark:bg-gray-800/75',
}
}"
>
<div class="w-full h-full text-center items-center">
<BcrosLoadingIcon />
<p class="text-white font-semibold">
{{ $t('text.general.fetchingData') }}
</p>
</div>
</UModal>
<!-- Dissolution Confirmation Dialog -->
<BcrosDialog
attach="#businessDetails"
Expand Down
15 changes: 13 additions & 2 deletions src/components/bcros/filing/CommonTemplate.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ import type { ApiResponseFilingI } from '#imports'
import { FilingStatusE, isFilingStatus } from '#imports'
import { loadComments } from '~/utils/filings'
const ui = useBcrosDashboardUi()
const contacts = getContactInfo('registries')
const t = useNuxtApp().$i18n.t
Expand All @@ -109,9 +110,19 @@ const isStatusApproved = computed(() => isFilingStatus(filing.value, FilingStatu
const isShowBody = ref(false)
const showDetails = () => {
const showDetails = async () => {
if (filing.value.documents === undefined && filing.value.documentsLink) {
loadDocumentList(filing.value)
ui.fetchingData = true
await loadDocumentList(filing.value).catch((error) => {
console.error('Failed to load the document list.', error)
// TO-DO: #25125 - show the download error dialog
})
// make the spinner display for another 250ms so it does not flash when the promise resolves quickly
await sleep(250)
ui.fetchingData = false
}
isShowBody.value = !isShowBody.value
}
Expand Down
17 changes: 15 additions & 2 deletions src/components/bcros/filing/common/HeaderActions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@
<UModal v-model="isCommentOpen" :ui="{base: 'absolute left-10 top-5 bottom-5'}">
<BcrosComment :comments="filing.comments" :filing="filing" @close="showCommentDialog(false)" />
</UModal>

<BcrosLoadingModal :open="loadingDocuments" />
</div>
</template>

Expand All @@ -103,6 +105,7 @@ const { isAllowedToFile, isBaseCompany, isDisableNonBenCorps, isEntityCoop, isEn
const { currentBusiness } = storeToRefs(useBcrosBusiness())
const { isBootstrapFiling } = useBcrosBusinessBootstrap()
const { goToEditPage } = useBcrosNavigate()
const ui = useBcrosDashboardUi()
const isCommentOpen = ref(false)
const filings = useBcrosFilings()
Expand Down Expand Up @@ -323,14 +326,24 @@ const actions: any[][] = [[
}
]]
const handleButtonClick = () => {
const handleButtonClick = async () => {
// toggle expansion state
isExpanded.value = !isExpanded.value
// if the filing has documentsLink but the documents list is empty
// (i.e., when View More is clicked for the first time), load the documents list
if (filing.value.documents === undefined && filing.value.documentsLink) {
loadDocumentList(filing.value)
ui.fetchingData = true
await loadDocumentList(filing.value).catch((error) => {
console.error('Failed to load the document list.', error)
// TO-DO: #25125 - show the download error dialog
})
// make the spinner display for another 250ms so it does not flash when the promise resolves quickly
await sleep(250)
ui.fetchingData = false
}
}
</script>
3 changes: 2 additions & 1 deletion src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@
"act": "Act",
"the": "The",
"company": "Company",
"fetchingData": "Loading...",
"fetchingData": "Fetching Data",
"loadingDashboard": "Loading Dashboard",
"notifications": "Notifications",
"pendingNotifications": "No notifications | You have {n} pending approval | You have {n} pending approvals",
"notificationSubLabel": "{n} team member require approval to access this account | {n} team members require approval to access this account"
Expand Down
10 changes: 5 additions & 5 deletions src/layouts/business.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<script setup lang="ts">
const route = useRoute()
const t = useNuxtApp().$i18n.t
const { isStaffAccount } = useBcrosAccount()
const { dashboardIsLoading } = storeToRefs(useBcrosDashboardUi())
const { dashboardIsLoading, fetchingData } = storeToRefs(useBcrosDashboardUi())
const crumbConstructors = computed(() => {
if (isStaffAccount) {
Expand All @@ -20,14 +21,13 @@ onMounted(async () => {
</script>

<template>
<div v-show="dashboardIsLoading" class="w-screen h-screen flex items-center justify-center">
<BcrosLoadingIcon />
</div>
<BcrosLoadingModal :open="dashboardIsLoading" :spinner-text="t('text.general.loadingDashboard')" />
<BcrosLoadingModal :open="fetchingData" :spinner-text="t('text.general.fetchingData')" />
<div v-show="!dashboardIsLoading" class="app-container" data-cy="default-layout">
<bcros-header />
<div class="justify-center">
<bcros-system-banner
class="justify-center "
class="justify-center"
:message="systemMessage"
/>
</div>
Expand Down
7 changes: 1 addition & 6 deletions src/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
const route = useRoute()
const { isStaffAccount } = useBcrosAccount()
const { dashboardIsLoading } = storeToRefs(useBcrosDashboardUi())
const crumbConstructors = computed(() => {
if (isStaffAccount) {
return (route?.meta?.staffBreadcrumbs || []) as (() => BreadcrumbI)[]
Expand All @@ -20,10 +18,7 @@ onMounted(async () => {
</script>

<template>
<div v-show="dashboardIsLoading" class="w-screen h-screen flex items-center justify-center">
<BcrosLoadingIcon />
</div>
<div v-show="!dashboardIsLoading" class="app-container" data-cy="default-layout">
<div class="app-container" data-cy="default-layout">
<bcros-header />
<bcros-system-banner
class="justify-center"
Expand Down
2 changes: 2 additions & 0 deletions src/stores/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ export const useBcrosDashboardUi = defineStore('bcros/dashboardUi', () => {
}

const dashboardIsLoading = computed(() => uiIsLoading.value.length > 0)
const fetchingData = ref(false)

return {
dashboardIsLoading,
fetchingData,
trackUiLoadingStart,
trackUiLoadingStop
}
Expand Down
2 changes: 0 additions & 2 deletions src/utils/download-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ const camelCaseToWords = (s: string): string => {
* @param filing the filing object
*/
export const loadDocumentList = async (filing: ApiResponseFilingI) => {
// TO-DO Add a loader state for loading documents #24451

const t = useNuxtApp().$i18n.t
const unknownStr = `[${t('text.general.unknown')}]`
const { currentBusinessIdentifier } = storeToRefs(useBcrosBusiness())
Expand Down
8 changes: 8 additions & 0 deletions src/utils/sleeps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* "Sleeps" for specified timeout. Must be awaited.
* @param ms Delay to sleep, in milliseconds.
* @returns A promise to await upon.
*/
export function sleep (ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms))
}

0 comments on commit 444aa60

Please sign in to comment.