@sbc-connect/nuxt-base 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/app/components/Connect/Footer.vue +0 -5
- package/app/components/Connect/Modal/Error.vue +76 -0
- package/app/composables/useConnectModal.ts +4 -2
- package/app/utils/getErrorMessage.ts +42 -0
- package/app/utils/getErrorStatus.ts +37 -0
- package/i18n/locales/en-CA.ts +0 -1
- package/i18n/locales/fr-CA.ts +1 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @sbc-connect/nuxt-base
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#111](https://github.com/bcgov/connect-nuxt/pull/111) [`d9d6356`](https://github.com/bcgov/connect-nuxt/commit/d9d63560e27117c43b9e8e54d363c3fdbb620049) Thanks [@hfekete](https://github.com/hfekete)! - Remove broken 'Release Notes' link from footer and related translations
|
|
8
|
+
|
|
9
|
+
## 0.4.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#106](https://github.com/bcgov/connect-nuxt/pull/106) [`f5d34df`](https://github.com/bcgov/connect-nuxt/commit/f5d34df0bbb2b37cbeda8a9dd39c6bce098c564f) Thanks [@deetz99](https://github.com/deetz99)! - <br>
|
|
14
|
+
- ConnectModalError component
|
|
15
|
+
- getErrorStatus util
|
|
16
|
+
- getErrorMessage util
|
|
17
|
+
|
|
3
18
|
## 0.3.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
|
@@ -9,11 +9,6 @@ const links = [
|
|
|
9
9
|
label: 'connect.label.home',
|
|
10
10
|
to: localePath('/')
|
|
11
11
|
},
|
|
12
|
-
{
|
|
13
|
-
label: 'connect.label.releaseNotes',
|
|
14
|
-
to: 'https://www.release-notes.bcregistry.gov.bc.ca',
|
|
15
|
-
target: '_blank'
|
|
16
|
-
},
|
|
17
12
|
{
|
|
18
13
|
label: 'connect.label.fees',
|
|
19
14
|
to: feesUrl,
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { VNode } from 'vue'
|
|
3
|
+
// https://vue-i18n.intlify.dev/api/composition.html#te-key-locale
|
|
4
|
+
const { t, te } = useI18n()
|
|
5
|
+
|
|
6
|
+
interface ErrorModalProps {
|
|
7
|
+
error: unknown
|
|
8
|
+
i18nPrefix: string
|
|
9
|
+
buttons?: ConnectModalButton[]
|
|
10
|
+
contactInfo?: VNode
|
|
11
|
+
preferErrorMessage?: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
error,
|
|
16
|
+
i18nPrefix,
|
|
17
|
+
buttons = [
|
|
18
|
+
{ label: useNuxtApp().$i18n.t('label.close'), shouldClose: true }
|
|
19
|
+
],
|
|
20
|
+
preferErrorMessage = false
|
|
21
|
+
} = defineProps<ErrorModalProps>()
|
|
22
|
+
defineEmits<{ close: [] }>()
|
|
23
|
+
|
|
24
|
+
const status = getErrorStatus(error)
|
|
25
|
+
const message = getErrorMessage(error)
|
|
26
|
+
|
|
27
|
+
const titleKey = `${i18nPrefix}.${status}.title`
|
|
28
|
+
const descKey = `${i18nPrefix}.${status}.description`
|
|
29
|
+
|
|
30
|
+
const title = te(titleKey) ? t(titleKey) : t(`${i18nPrefix}.undefined.title`)
|
|
31
|
+
const i18nDescription = te(descKey) ? t(descKey) : t(`${i18nPrefix}.undefined.description`)
|
|
32
|
+
|
|
33
|
+
const description = (preferErrorMessage && message)
|
|
34
|
+
? message
|
|
35
|
+
: i18nDescription
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<UModal
|
|
40
|
+
id="connect-error-modal"
|
|
41
|
+
overlay
|
|
42
|
+
:title
|
|
43
|
+
:description
|
|
44
|
+
:dismissible="false"
|
|
45
|
+
>
|
|
46
|
+
<template #content>
|
|
47
|
+
<div class="p-10 flex flex-col gap-6">
|
|
48
|
+
<h2 class="text-2xl font-semibold text-neutral-highlighted">
|
|
49
|
+
{{ title }}
|
|
50
|
+
</h2>
|
|
51
|
+
<p>{{ description }}</p>
|
|
52
|
+
<component :is="contactInfo" v-if="contactInfo" />
|
|
53
|
+
<div class="flex flex-wrap items-center justify-center gap-4">
|
|
54
|
+
<template
|
|
55
|
+
v-for="button in buttons"
|
|
56
|
+
:key="button.label"
|
|
57
|
+
>
|
|
58
|
+
<UButton
|
|
59
|
+
v-if="button.shouldClose"
|
|
60
|
+
v-bind="button"
|
|
61
|
+
size="xl"
|
|
62
|
+
class="w-full justify-center sm:w-min sm:justify-normal"
|
|
63
|
+
@click="$emit('close')"
|
|
64
|
+
/>
|
|
65
|
+
<UButton
|
|
66
|
+
v-else
|
|
67
|
+
v-bind="button"
|
|
68
|
+
size="xl"
|
|
69
|
+
class="w-full justify-center sm:w-min sm:justify-normal"
|
|
70
|
+
/>
|
|
71
|
+
</template>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</template>
|
|
75
|
+
</UModal>
|
|
76
|
+
</template>
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { ConnectModal } from '#components'
|
|
1
|
+
import { ConnectModal, ConnectModalError } from '#components'
|
|
2
2
|
|
|
3
3
|
export const useConnectModal = () => {
|
|
4
4
|
const overlay = useOverlay()
|
|
5
5
|
|
|
6
6
|
const baseModal = overlay.create(ConnectModal)
|
|
7
|
+
const errorModal = overlay.create(ConnectModalError)
|
|
7
8
|
|
|
8
9
|
return {
|
|
9
|
-
baseModal
|
|
10
|
+
baseModal,
|
|
11
|
+
errorModal
|
|
10
12
|
}
|
|
11
13
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Safely extracts an error message from an unknown error object.
|
|
5
|
+
*
|
|
6
|
+
* The search order (Highest Priority to Lowest) is:
|
|
7
|
+
* 1. Current object's 'message' (must be a non-empty string).
|
|
8
|
+
* 2. Current object's 'detail' (must be a non-empty string).
|
|
9
|
+
* 3. Recursively searches the 'error.data.rootCause' object.
|
|
10
|
+
* 4. Recursively searches the 'error.data' object.
|
|
11
|
+
*
|
|
12
|
+
* This function will return the first valid, non-empty string message found.
|
|
13
|
+
*
|
|
14
|
+
* @param error - The error object (unknown).
|
|
15
|
+
* @returns The error message if found, else 'undefined'.
|
|
16
|
+
*/
|
|
17
|
+
export function getErrorMessage(error: unknown): string | undefined {
|
|
18
|
+
if (error && typeof error === 'object') {
|
|
19
|
+
const errorObject = error as Record<string, any>
|
|
20
|
+
|
|
21
|
+
const message = errorObject.message
|
|
22
|
+
if (message && typeof message === 'string' && message.length > 0) {
|
|
23
|
+
return message
|
|
24
|
+
}
|
|
25
|
+
const detail = errorObject.detail
|
|
26
|
+
if (detail && typeof detail === 'string' && detail.length > 0) {
|
|
27
|
+
return detail
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const rootCauseMessage = getErrorMessage(errorObject?.data?.rootCause)
|
|
31
|
+
if (rootCauseMessage) {
|
|
32
|
+
return rootCauseMessage
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const dataMessage = getErrorMessage(errorObject?.data)
|
|
36
|
+
if (dataMessage) {
|
|
37
|
+
return dataMessage
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return undefined
|
|
42
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safely extracts the HTTP status code from a thrown error.
|
|
3
|
+
*
|
|
4
|
+
* This provides a reliable way to get a status code from an `unknown` error type.
|
|
5
|
+
*
|
|
6
|
+
* @param error - The error object to inspect. It can be of any type.
|
|
7
|
+
* @returns The numeric HTTP status code if found, otherwise `undefined`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* getErrorStatus({ response: { status: 404 } }); // returns 404
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* getErrorStatus({ statusCode: 403 }); // returns 403
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* getErrorStatus(new Error("Network failed")); // returns undefined
|
|
17
|
+
*/
|
|
18
|
+
export function getErrorStatus(error: unknown): number | undefined {
|
|
19
|
+
// check if error is valid object
|
|
20
|
+
if (
|
|
21
|
+
error
|
|
22
|
+
&& typeof error === 'object'
|
|
23
|
+
&& ('statusCode' in error || 'response' in error)
|
|
24
|
+
) {
|
|
25
|
+
// handle case where error.response.status
|
|
26
|
+
if ('response' in error && error.response && typeof error.response === 'object' && 'status' in error.response) {
|
|
27
|
+
return error.response.status as number
|
|
28
|
+
}
|
|
29
|
+
// handle case where no error.response.status, fallback to error.statusCode
|
|
30
|
+
if ('statusCode' in error) {
|
|
31
|
+
return error.statusCode as number
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// return undefined if no status or statusCode
|
|
36
|
+
return undefined
|
|
37
|
+
}
|
package/i18n/locales/en-CA.ts
CHANGED
|
@@ -33,7 +33,6 @@ export default {
|
|
|
33
33
|
hoursOfOperation: 'Hours of Operation',
|
|
34
34
|
localeSelect: 'Select a Language, current language: English',
|
|
35
35
|
privacy: 'Privacy',
|
|
36
|
-
releaseNotes: 'Release Notes',
|
|
37
36
|
whatsNew: "What's New",
|
|
38
37
|
whatsNewAria: "What's New, {count} unread",
|
|
39
38
|
whatsNewSlideover: "What's New at BC Registries"
|
package/i18n/locales/fr-CA.ts
CHANGED