Skip to content

Commit

Permalink
- combined Upload Affidavit component with ULC Info component
Browse files Browse the repository at this point in the history
- more WIP
  • Loading branch information
Severin Beauvais committed Oct 23, 2024
1 parent 845c7c9 commit 23c8362
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 310 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,88 @@
<v-card
flat
class="py-8 px-6"
:class="{ 'invalid-section': getShowErrors && !affidavitValid }"
:class="{ 'invalid-section': getShowErrors && !affidavitFileValid }"
>
<!-- Upload File -->
<v-row no-gutters>
<v-col
cols="12"
sm="3"
class="pr-4"
>
<label>Upload File</label>
<label class="font-weight-bold colour-dk-text">Upload File</label>
</v-col>

<v-col
cols="12"
sm="9"
class="pt-4 pt-sm-0"
>
<UploadAffidavit
:business="business"
@valid="affidavitValid = $event"
<p :class="{ 'error-text': getShowErrors && !affidavitFileValid }">
You are required to provide either a <strong>Director's Affidavit</strong> or a
<strong>Court Order</strong>. This will be reviewed by BC Registries.
</p>

<ul>
<li>Use a white background and a legible font with contrasting font colour</li>
<li>PDF file type (maximum 30 MB file size)</li>
</ul>

<v-btn
id="add-affidavit-button"
outlined
color="primary"
class="btn-outlined-primary mt-4"
:disabled="affidavitFileValid"
:loading="isDocumentLoading"
@click="onClickAddDocumentButton()"
>
<v-icon>mdi-plus</v-icon>
<span>Add a Document</span>
</v-btn>

<p
v-if="customErrorMessage"
class="error-text mt-4 mb-0"
>
{{ customErrorMessage }}
</p>

<FileUploadPreview
ref="fileUploadPreview"
class="d-none"
:maxSize="MAX_FILE_SIZE"
:customErrorMessage.sync="customErrorMessage"
:isRequired="false"
@fileValidity="onFileValidity($event)"
@fileSelected="onFileSelected($event)"
/>

<div
v-if="affidavitFileValid"
class="dk-gray-background rounded d-flex justify-space-between align-center mt-5 px-2 py-2"
>
<v-icon>mdi-paperclip</v-icon>
<div class="document-details mr-auto pl-2">
{{ business.affidavitFile.name }}
<span class="pl-2">({{ friendlyFileSize(business.affidavitFile) }})</span>
</div>
<v-btn
class="remove-document-button"
text
color="primary"
@click="onRemoveClicked()"
>
<span>Remove</span>
<v-icon dense>
mdi-close
</v-icon>
</v-btn>
</div>

