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

22468 - Launch Tiles #3134

Merged
merged 3 commits into from
Nov 1, 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
1 change: 1 addition & 0 deletions auth-web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ VUE_APP_XLP_FORMS_URL="https://www2.gov.bc.ca/assets/gov/employment-business-and
VUE_APP_REGISTRY_HOME_URL="https://dev.bcregistry.gov.bc.ca/"
VUE_APP_AUTH_WEB_URL="https://dev.account.bcregistry.gov.bc.ca/"
VUE_APP_DASHBOARD_URL="https://dev.business.bcregistry.gov.bc.ca/"
VUE_APP_DOCUMENTS_UI_URL="https://documents-ui-dev.firebaseapp.com"
VUE_APP_ENTITY_SELECTOR_URL="https://entity-selection-dev.apps.silver.devops.gov.bc.ca/"
VUE_APP_SITEMINDER_LOGOUT_URL="https://logontest7.gov.bc.ca/clp-cgi/logoff.cgi"
VUE_APP_NAME_REQUEST_URL="https://dev.names.bcregistry.gov.bc.ca/"
Expand Down
1 change: 1 addition & 0 deletions auth-web/devops/vaults.env
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ VUE_APP_ONE_STOP_URL="op://relationship/$APP_ENV/auth-web/ONE_STOP_URL"
VUE_APP_REGISTRY_HOME_URL="op://web-url/$APP_ENV/registry/REGISTRY_HOME_URL"
VUE_APP_AUTH_WEB_URL="op://web-url/$APP_ENV/auth-web/AUTH_WEB_URL"
VUE_APP_DASHBOARD_URL="op://web-url/$APP_ENV/business/DASHBOARD_URL"
VUE_APP_DOCUMENTS_UI_URL="op://web-url/$APP_ENV/documents-ui/DOCUMENTS_UI_URL"
seeker25 marked this conversation as resolved.
Show resolved Hide resolved
VUE_APP_ENTITY_SELECTOR_URL="op://web-url/$APP_ENV/entity-selector/ENTITY_SELECTOR_URL"
VUE_APP_SITEMINDER_LOGOUT_URL="op://web-url/$APP_ENV/siteminder/SITEMINDER_LOGOUT_URL"
VUE_APP_NAME_REQUEST_URL="op://web-url/$APP_ENV/name-request/NAME_REQUEST_URL"
Expand Down
4 changes: 2 additions & 2 deletions auth-web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion auth-web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "auth-web",
"version": "2.6.105",
"version": "2.6.106",
"appName": "Auth Web",
"sbcName": "SBC Common Components",
"private": true,
Expand Down
6 changes: 6 additions & 0 deletions auth-web/src/assets/img/icon-drs.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions auth-web/src/assets/img/icon-involuntary-dissolution.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 77 additions & 0 deletions auth-web/src/components/LaunchTile.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<script lang="ts">
import { computed, defineComponent, reactive, toRefs } from '@vue/composition-api'
import { LaunchTileConfigIF } from '@/models/common'

export default defineComponent({
name: 'LaunchTile',
props: {
tileConfig: {
type: Object as () => LaunchTileConfigIF,
required: true
}
},
setup (props) {
const localVars = (reactive({
tileUrl: computed(() => {
return props.tileConfig?.href ? new URL(props.tileConfig.href, import.meta.url) : null
}),
imgUrl: computed(() => new URL(`/src/assets/img/${props.tileConfig.image}`, import.meta.url))
}))

return {
...toRefs(localVars)
}
}
})
</script>

<template>
<v-card
v-if="tileConfig.showTile"
class="launch-card"
>
<v-row>
<v-col cols="auto">
<img
:src="imgUrl"
alt=""
class="launch-image"
>
</v-col>
<v-col>
<header>
<h2>{{ tileConfig.title }}</h2>
<p class="my-3">
{{ tileConfig.description }}
</p>
</header>
<v-btn
id="tile-btn"
class="mt-1"
color="primary"
filled
dark
large
:href="tileUrl"
@click="!tileConfig.href ? tileConfig.action() : null"
>
<span>
{{ tileConfig.actionLabel }}
<v-icon>mdi-chevron-right</v-icon>
</span>
</v-btn>
</v-col>
</v-row>
</v-card>
</template>

