Skip to content

Commit

Permalink
8572 Old Manage business dashboard updates (#1746)
Browse files Browse the repository at this point in the history
* Initial Commit

* Added Feature Flag

* Clean up

* Updated Flag parsing

* Updated for Multiple names
  • Loading branch information
cameron-eyds authored Aug 23, 2021
1 parent 7117aec commit 3f33d90
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 64 deletions.
1 change: 1 addition & 0 deletions auth-web/src/assets/scss/theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,4 @@ $BCgovFontColorInverted: #ffffff;
// App Colors
$app-blue: #1669bb; // same as the Vuetify theme primary
$app-lt-blue: #01336626; // LOW OPACITY PRIMARY BLUE
$app-background-blue: #E4EDF7 // Hover Background Blue
Original file line number Diff line number Diff line change
Expand Up @@ -156,32 +156,10 @@ export default class AddNameRequestForm extends Vue {
email: this.applicantEmail
})
if (nrResponse?.status === 201) {
// update the legal api if the status is success
const filingBody: BusinessRequest = {
filing: {
header: {
name: FilingTypes.INCORPORATION_APPLICATION,
accountId: this.currentOrganization.id
},
business: {
legalType: LegalTypes.BCOMP
},
incorporationApplication: {
nameRequest: {
legalType: LegalTypes.BCOMP,
nrNumber: this.nrNumber
}
}
}
}
const filingResponse = await this.createNamedBusiness(filingBody)
if (filingResponse?.errorMsg) {
this.$emit('add-unknown-error')
} else {
// emit event to let parent know business added
this.$emit('add-success')
}
// emit event to let parent know business added
this.$emit('add-success')
} else {
this.$emit('add-unknown-error')
}
} catch (exception) {
if (exception.response?.status === StatusCodes.BAD_REQUEST) {
Expand Down
210 changes: 177 additions & 33 deletions auth-web/src/components/auth/manage-business/AffiliatedEntityList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,73 @@
<div class="meta">
<v-list-item-title v-if="isNumberedIncorporationApplication(item)">Numbered Benefit Company</v-list-item-title>
<v-list-item-title v-if="!isNumberedIncorporationApplication(item)">{{ item.name }}</v-list-item-title>
<v-list-item-title v-if="!item.name && isNameRequest(item.corpType.code)">{{ getApprovedName(item) }}</v-list-item-title>
<v-list-item-subtitle v-if="isIncorporationNumber(item.corpType.code)">Incorporation Number: {{ item.businessIdentifier }}</v-list-item-subtitle>
<v-list-item-subtitle v-if="isNameRequest(item.corpType.code)">Name Request ({{ item.businessIdentifier }})</v-list-item-subtitle>
<v-list-item-subtitle v-if="isTemporaryBusinessRegistration(item.corpType.code)">Incorporation Application</v-list-item-subtitle>
</div>
</template>
<template v-slot:[`item.action`]="{ item }">

<!-- Actions -->
<template v-slot:[`item.action`]="{ item, index }">
<div class="actions">
<v-btn small color="primary" @click="goToDashboard(item)" title="Go to Business Dashboard" data-test="goto-dashboard-button">Open</v-btn>
<v-btn v-can:REMOVE_BUSINESS.disable small depressed @click="removeBusiness(item)" title="Remove Business" data-test="remove-button">Remove</v-btn>
<span class="open-action">
<v-btn
small
color="primary"
min-width="5rem"
min-height="2rem"
class="open-action-btn"
data-test="open-action-button"
@click="open(item)"
>
Open
</v-btn>
</span>

<!-- More Actions Menu -->
<span class="more-actions mr-4">
<v-menu
offset-y left nudge-bottom="4"
v-model="index"
>
<template v-slot:activator="{ on }">
<v-btn
small
color="primary"
min-height="2rem"
class="more-actions-btn"
v-on="on"
>
<v-icon>{{index ? 'mdi-menu-up' : 'mdi-menu-down'}}</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item
v-if="isApprovedForIA(item)"
class="actions-dropdown_item"
data-test="use-name-request-button"
@click="createDraftGoToDashboard(item)"
>
<v-list-item-subtitle>
<v-icon small>mdi-file-certificate-outline</v-icon>
<span class="pl-1">Use this Name Request</span>
</v-list-item-subtitle>
</v-list-item>
<v-list-item
class="actions-dropdown_item"
data-test="remove-button"
v-can:REMOVE_BUSINESS.disable
@click="removeBusiness(item)"
>
<v-list-item-subtitle>
<v-icon small>mdi-delete</v-icon>
<span class="pl-1">Remove</span>
</v-list-item-subtitle>
</v-list-item>
</v-list>
</v-menu>
</span>
</div>
</template>
</v-data-table>
Expand All @@ -47,12 +105,13 @@
</template>

<script lang="ts">
import { Business, BusinessRequest } from '@/models/business'
import { Business, BusinessRequest, NameRequest } from '@/models/business'
import { Component, Emit, Vue } from 'vue-property-decorator'
import { CorpType, FilingTypes, LegalTypes, SessionStorageKeys } from '@/util/constants'
import { CorpType, FilingTypes, LDFlags, LegalTypes, NrState, SessionStorageKeys } from '@/util/constants'
import { Member, MembershipStatus, MembershipType, Organization, RemoveBusinessPayload } from '@/models/Organization'
import { mapActions, mapMutations, mapState } from 'vuex'
import ConfigHelper from '@/util/config-helper'
import LaunchDarklyService from 'sbc-common-components/src/services/launchdarkly.services'
import OrgModule from '@/store/modules/org'
import TeamManagement from '@/components/auth/account-settings/team-management/TeamManagement.vue'
import { getModule } from 'vuex-module-decorators'
Expand Down Expand Up @@ -111,13 +170,34 @@ export default class AffiliatedEntityList extends Vue {
return corpType === CorpType.NAME_REQUEST
}
private isApprovedForIA (business: Business): boolean {
// Split string tokens into an array to avoid false string matching
const supportedEntityFlags = LaunchDarklyService.getFlag(LDFlags.IaSupportedEntities)?.split(' ')
return this.isNameRequest(business.corpType.code) &&
business.nameRequest?.state === NrState.APPROVED &&
supportedEntityFlags?.includes(business.nameRequest?.legalType)
}
private isTemporaryBusinessRegistration (corpType: string): boolean {
return corpType === CorpType.NEW_BUSINESS
}
private isNumberedIncorporationApplication (item: Business): boolean {
return item.corpType.code === CorpType.NEW_BUSINESS && item.name === item.businessIdentifier
}
private getApprovedName (item: Business): any {
const approvedName = item => {
for (const nameItem of item.nameRequest?.names) {
if (nameItem.state === NrState.APPROVED) {
return nameItem.name
}
}
}
return approvedName(item) || item.nameRequest.names[0].name // Return first name if DRAFT (None Approved)
}
private customSort (items, index, isDescending) {
const isDesc = isDescending.length > 0 && isDescending[0]
if (index[0] === 'info') {
Expand Down Expand Up @@ -152,45 +232,71 @@ export default class AffiliatedEntityList extends Vue {
this.$router.push({ path: '/businessprofile', query: { redirect: `/account/${this.currentOrganization.id}` } })
}
async goToDashboard (business: Business) {
private open (business: Business): void {
if (business.corpType.code === CorpType.NAME_REQUEST) {
this.goToNameRequest(business.nameRequest)
} else {
this.goToDashboard(business.businessIdentifier)
}
}
private manageTeam (business: Business) {
this.setCurrentBusiness(business)
// Not ideal, as this makes the component less reusable
// TODO: Come up with a better solution: global event bus?
this.$parent.$emit('change-to', TeamManagement)
}
async createDraftGoToDashboard (business: Business) {
let businessIdentifier = business.businessIdentifier
// 3806 : Create new IA if the selected item is Name Request
// If the business is NR, indicates there is no temporary business. Create a new IA for this NR and navigate.
if (business.corpType.code === CorpType.NAME_REQUEST) {
if (business.corpType.code === CorpType.NAME_REQUEST && business.nameRequest.state === NrState.APPROVED) {
this.isLoading = true
const filingBody: BusinessRequest = {
filing: {
header: {
name: FilingTypes.INCORPORATION_APPLICATION,
accountId: this.currentOrganization.id
},
business: {
legalType: LegalTypes.BCOMP
},
incorporationApplication: {
nameRequest: {
legalType: LegalTypes.BCOMP,
nrNumber: business.businessIdentifier
}
}
}
}
const filingResponse = await this.createNamedBusiness(filingBody)
this.isLoading = false
// Find business with name as the NR number and use it for redirection
businessIdentifier = filingResponse.data.filing.business.identifier
businessIdentifier = await this.createBusinessRecord(business)
this.isLoading = false
}
this.goToDashboard(businessIdentifier)
}
private goToDashboard (businessIdentifier: string): void {
ConfigHelper.addToSession(SessionStorageKeys.BusinessIdentifierKey, businessIdentifier)
let redirectURL = `${ConfigHelper.getBusinessURL()}${businessIdentifier}`
window.location.href = decodeURIComponent(redirectURL)
}
private manageTeam (business: Business) {
this.setCurrentBusiness(business)
// Not ideal, as this makes the component less reusable
// TODO: Come up with a better solution: global event bus?
this.$parent.$emit('change-to', TeamManagement)
private goToNameRequest (nameRequest: NameRequest): void {
ConfigHelper.setNrCredentials(nameRequest)
window.location.href = `${ConfigHelper.getNameRequestUrl()}nr/${nameRequest.id}`
}
private async createBusinessRecord (business: Business): Promise<string> {
const filingBody: BusinessRequest = {
filing: {
header: {
name: FilingTypes.INCORPORATION_APPLICATION,
accountId: this.currentOrganization.id
},
business: {
legalType: business.nameRequest.legalType
},
incorporationApplication: {
nameRequest: {
legalType: business.nameRequest.legalType,
nrNumber: business.businessIdentifier
}
}
}
}
const filingResponse = await this.createNamedBusiness(filingBody)
if (filingResponse?.errorMsg) {
this.$emit('add-unknown-error')
} else {
return filingResponse.data.filing.business.identifier
}
}
}
</script>
Expand All @@ -215,11 +321,29 @@ export default class AffiliatedEntityList extends Vue {
}
.actions {
.open-action {
border-right: 1px solid $gray1;
}
.open-action-btn {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.more-actions-btn {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.v-btn + .v-btn {
margin-left: 0.4rem;
margin-left: 0.5rem;
}
}
.actions-dropdown_item:hover {
background-color: $app-background-blue;
}
dd,
dt {
float: left;
Expand Down Expand Up @@ -264,4 +388,24 @@ dd {
padding-bottom: 0.75rem;
}
}
// Vuetify Overrides
::v-deep .v-list-item {
min-height: 2rem !important;
:hover {
cursor: pointer;
}
}
::v-deep .theme--light.v-data-table thead tr:last-child th:last-child span {
padding-right: 85px;
}
::v-deep .theme--light.v-list-item .v-list-item__action-text, .theme--light.v-list-item .v-list-item__subtitle {
color: $app-blue;
.v-icon.v-icon {
color: $app-blue;
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
<AffiliatedEntityList
@add-business="showAddBusinessModal()"
@remove-business="showPasscodeResetOptionsModal($event)"
@add-failed-show-msg="showNRErrorModal"
/>
</template>

Expand Down
21 changes: 19 additions & 2 deletions auth-web/src/models/business.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export interface Business {
name?: string
contacts?: Contact[]
corpType: CorpType,
folioNumber: string
folioNumber: string,
nameRequest?: NameRequest
}

export interface BusinessSearchResultDto {
Expand All @@ -48,8 +49,24 @@ export interface UpdateBusinessNamePayload {

// see https://github.com/bcgov/business-schemas/blob/master/src/registry_schemas/schemas/name_request.json
export interface NameRequest {
names?: Array<Names>
id?: number,
legalType: string,
nrNumber?: string
nrNumber?: string,
state?: string,
applicantEmail?: string,
applicantPhone?: string
}

// Names interface to match external data provided from lear.
export interface Names {
/* eslint-disable camelcase */
decision_text: string,
name_type_cd: string,
designation: string,
name: string,
state: string
/* eslint-disable camelcase */
}

export interface BusinessRequest {
Expand Down
4 changes: 4 additions & 0 deletions auth-web/src/services/business.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,8 @@ export default class BusinessService {
static async resetBusinessPasscode (passcodeResetLoad: PasscodeResetLoad): Promise<AxiosResponse<any>> {
return axios.patch(`${ConfigHelper.getAuthAPIUrl()}/entities/${passcodeResetLoad.businessIdentifier}`, { businessIdentifier: passcodeResetLoad.businessIdentifier, passcodeResetEmail: passcodeResetLoad.passcodeResetEmail, resetPasscode: passcodeResetLoad.resetPasscode })
}

static async getNrData (nrNumber: string): Promise<AxiosResponse<any>> {
return axios.get(`${ConfigHelper.getLegalAPIUrl()}/nameRequests/${nrNumber}`)
}
}
Loading

0 comments on commit 3f33d90

Please sign in to comment.