<p class="info-text font-14 mt-6 mb-0">
Uploaded files will be renamed automatically.
</p>
</v-col>
</v-row>
</v-card>
Expand All @@ -32,121 +95,164 @@
<script lang="ts">
import { Component, Emit, Mixins, Watch } from 'vue-property-decorator'
import { Action, Getter } from 'pinia-class'
import { StatusCodes } from 'http-status-codes'
import { useStore } from '@/store/store'
import { DateMixin } from '@/mixins'
import { ExistingBusinessInfoIF } from '@/interfaces'
import { JurisdictionLocation } from '@bcrs-shared-components/enums'
import UploadAffidavit from './UploadAffidavit.vue'
import { DateMixin, DocumentMixin } from '@/mixins'
import { ExistingBusinessInfoIF, PresignedUrlIF } from '@/interfaces'
import FileUploadPreview from '../common/FileUploadPreview.vue'
@Component({
components: {
UploadAffidavit
FileUploadPreview
}
})
export default class UnlimitedLiabilityCorporationInformation extends Mixins(DateMixin) {
export default class UnlimitedLiabilityCorporationInformation extends Mixins(DateMixin, DocumentMixin) {
// Refs
$refs!: {
fileUploadPreview: FileUploadPreview
}
@Getter(useStore) getCurrentDate!: string
@Getter(useStore) getExistingBusinessInfo!: ExistingBusinessInfoIF
@Getter(useStore) getKeycloakGuid!: string
@Getter(useStore) getShowErrors!: boolean
@Getter(useStore) isContinuationInAffidavitRequired!: boolean
@Action(useStore) setExistingBusinessInfo!: (x: ExistingBusinessInfoIF) => void
@Action(useStore) setHaveChanges!: (x: boolean) => void
// Local properties
business = {} as ExistingBusinessInfoIF
affidavitValid = false
customErrorMessage = ''
fileValidity = false
isDocumentLoading = false
/** Called when this component is mounted. */
mounted (): void {
// point business variable to Existing Business Info object from the store, if it exists
if (this.getExistingBusinessInfo) this.business = this.getExistingBusinessInfo
}
/** Called when user has selected a jurisdiction. */
onJurisdictionChange (jurisdiction: any): void {
this.business.previousJurisdiction = null
/** Whether the affidavit file is valid. */
get affidavitFileValid (): boolean {
// assume valid if file object is present
return !!this.business.affidavitFile
}
if (jurisdiction?.group === 0) {
// set property reactively (in case it was null)
this.$set(this.business, 'previousJurisdiction', {
country: JurisdictionLocation.CA,
region: (jurisdiction.value === JurisdictionLocation.FD) ? 'FEDERAL' : jurisdiction.value
})
}
/** When user has clicked the Add button, opens the file selection dialog. */
onClickAddDocumentButton (): void {
this.$refs.fileUploadPreview.clickFileInput()
}
/**
* Called when FileUploadPreview tells us whether a file is valid.
* This is called right before the File Selected event.
*/
onFileValidity (valid: boolean): void {
this.fileValidity = valid
}
if (jurisdiction?.group === 1) {
// set property reactively (in case it was null)
this.$set(this.business, 'previousJurisdiction', {
country: JurisdictionLocation.US,
region: jurisdiction.value
})
/**
* Called when FileUploadPreview tells us about a new or cleared file.
* This is called right after the File Validity event.
* @param file the file to add
*/
async onFileSelected (file: File): Promise<void> {
/** Returns True if given string contains only Latin 1 (ie, ISO8859-1) characters. */
function isValidLatin1 (str: string): boolean {
// eslint-disable-next-line no-control-regex
return !/[^\u0000-\u00ff]/g.test(str)
}
if (jurisdiction?.group === 2) {
// set property reactively (in case it was null)
this.$set(this.business, 'previousJurisdiction', {
country: jurisdiction.value,
region: ''
})
// verify that file is specified and is valid
if (file && this.fileValidity) {
// verify file name encoding
if (!isValidLatin1(file.name)) {
// set error message
this.customErrorMessage = 'Invalid character in file name.'
return // don't add to array
}
// try to upload to Minio
let psu: PresignedUrlIF
try {
this.isDocumentLoading = true
psu = await this.getPresignedUrl(file.name)
const res = await this.uploadToUrl(psu.preSignedUrl, file, psu.key, this.getKeycloakGuid)
if (!res || res.status !== StatusCodes.OK) throw new Error()
} catch {
// set error message
this.customErrorMessage = this.UPLOAD_FAILED_MESSAGE
return // don't add to array
} finally {
this.isDocumentLoading = false
}
// add properties reactively to business object
// (it is the same object the parent is working with)
this.$set(this.business, 'affidavitFile', {
name: file.name,
lastModified: file.lastModified,
size: file.size
} as File)
this.$set(this.business, 'affidavitFileKey', psu.key)
this.$set(this.business, 'affidavitFileName', file.name)
}
}
/** Called when user clicks a Remove button. */
onRemoveClicked (): void {
// delete file from Minio, not waiting for response and ignoring errors
this.deleteDocument(this.business.affidavitFileKey).catch(() => null)
// delete properties reactively
this.$delete(this.business, 'affidavitFile')
this.$delete(this.business, 'affidavitFileKey')
this.$delete(this.business, 'affidavitFileName')
// clear any existing error message
this.customErrorMessage = ''
}
/** Emits form validity. */
@Watch('business', { deep: true })
@Watch('affidavitValid')
@Watch('getShowErrors')
@Watch('affidavitFileValid')
@Emit('valid')
private onComponentValid (): boolean {
// if we're here it's because the user has changed something
this.setHaveChanges(true)
// this component is valid if we have the affidavit file, if required
return (this.getShowErrors && this.affidavitValid)
// this component is valid if we have the affidavit file
return (this.getShowErrors && this.affidavitFileValid)
}
}
</script>

<style lang="scss" scoped>
@import '@/assets/styles/theme.scss';
// set style for all root labels
label {
font-weight: bold;
color: $gray9;
}
// add whitespace between the first and second columns
.col-sm-3 {
padding-right: 1rem !important;
}
// disable the clickable v-textfield label
:deep(.incorporation-number label) {
pointer-events: none;
}
// style the bullets
ul {
list-style: none;
color: $gray7;
#incorporation-date {
// show pointer on hover
:deep(.v-input__slot) {
pointer-events: auto;
cursor: pointer;
li::before {
content: "\2022";
display: inline-block;
width: 1.25em;
margin-left: -1.5em;
padding-left: 0.25rem;
}
// set icon color
:deep(.v-input__icon--append .v-icon) {
color: $app-blue !important;
li {
color: $gray7;
}
}
// align the checkbox with its label
:deep(.v-input--checkbox .v-input__slot) {
align-items: flex-start;
// align the remove icon with the button label
.v-icon.mdi-close {
padding-top: 1px;
}
// style the checkbox label
:deep(.v-input--checkbox label) {
margin-top: 1px;
font-size: $px-14;
color: $gray9;
// show info text in lighter gray
.info-text {
color: $gray7;
}
</style>
Loading

0 comments on commit 23c8362

Please sign in to comment.