Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

22059 - loading animation for loading business info. #46

Merged
merged 19 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"vue/no-unused-vars": "warn",
"vue/multi-word-component-names": "off",
"vue/no-v-html": "off",
"vue/no-multiple-template-root": "off",
"@typescript-eslint/no-unused-vars": "warn"
}
}
}
32 changes: 29 additions & 3 deletions cypress/e2e/initial-page-load.cy.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,38 @@
context('Business Dashboard -> Basic page rendering tests', () => {
beforeEach(() => {
it('Loads the page with expected text', () => {
cy.visitBusinessDash()
})

it('Loads the page with expected text', () => {
cy.get('[data-cy="business-dashboard"]').should('exist')

cy.get('[data-cy="business-dashboard"]').should('contain.text', 'To Do (0)')
cy.get('[data-cy="business-dashboard"]').should('contain.text', 'Recent Filing History (0)')
})

it('Loads indefinite, display loader icon', () => {
const legalType = 'BEN'
const isHistorical = false
const businessIdentifier = 'BC0871427'

sessionStorage.setItem('FAKE_CYPRESS_LOGIN', 'true')
cy.intercept('GET', '**/api/v1/users/**/settings', { fixture: 'settings.json' }).as('getSettings')
cy.intercept(
'REPORT',
'https://app.launchdarkly.com/sdk/evalx/**/context',
{ fixture: 'ldarklyContext.json' }
).as('getLdarklyContext')
cy.intercept('GET', '**/api/v1/orgs/**/products*', { fixture: 'products.json' }).as('getProducts')
cy.interceptBusinessContact(businessIdentifier, legalType).as('getBusinessContact')
cy.interceptBusinessInfo(businessIdentifier, legalType, isHistorical).as('getBusinessInfo')
cy.interceptAddresses(legalType).as('getAddresses')
cy.interceptParties(legalType, isHistorical).as('getParties')
cy.interceptAffiliationRequests(false, false).as('getAffiliationRequests')
cy.interceptTasks('tasksEmpty.json').as('getTasks')

cy.visit(`/${businessIdentifier}`).then(() => {
cy.get('[data-cy="loading-icon"]').should('be.visible').then(() => {
cy.wait(['@getBusinessInfo'])
cy.get('[data-cy="loading-icon"]').should('not.be.visible')
})
})
})
})
30 changes: 16 additions & 14 deletions src/app.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script setup lang="ts">
import { StatusCodes } from 'http-status-codes'

const appLoading = ref(true)
// // errors
const errorDisplay = ref(false)
const errorContactInfo = ref(false)
Expand All @@ -10,20 +9,25 @@ const errorInfo: Ref<DialogOptionsI | null> = ref(null)
const account = useBcrosAccount()
const { accountErrors } = storeToRefs(account)

const { trackUiLoadingStart, trackUiLoadingStop } = useBcrosDashboardUi()
const loaderTrackingId = 'main-app-loading'

onMounted(async () => {
appLoading.value = true
trackUiLoadingStart(loaderTrackingId)
if (accountErrors.value?.length > 0) {
handleError(accountErrors.value[0])
appLoading.value = false
trackUiLoadingStop(loaderTrackingId)
return
}
if (account.currentAccount?.id) {
// load account products
console.info('Loading active products...', account.currentAccount)
await account.setActiveProducts()
if (accountErrors.value?.length > 0) { return }
if (accountErrors.value?.length > 0) {
return
}
}
appLoading.value = false
trackUiLoadingStop(loaderTrackingId)
console.info('App ready')
})

Expand Down Expand Up @@ -55,7 +59,7 @@ const handleError = (error: ErrorI) => {
errorInfo.value = getDefaultError()
errorContactInfo.value = true
errorDisplay.value = true
// Sentry.captureException(error)
// Sentry.captureException(error)
}
}

Expand All @@ -66,7 +70,11 @@ const clearDialog = () => {
}

// watchers for errors
watch(accountErrors.value, (val) => { if (val && val.length > 0) { handleError(val[0]) } })
watch(accountErrors.value, (val) => {
if (val && val.length > 0) {
handleError(val[0])
}
})
</script>

<template>
Expand All @@ -86,13 +94,7 @@ watch(accountErrors.value, (val) => { if (val && val.length > 0) { handleError(v
<bcros-contact-info class="font-normal font-16 mt-4" :contacts="getContactInfo('registries')" />
</template>
</bcros-dialog>
<div v-if="appLoading">
<UIcon
name="i-heroicons-arrow-path"
class="animate-spin text-[50px] text-gray-700 absolute top-40 left-[50%]"
/>
</div>
<NuxtPage v-else />
<NuxtPage />
</NuxtLayout>
</div>
</template>
3 changes: 3 additions & 0 deletions src/components/bcros/LoadingIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<UIcon class="text-6xl text-gray-700 animate-spin" name="i-mdi-loading" data-cy="loading-icon" />
</template>
2 changes: 1 addition & 1 deletion src/components/bcros/businessDetails/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ watch(currentBusinessContact, updateBusinessDetails)
async function loadComponentData (identifier: string) {
if (bootstrap.checkIsTempReg(identifier)) {
// this is a business bootstrap (actual business does not exist yet)
await bootstrap.loadBusinessBootstrap(identifier)
bootstrap.loadBusinessBootstrap(identifier)
} else {
await business.loadBusiness(identifier)
await business.loadBusinessContact(identifier)
Expand Down
7 changes: 6 additions & 1 deletion src/layouts/business.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
const route = useRoute()
const { isStaffAccount } = useBcrosAccount()

const { dashboardIsLoading } = storeToRefs(useBcrosDashboardUi())

const crumbConstructors = computed(() => {
if (isStaffAccount) {
return (route?.meta?.staffBreadcrumbs || []) as (() => BreadcrumbI)[]
Expand All @@ -18,7 +20,10 @@ onMounted(async () => {
</script>

<template>
<div class="app-container" data-cy="default-layout">
<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">
<bcros-header />
<bcros-system-banner
class="justify-center"
Expand Down
7 changes: 6 additions & 1 deletion src/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
const route = useRoute()
const { isStaffAccount } = useBcrosAccount()

const { dashboardIsLoading } = storeToRefs(useBcrosDashboardUi())

const crumbConstructors = computed(() => {
if (isStaffAccount) {
return (route?.meta?.staffBreadcrumbs || []) as (() => BreadcrumbI)[]
Expand All @@ -18,7 +20,10 @@ onMounted(async () => {
</script>

<template>
<div class="app-container" data-cy="default-layout">
<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">
<bcros-header />
<bcros-system-banner
class="justify-center"
Expand Down
3 changes: 2 additions & 1 deletion src/pages/dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const pendingAddress = computed(() => {
return new Date(b.effectiveDate) - new Date(a.effectiveDate)
})
const coaFiling = coaFilings[0]
if (new Date(coaFiling.effectiveDate) > currentDate) {
if (coaFiling?.effectiveDate && new Date(coaFiling?.effectiveDate) > currentDate) {
return true
}
}
Expand Down Expand Up @@ -340,6 +340,7 @@ const pendingAddress = computed(() => {
.bcros-dash-col {
@apply flex flex-col space-y-5
}

.bcros-dash-side-col {
@apply md:w-3/12 md:pl-5 md:pt-0
}
Expand Down
18 changes: 12 additions & 6 deletions src/stores/business.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const useBcrosBusiness = defineStore('bcros/business', () => {
const authApiURL = useRuntimeConfig().public.authApiURL
const launchdarklyStore = useBcrosLaunchdarkly()

async function fetchBusinessComments(identifier: string) {
async function fetchBusinessComments (identifier: string) {
commentsLoading.value = true
comments.value = []
return await useBcrosFetch<CommentIF>(`${apiURL}/businesses/${identifier}/comments`, {})
Expand Down Expand Up @@ -159,6 +159,10 @@ export const useBcrosBusiness = defineStore('bcros/business', () => {
}

async function loadBusiness (identifier: string, force = false) {
const { trackUiLoadingStart, trackUiLoadingStop } = useBcrosDashboardUi()

trackUiLoadingStart('businessInfoLoading')

const businessCached = currentBusiness.value && identifier === currentBusinessIdentifier.value
if (!businessCached || force) {
fetchBusinessComments(identifier)
Expand All @@ -168,6 +172,7 @@ export const useBcrosBusiness = defineStore('bcros/business', () => {
}
businessConfig.value = getBusinessConfig(currentBusiness.value.legalType)
}
trackUiLoadingStop('businessInfoLoading')
}

async function loadBusinessContact (identifier: string, force = false) {
Expand Down Expand Up @@ -410,7 +415,8 @@ export const useBcrosBusiness = defineStore('bcros/business', () => {
return (ff && isAllowedToFile(FilingTypes.DISSOLUTION, FilingSubTypeE.DISSOLUTION_VOLUNTARY))
}

default: return false // should never happen
default:
return false // should never happen
}
}

Expand Down Expand Up @@ -459,10 +465,10 @@ export const useBcrosBusiness = defineStore('bcros/business', () => {
}

/**
* Creates a new comment
* @param url the full URL to fetch the documents
* @returns the fetch documents object or throws error
*/
* Creates a new comment
* @param url the full URL to fetch the documents
* @returns the fetch documents object or throws error
*/
const postComment = async (businessId: string, comment: CreateCommentI) => {
const apiURL = useRuntimeConfig().public.legalApiURL
const url = `${apiURL}/businesses/${businessId}/comments`
Expand Down
17 changes: 5 additions & 12 deletions src/stores/businessBootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,15 @@ export const useBcrosBusinessBootstrap = defineStore('bcros/businessBootstrap',

/** Load the bootstrap filing for the temporary identifier */
const loadBusinessBootstrap = async (identifier: string, force = false) => {
const { trackUiLoadingStart, trackUiLoadingStop } = useBcrosDashboardUi()
trackUiLoadingStart('boostrapBusinessLoading')

if (!checkIsTempReg(identifier)) {
// should never be here
console.error(`Attempted to load ${identifier} as a bootstrap filing.`)
return
}

const storeIsLoading = new Promise((resolve) => {
watch(isStoreLoading, (newValue) => {
if (newValue === false) { // check the condition
resolve(true)
}
}, { immediate: true })
})

// this acts as semaphore, to check if we already have running loadBusinessBootstrap for current/another business
// because there is a possibility to have race conditions to some of the variables if it's started in another thread
await storeIsLoading

const bootsrapCached = bootstrapIdentifier.value === identifier
if (!bootsrapCached || force) {
isStoreLoading.value = true
Expand All @@ -131,6 +122,8 @@ export const useBcrosBusinessBootstrap = defineStore('bcros/businessBootstrap',
}
isStoreLoading.value = false
}

trackUiLoadingStop('boostrapBusinessLoading')
}

return {
Expand Down
23 changes: 23 additions & 0 deletions src/stores/ui.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/** Manages bcros account data */
export const useBcrosDashboardUi = defineStore('bcros/dashboardUi', () => {
const uiIsLoading = ref([])

const trackUiLoadingStart = (trackingUuid: string) => {
uiIsLoading.value.push(trackingUuid)
}

const trackUiLoadingStop = (trackerUuidDone: string) => {
const index = uiIsLoading.value.findIndex(tracker => tracker === trackerUuidDone)
if (index !== -1) {
uiIsLoading.value.splice(index, 1)
}
}

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

return {
dashboardIsLoading,
trackUiLoadingStart,
trackUiLoadingStop
}
})
Loading