Skip to content

Commit

Permalink
UI - Display loader and enable court order download (#67)
Browse files Browse the repository at this point in the history
* backup

* add loader to file downloading; add court order file downloading option

* re-organize code and add cypress tests

* update display logic for 'download all'
  • Loading branch information
patrickpeinanw authored Nov 18, 2024
1 parent 3f3a0b0 commit 25bea21
Show file tree
Hide file tree
Showing 9 changed files with 226 additions and 161 deletions.
32 changes: 32 additions & 0 deletions cypress/e2e/components/filings/section.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,22 @@ context('Filings history section', () => {
.find('[data-cy="filing-main-action-button"]')
.click()

// verify document list
cy.wait('@directorChangeDocumentList')
cy.get('[data-cy="download-document-button-Director Change"]').should('exist')
cy.get('[data-cy="download-document-button-Notice Of Articles"]').should('exist')
cy.get('[data-cy="download-document-button-Receipt"]').should('exist')
cy.get('[data-cy="download-document-button-downloadAll"]').should('exist')

// download a single file, all document download buttons should be disabled
cy.intercept('GET', '**/api/v2/businesses/**/filings/**/documents/receipt').as('downloadDocument')
.get('[data-cy="download-document-button-Receipt"]').click()
.get('[data-cy="download-document-button-Director Change"]').should('be.disabled')
.get('[data-cy="download-document-button-Notice Of Articles"]').should('be.disabled')
.get('[data-cy="download-document-button-Receipt"]').should('be.disabled')
.get('[data-cy="download-document-button-downloadAll"]').should('be.disabled')
.wait('@downloadDocument')

// contract filing
cy.get(`[data-cy="filingHistoryItem-default-filing-${directorChange.filingId}"]`)
.find('[data-cy="filing-main-action-button"]')
Expand Down Expand Up @@ -117,10 +127,32 @@ context('Filings history section', () => {
// verify notification
cy.get('[data-cy="hasCourtOrdersNotificationCard"]').should('exist')

// intercept the GET request for the docoument list
cy.intercept(
'GET',
`**/api/v2/businesses/**/filings/${courtOrder.filingId}/documents`,
{
documents: {
uploadedCourtOrder:
`sample/api/v2/businesses/somebusiness/filings/${courtOrder.filingId}/documents/uploadedCourtOrder`
}
}
).as('courtOrderDocumentList')

// expand filing
cy.get(`[data-cy="filingHistoryItem-staff-filing-${courtOrder.filingId}"]`)
.find('[data-cy="filing-main-action-button"]')
.click()
.wait('@courtOrderDocumentList')

// intercept the GET request for downloading the court order
cy.intercept('GET', '**/api/v2/businesses/**/filings/**/uploadedCourtOrder').as('downloadCourtOrder')

// the court order file should be available for download
cy.get(`[data-cy="download-document-button-Court Order ${courtOrder.data.order.fileNumber}"]`)
.should('exist')
.click()
.wait('@downloadCourtOrder')

cy.get(`[data-cy="filingHistoryItem-staff-filing-${courtOrder.filingId}"]`)
.contains('Pursuant to a Plan of Arrangement')
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/initial-page-load.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ context('Business Dashboard -> Basic page rendering tests', () => {
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)')
cy.get('[data-cy="business-dashboard"]').should('contain.text', 'Filing History (0)')
})

it('Loads indefinite, display loader icon', () => {
Expand Down
11 changes: 8 additions & 3 deletions src/components/bcros/filing/CommonTemplate.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
</div>
<div class="ml-auto order-2">
<slot name="actions">
<BcrosFilingCommonHeaderActions v-model:isExpanded="isShowBody" :filing="filing" />
<BcrosFilingCommonHeaderActions v-model:isExpanded="isShowBody" v-model:filing="filing" />
</slot>
</div>
</div>
Expand Down Expand Up @@ -70,7 +70,9 @@
<!-- NB: staff filings don't have documents - see StaffFiling.vue for any exceptions -->
<template v-if="!isStaffFiling(filing) && filing.documentsLink">
<UDivider class="my-6" />
<BcrosFilingCommonDocumentsList :filing="filing" />
<BcrosFilingCommonDocumentsList
:filing="filing"
/>
</template>
</slot>

Expand All @@ -95,7 +97,10 @@ const contacts = getContactInfo('registries')
const t = useNuxtApp().$i18n.t
const filing = defineModel('filing', { type: Object as PropType<ApiResponseFilingI>, required: true })
defineProps({ dataCy: { type: String, required: true } })
defineProps({
dataCy: { type: String, required: true },
downloading: { type: Boolean, required: true }
})
if (filing.value.commentsCount && filing.value.commentsLink) {
filing.value.comments = await loadComments(filing.value)
Expand Down
3 changes: 3 additions & 0 deletions src/components/bcros/filing/List.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const { currentBusiness } = storeToRefs(useBcrosBusiness())
const hasCourtOrders = computed(() => currentBusiness.value?.hasCourtOrders)
const downloading = ref(false)
/** Returns the name of the sub-component to use for the specified filing. */
const filingComponent = (filing: ApiResponseFilingI): Component => {
switch (true) {
Expand Down Expand Up @@ -88,6 +90,7 @@ const filingComponent = (filing: ApiResponseFilingI): Component => {
:is="filingComponent(filing)"
v-if="filing.displayLedger"
:filing="filing"
:downloading="downloading"
/>
</template>

Expand Down
134 changes: 22 additions & 112 deletions src/components/bcros/filing/common/DocumentsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@
:label="document.title"
variant="ghost"
leading-icon="i-mdi-file-pdf-outline"
:disabled="isLoading && !!loadingDocuments.find(doc => doc === document)"
:loading="isLoading"
:disabled="filings.downloadingInProgress || downloadingIndex !== -1 || downloadingAll === true"
:loading="downloadingIndex === index"
class="px-4 py-2"
:data-cy="`download-document-button-${document.title}`"
@click="downloadOne(document)"
@click="downloadOne(document, index)"
/>
</div>
</div>

<div>
<UButton
v-if="filing.documents?.length > 1"
:label="$t('button.filing.common.downloadAll')"
variant="ghost"
:disabled="isLoading"
:loading="isLoading"
:disabled="filings.downloadingInProgress || downloadingIndex !== -1 || downloadingAll === true"
:loading="downloadingAll"
leading-icon="i-mdi-download"
class="px-4 py-2 min-w-10"
data-cy="download-document-button-downloadAll"
Expand All @@ -35,120 +35,30 @@
</template>

<script setup lang="ts">
import type { ApiResponseFilingI, DocumentI, FetchDocumentsI } from '#imports'
import { dateToYyyyMmDd, fetchDocuments, saveBlob } from '#imports'
const t = useNuxtApp().$i18n.t
const unknownStr = `[${t('text.general.unknown')}]`
import type { ApiResponseFilingI, DocumentI } from '#imports'
const { hasRoleStaff } = useBcrosKeycloak()
const filings = useBcrosFilings()
const filing = defineModel('filing', { type: Object as PropType<ApiResponseFilingI>, required: true })
const downloadOne = async (document: DocumentI) => {
const doc = await fetchDocuments(document.link)
saveBlob(doc, document.title)
const downloadingIndex = ref(-1)
const downloadingAll = ref(false)
const downloadOne = async (document: DocumentI, index: number) => {
downloadingIndex.value = index
filings.downloadingInProgress = true
await downloadFile(document)
downloadingIndex.value = -1
filings.downloadingInProgress = false
}
const downloadAll = async () => {
downloadingAll.value = true
filings.downloadingInProgress = true
for (const document of filing.value.documents) {
await downloadOne(document)
}
}
const loadingDocuments = ref([] as DocumentI[])
const isLoading = computed(() => loadingDocuments.value.length !== 0)
const pushDocument = (title: string, filename: string, link: string) => {
if (title && filename && link) {
filing.value.documents.push({ title, filename, link } as DocumentI)
} else {
// eslint-disable-next-line no-console
console.log(`invalid document = ${title} | ${filename} | ${link}`)
}
}
const { currentBusinessIdentifier } = storeToRefs(useBcrosBusiness())
/**
* Converts a string in "camelCase" (or "PascalCase") to a string of separate, title-case words,
* suitable for a title or proper name.
* @param s the string to convert
* @returns the converted string
*/
const camelCaseToWords = (s: string): string => {
const words = s?.split(/(?=[A-Z])/).join(' ').replace(/^\w/, c => c.toUpperCase()) || ''
// SPECIAL CASE: convert 'Agm' to uppercase
return words.replace('Agm', 'AGM')
}
const loadDocumentList = async () => {
if (!filing.value.documents && filing.value.documentsLink) {
// eslint-disable-next-line no-console
console.log('loading filing documents for: ', filing.value.documentsLink)
// todo: add global UI loader start and end #22059
try {
filing.value.documents = []
const documentListObj = await fetchDocumentList(filing.value.documentsLink)
const fetchedDocuments: FetchDocumentsI = documentListObj.documents || {}
for (const groupName in fetchedDocuments) {
if (groupName === 'legalFilings' && Array.isArray(fetchedDocuments.legalFilings)) {
// iterate over legalFilings array
for (const legalFilings of fetchedDocuments.legalFilings) {
// iterate over legalFilings properties
for (const legalFiling in legalFilings) {
// this is a legal filing output
let title: string
// use display name for primary document's title
if (legalFiling === filing.value.name) {
title = filing.value.displayName
} else {
title = t(`filing.name.${legalFiling}`)
if (title === `filing.name.${legalFiling}`) {
title = camelCaseToWords(legalFiling)
}
}
const date = dateToYyyyMmDd(new Date(filing.value.submittedDate))
const filename = `${currentBusinessIdentifier} ${title} - ${date}.pdf`
const link = legalFilings[legalFiling]
pushDocument(title, filename, link)
}
}
} else if (groupName === 'staticDocuments' && Array.isArray(fetchedDocuments.staticDocuments)) {
// iterate over staticDocuments array
for (const document of fetchedDocuments.staticDocuments) {
const title = document.name
const filename = title
const link = document.url
pushDocument(title, filename, link)
}
} else if (groupName === 'uploadedCourtOrder') {
const fileNumber = filing.value.data?.order?.fileNumber || unknownStr
const title = hasRoleStaff ? `${filing.value.displayName} ${fileNumber}` : `${filing.value.displayName}`
const filename = title
const link = fetchedDocuments[groupName] as string
pushDocument(title, filename, link)
} else {
// this is a submission level output
const title = camelCaseToWords(groupName)
const date = dateToYyyyMmDd(new Date(filing.value.submittedDate))
const filename = `${currentBusinessIdentifier} ${title} - ${date}.pdf`
const link = fetchedDocuments[groupName] as string
pushDocument(title, filename, link)
}
}
} catch (error) {
// set property to null to retry next time
filing.value.documents = null
// eslint-disable-next-line no-console
console.log('loadDocuments() error =', error)
// FUTURE: enable some error dialog?
}
await downloadFile(document)
}
}
if (filing.value.documents === undefined && filing.value.documentsLink) {
loadDocumentList()
downloadingAll.value = false
filings.downloadingInProgress = false
}
</script>
Loading

0 comments on commit 25bea21

Please sign in to comment.