<style lang="scss" scoped>
.launch-card {
height: 225px;
padding: 14px 26px;
}
.launch-image {
width: 50px;
height: auto;
}
</style>
1 change: 1 addition & 0 deletions auth-web/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { default as BaseVExpansionPanel } from './BaseVExpansionPanel.vue'
export { default as CardHeader } from './CardHeader.vue'
export { default as DatePicker } from './DatePicker.vue'
export { default as IconTooltip } from './IconTooltip.vue'
export { default as LaunchTile } from './LaunchTile.vue'
12 changes: 12 additions & 0 deletions auth-web/src/models/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ComputedRef } from '@vue/composition-api'

/** Interface for the LaunchTileConfig object */
export interface LaunchTileConfigIF {
showTile: ComputedRef<boolean>
image: string
title: string
description: string
href?: string
action?: () => void
actionLabel: string
}
4 changes: 4 additions & 0 deletions auth-web/src/util/config-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export default class ConfigHelper {
return `${import.meta.env.VUE_APP_REGISTRY_HOME_URL}dashboard`
}

static getBcrosDocumentsUiURL () {
return `${import.meta.env.VUE_APP_DOCUMENTS_UI_URL}`
}

static getBcrosURL () {
return `${ConfigHelper.getSelfURL()}/signin/bcros/`
}
Expand Down
1 change: 1 addition & 0 deletions auth-web/src/util/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ export enum LDFlags {
EnableAffiliationDelegation = 'enable-affiliation-delegation',
EnableCreditCardPremium = 'enable-credit-card-premium',
EnableEFTBalanceByPAD = 'enable-eft-balance-by-pad',
EnableDRSLookup = 'enable-drs-lookup', // Document Record Services
}

export enum DateFilterCodes {
Expand Down
75 changes: 40 additions & 35 deletions auth-web/src/views/auth/staff/StaffDashboardView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -265,53 +265,30 @@
</template>
</BaseVExpansionPanel>

<!-- Involuntary Dissolution -->
<v-card
v-if="showInvoluntaryDissolutionTile"
class="mt-4 pa-8"
>
<v-row
align="center"
justify="space-between"
<!-- Feature Launch Tiles: ie Involuntary Dissolution, Document Record Service -->
<v-row>
<v-col
v-for="tile in launchTileConfig"
:key="tile.title"
cols="6"
>
<v-col>
<header>
<h2 class="mb-0">
Involuntary Dissolution
</h2>
<p class="mt-3 mb-0">
Set up and manage automation for Involuntary Dissolution of businesses
</p>
</header>
</v-col>
<v-col cols="auto">
<v-btn
id="involuntary-dissolution-button"
class="mr-4"
color="primary"
outlined
dark
large
@click="goToInvoluntaryDissolution()"
>
<span>Manage Involuntary Dissolution</span>
</v-btn>
</v-col>
</v-row>
</v-card>
<LaunchTile :tileConfig="tile" />
</v-col>
</v-row>
</v-container>
</template>

<script lang="ts">
import { BaseVExpansionPanel, LaunchTile } from '@/components'
import { ComputedRef, Ref, computed, defineComponent, reactive, ref, toRefs } from '@vue/composition-api'
import { LDFlags, Role, SessionStorageKeys } from '@/util/constants'
import { BaseVExpansionPanel } from '@/components'
import CommonUtils from '@/util/common-util'
import ConfigHelper from '@/util/config-helper'
import ContinuationApplications from '@/components/auth/staff/continuation-application/ContinuationApplications.vue'
import GLCodesListView from '@/views/auth/staff/GLCodesListView.vue'
import IncorporationSearchResultView from '@/views/auth/staff/IncorporationSearchResultView.vue'
import LaunchDarklyService from 'sbc-common-components/src/services/launchdarkly.services'
import { LaunchTileConfigIF } from '@/models/common'
import { Organization } from '@/models/Organization'
import PPRLauncher from '@/components/auth/staff/PPRLauncher.vue'
import SafeEmailView from '@/views/auth/staff/SafeEmailView.vue'
Expand All @@ -337,11 +314,15 @@ interface StaffDashboardViewI {
isFasDashboardEnabled: ComputedRef<boolean>
showBusSearchlink: ComputedRef<boolean>
registrySearchUrl: ComputedRef<string>
showDrsTile: ComputedRef<boolean>
documentsUiUrl: string
showInvoluntaryDissolutionTile: ComputedRef<boolean>
}

export default defineComponent({
name: 'StaffDashboardView',
components: {
LaunchTile,
BaseVExpansionPanel,
SafeEmailView,
GLCodesListView,
Expand Down Expand Up @@ -378,10 +359,13 @@ export default defineComponent({
errorMessage: '',
isFasDashboardEnabled: computed((): boolean => currentUser.value?.roles?.includes(Role.FasSearch)),
registrySearchUrl: computed((): string => ConfigHelper.getRegistrySearchUrl()),
documentsUiUrl: computed((): string => ConfigHelper.getBcrosDocumentsUiURL()),
searchActive: false,
searchedBusinessNumber: '',
showBusSearchlink: computed((): boolean => true),
showInvoluntaryDissolutionTile: computed((): boolean => LaunchDarklyService.getFlag(LDFlags.EnableInvoluntaryDissolution) || false)
showInvoluntaryDissolutionTile: computed((): boolean =>
LaunchDarklyService.getFlag(LDFlags.EnableInvoluntaryDissolution) || false),
showDrsTile: computed((): boolean => LaunchDarklyService.getFlag(LDFlags.EnableDRSLookup) || false)
}) as unknown) as StaffDashboardViewI

const isFormValid = () => localVars.businessIdentifier && searchBusinessForm.value?.validate()
Expand All @@ -390,6 +374,26 @@ export default defineComponent({

const goToManageBusiness = () => root.$router.push(`/account/${currentOrganization.value?.id}/business`)

const launchTileConfig: Array<LaunchTileConfigIF> = [
{
showTile: localVars.showInvoluntaryDissolutionTile,
image: 'icon-involuntary-dissolution.svg',
title: 'Involuntary Dissolution',
description: 'Set up and manage automation for Involuntary Dissolution of businesses',
action: () => { goToInvoluntaryDissolution() },
actionLabel: 'Manage Involuntary Dissolution'
},
{
showTile: localVars.showDrsTile,
image: 'icon-drs.svg',
title: 'Document Record Service',
description: 'Use our document record service to create a new record or search for existing ones. To edit a ' +
'record, simply search for and open the document record.',
href: localVars.documentsUiUrl,
actionLabel: 'Open'
}
]

const updateCurrentBusiness = async () => {
try {
// Search for business, action will set session storage
Expand Down Expand Up @@ -465,6 +469,7 @@ export default defineComponent({
searchBusinessForm,
emailToAdd,
addEmail,
launchTileConfig,
...toRefs(localVars)
}
}
Expand Down
63 changes: 63 additions & 0 deletions auth-web/tests/unit/components/LaunchTile.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import LaunchTile from '@/components/LaunchTile.vue'
import { LaunchTileConfigIF } from '@/models/common'
import { mount } from '@vue/test-utils'
import { nextTick } from '@vue/composition-api'

// Mock data for the tileConfig prop
const mockTileConfig: LaunchTileConfigIF = {
showTile: true,
image: 'icon-drs.svg',
title: 'Document Record Service',
description: 'Use our document record service to create a new record or search for existing ones.',
href: 'http://example.com/',
actionLabel: 'Open',
action: vi.fn(() => 'action called')
}

describe('LaunchTile.vue', () => {
let wrapper: any

beforeEach(() => {
wrapper = mount(LaunchTile, {
propsData: {
tileConfig: mockTileConfig
}
})
})

it('renders the component when showTile is true', () => {
expect(wrapper.find('.launch-card').exists()).toBe(true)
})

it('renders the image with the correct src', () => {
const img = wrapper.find('img')
expect(img.attributes('src')).toContain(mockTileConfig.image)
})

it('renders the title and description', () => {
expect(wrapper.find('h2').text()).toBe(mockTileConfig.title)
expect(wrapper.find('p').text()).toBe(mockTileConfig.description)
})

it('renders the button with the correct label and href', () => {
const button = wrapper.find('#tile-btn')
expect(button.text()).toContain(mockTileConfig.actionLabel)
expect(button.attributes('href')).toBe(mockTileConfig.href)
})

it('calls the action method when button is clicked and href is not provided', async () => {
// Update the props
await wrapper.setProps({
tileConfig: { ...mockTileConfig, href: null }
})

// Find the button and trigger a click event
const button = wrapper.find('#tile-btn')
await button.trigger('click')
await nextTick()

// Assert that the action method was called
expect(mockTileConfig.action).toHaveBeenCalled()
expect(mockTileConfig.action).toHaveReturnedWith('action called')
})
})
Loading