3
0

Adjust error reporting in compose blocks

This commit is contained in:
Jože Fortun 2024-11-27 15:35:51 +01:00
parent ac06c00805
commit 3172415575
12 changed files with 252 additions and 105 deletions

View File

@ -16,6 +16,14 @@ export default {
this.toast(message, { title, variant: 'warning' })
},
toastInfo (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general.info')
}
this.toast(message, { title, variant: 'info' })
},
toastDanger (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general.error')
@ -28,6 +36,14 @@ export default {
this.$root.$bvToast.toast(msg, opt)
},
getToastMessage (err) {
if (err.message && err.message.startsWith('notification')) {
return this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
return err.message
},
toastErrorHandler (opt) {
if (typeof opt === 'string') {
opt = { prefix: opt }
@ -36,13 +52,13 @@ export default {
const { prefix, title } = opt
return (err = {}) => {
// only messages starting with 'notification:' or 'notification.' should be translated
if (err.message && err.message.startsWith('notification')) {
err.message = this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
err.message = this.getToastMessage(err)
// all other messages should be shown as they are
const msg = err.message ? `${prefix}: ${err.message}` : prefix
this.toastDanger(msg, title)
return err.message
}
},
},

View File

@ -1,5 +1,5 @@
<template>
<div class="d-flex flex-column align-items-center justify-content-center h-100 position-relative">
<div class="d-flex h-100 w-100 position-relative">
<div
v-if="processing"
class="d-flex flex-column align-items-center justify-content-center flex-fill"
@ -7,8 +7,15 @@
<b-spinner />
</div>
<label
v-else-if="error"
class="text-primary p-3"
>
{{ error }}
</label>
<c-chart
v-if="renderer"
v-else-if="renderer"
:chart="renderer"
class="flex-fill p-1"
@click="drillDown"
@ -50,6 +57,7 @@ export default {
data () {
return {
error: undefined,
processing: false,
valueMap: new Map(),
@ -87,6 +95,7 @@ export default {
}),
async updateChart () {
this.error = undefined
this.renderer = undefined
const [report = {}] = this.chart.config.reports
@ -203,8 +212,8 @@ export default {
this.renderer = chart.makeOptions(data)
} catch (e) {
this.error = this.toastErrorHandler(this.$t('chart.optionsBuildFailed'))(e)
this.processing = false
this.toastErrorHandler(this.$t('chart.optionsBuildFailed'))(e)
}
setTimeout(() => {
@ -245,11 +254,6 @@ export default {
}
},
error (msg) {
/* eslint-disable no-console */
console.error(msg)
},
setDefaultValues () {
this.processing = false
this.renderer = undefined

View File

@ -3,8 +3,16 @@
v-bind="$props"
v-on="$listeners"
>
<label
v-if="error"
class="text-primary p-3"
>
{{ error }}
</label>
<div
class="rt-content px-3 py-2"
v-else
class="rt-content p-3"
>
<p
:style="{ 'white-space': 'pre-wrap' }"
@ -21,17 +29,39 @@ import { NoID } from '@cortezaproject/corteza-js'
export default {
extends: base,
computed: {
contentBody () {
data () {
return {
error: null,
contentBody: '',
}
},
watch: {
'options.body': {
immediate: true,
handler () {
this.makeContentBody()
},
},
},
methods: {
makeContentBody () {
this.error = null
try {
const { body = '' } = this.options
return evaluatePrefilter(body, {
this.contentBody = evaluatePrefilter(body, {
record: this.record,
user: this.$auth.user || {},
recordID: (this.record || {}).recordID || NoID,
ownerID: (this.record || {}).ownedBy || NoID,
userID: (this.$auth.user || {}).userID || NoID,
})
} catch (e) {
this.error = this.getToastMessage(e)
}
},
},
}

View File

@ -11,6 +11,13 @@
<b-spinner />
</div>
<label
v-else-if="error"
class="text-primary p-3"
>
{{ error }}
</label>
<template v-else>
<div
v-for="(m, mi) in options.metrics"
@ -66,6 +73,8 @@ export default {
data () {
return {
processing: false,
error: undefined,
reports: [],
abortableRequests: [],
@ -148,6 +157,7 @@ export default {
* Pulls fresh data from the API
*/
async refresh () {
this.error = undefined
this.processing = true
try {
@ -196,7 +206,9 @@ export default {
setTimeout(() => {
this.processing = false
}, 300)
} catch {
} catch (e) {
this.error = this.getToastMessage(e)
setTimeout(() => {
this.processing = false
}, 300)

View File

@ -4,13 +4,29 @@
v-on="$listeners"
@refreshBlock="refresh"
>
<template
v-if="canAddRecord"
#toolbar
>
<div class="p-3 border-bottom">
<b-button
variant="primary"
size="lg"
@click.prevent="createNewRecord"
>
{{ $t('recordOrganizer.addNewRecord') }}
</b-button>
</div>
</template>
<template #default>
<div
<label
v-if="!isConfigured"
class="d-flex align-items-center justify-content-center h-100 p-3"
class="text-primary p-3"
>
{{ $t('recordOrganizer.notConfigured') }}
</div>
</label>
<div
v-else
class="h-100"
@ -30,7 +46,7 @@
#header
>
<div
class="small p-3 text-secondary"
class="small text-secondary"
>
{{ $t('recordOrganizer.noRecords') }}
</div>
@ -40,7 +56,7 @@
v-for="record in records"
:key="`${record.recordID}`"
body-class="rounded p-3"
class="record-item border border-light mb-3 grab"
class="record-item border border-light mb-3 grab shadow-sm"
@click="handleRecordClick(record)"
>
<h6
@ -88,22 +104,6 @@
</div>
</div>
</template>
<template
v-if="canAddRecord"
#footer
>
<div
class="p-2"
>
<b-button
variant="outline-light"
class="d-flex align-items-center justify-content-center text-primary border-0"
@click.prevent="createNewRecord"
>
{{ $t('recordOrganizer.addNewRecord') }}
</b-button>
</div>
</template>
</wrap>
</template>
@ -172,6 +172,19 @@ export default {
return this.options.moduleID
},
allFields () {
if (this.options.moduleID) {
return [
...this.roModule.fields,
...this.roModule.systemFields().map(sf => {
sf.label = this.$t(`field:system.${sf.name}`)
return sf
}),
]
}
return []
},
labelField () {
const { labelField } = this.options
@ -179,7 +192,7 @@ export default {
return undefined
}
return this.roModule.fields.find(f => f.name === labelField) || {}
return this.allFields.find(f => f.name === labelField) || {}
},
descriptionField () {
@ -189,7 +202,7 @@ export default {
return undefined
}
return this.roModule.fields.find(f => f.name === descriptionField) || {}
return this.allFields.find(f => f.name === descriptionField) || {}
},
positionField () {
@ -199,7 +212,7 @@ export default {
return undefined
}
return this.roModule.fields.find(f => f.name === positionField) || {}
return this.allFields.find(f => f.name === positionField) || {}
},
groupField () {
@ -209,7 +222,7 @@ export default {
return undefined
}
return this.roModule.fields.find(f => f.name === groupField) || {}
return this.allFields.find(f => f.name === groupField) || {}
},
canPull () {
@ -554,6 +567,6 @@ export default {
}
.record-item:hover {
box-shadow: 0 0.125rem 0.25rem rgb(0 0 0 / 8%) !important;
background-color: var(--light) !important;
}
</style>

View File

@ -75,9 +75,9 @@
>
<c-input-select
v-model="options.labelField"
:options="selectedModuleFields"
:options="allFields"
:reduce="o => o.name"
:get-option-label="fieldLabel"
:get-option-label="getFieldLabel"
:placeholder="$t('general.label.none')"
/>
<b-form-text>{{ $t('recordOrganizer.labelField.footnote') }}</b-form-text>
@ -94,9 +94,9 @@
>
<c-input-select
v-model="options.descriptionField"
:options="selectedModuleFields"
:options="allFields"
:reduce="o => o.name"
:get-option-label="descriptionLabel"
:get-option-label="getFieldLabel"
:placeholder="$t('general.label.none')"
/>
@ -118,7 +118,7 @@
v-model="options.groupField"
:options="groupFields"
:reduce="o => o.name"
:get-option-label="groupFieldLabel"
:get-option-label="getFieldLabel"
:placeholder="$t('general.label.none')"
/>
@ -271,7 +271,7 @@ export default {
},
groupFields () {
return this.selectedModuleFields.filter(({ isMulti }) => !isMulti)
return this.allFields.filter(({ isMulti }) => !isMulti)
},
group () {
@ -332,21 +332,13 @@ export default {
},
methods: {
getFieldLabel (option) {
return `${option.label || option.name} (${option.kind})`
},
setDefaultValues () {
this.mock = []
},
fieldLabel (option) {
return `${option.label || option.name} (${option.kind})`
},
descriptionLabel (option) {
return `${option.label || option.name} (${option.kind})`
},
groupFieldLabel (option) {
return `${option.label || option.name}`
},
},
}
</script>

View File

@ -36,6 +36,14 @@ export default {
this.$root.$bvToast.toast(msg, opt)
},
getToastMessage (err) {
if (err.message && err.message.startsWith('notification')) {
return this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
return err.message
},
toastErrorHandler (opt) {
if (typeof opt === 'string') {
opt = { prefix: opt }
@ -44,13 +52,13 @@ export default {
const { prefix, title } = opt
return (err = {}) => {
// only messages starting with 'notification:' or 'notification.' should be translated
if (err.message && err.message.startsWith('notification')) {
err.message = this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
err.message = this.getToastMessage(err)
// all other messages should be shown as they are
const msg = err.message ? `${prefix}: ${err.message}` : prefix
this.toastDanger(msg, title)
return err.message
}
},
},

View File

@ -2,7 +2,7 @@ export default {
methods: {
toastSuccess (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general:success')
title = this.$t('notification:general.success')
}
this.toast(message, { title, variant: 'success' })
@ -10,15 +10,23 @@ export default {
toastWarning (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general:warning')
title = this.$t('notification:general.warning')
}
this.toast(message, { title, variant: 'warning' })
},
toastInfo (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general.info')
}
this.toast(message, { title, variant: 'info' })
},
toastDanger (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general:error')
title = this.$t('notification:general.error')
}
this.toast(message, { title, variant: 'danger' })
@ -28,6 +36,14 @@ export default {
this.$root.$bvToast.toast(msg, opt)
},
getToastMessage (err) {
if (err.message && err.message.startsWith('notification')) {
return this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
return err.message
},
toastErrorHandler (opt) {
if (typeof opt === 'string') {
opt = { prefix: opt }
@ -36,13 +52,13 @@ export default {
const { prefix, title } = opt
return (err = {}) => {
// only messages starting with 'notification:' or 'notification.' should be translated
if (err.message && err.message.startsWith('notification')) {
err.message = this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
err.message = this.getToastMessage(err)
// all other messages should be shown as they are
const msg = err.message ? `${prefix}: ${err.message}` : prefix
this.toastDanger(msg, title)
return err.message
}
},
},

View File

@ -2,7 +2,7 @@ export default {
methods: {
toastSuccess (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general:success')
title = this.$t('notification:general.success')
}
this.toast(message, { title, variant: 'success' })
@ -10,15 +10,23 @@ export default {
toastWarning (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general:warning')
title = this.$t('notification:general.warning')
}
this.toast(message, { title, variant: 'warning' })
},
toastInfo (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general.info')
}
this.toast(message, { title, variant: 'info' })
},
toastDanger (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general:error')
title = this.$t('notification:general.error')
}
this.toast(message, { title, variant: 'danger' })
@ -28,6 +36,14 @@ export default {
this.$root.$bvToast.toast(msg, opt)
},
getToastMessage (err) {
if (err.message && err.message.startsWith('notification')) {
return this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
return err.message
},
toastErrorHandler (opt) {
if (typeof opt === 'string') {
opt = { prefix: opt }
@ -36,13 +52,13 @@ export default {
const { prefix, title } = opt
return (err = {}) => {
// only messages starting with 'notification:' or 'notification.' should be translated
if (err.message && err.message.startsWith('notification')) {
err.message = this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
err.message = this.getToastMessage(err)
// all other messages should be shown as they are
const msg = err.message ? `${prefix}: ${err.message}` : prefix
this.toastDanger(msg, title)
return err.message
}
},
},

View File

@ -2,7 +2,7 @@ export default {
methods: {
toastSuccess (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general:success')
title = this.$t('notification:general.success')
}
this.toast(message, { title, variant: 'success' })
@ -10,15 +10,23 @@ export default {
toastWarning (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general:warning')
title = this.$t('notification:general.warning')
}
this.toast(message, { title, variant: 'warning' })
},
toastInfo (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general.info')
}
this.toast(message, { title, variant: 'info' })
},
toastDanger (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general:error')
title = this.$t('notification:general.error')
}
this.toast(message, { title, variant: 'danger' })
@ -28,6 +36,14 @@ export default {
this.$root.$bvToast.toast(msg, opt)
},
getToastMessage (err) {
if (err.message && err.message.startsWith('notification')) {
return this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
return err.message
},
toastErrorHandler (opt) {
if (typeof opt === 'string') {
opt = { prefix: opt }
@ -36,13 +52,13 @@ export default {
const { prefix, title } = opt
return (err = {}) => {
// only messages starting with 'notification:' or 'notification.' should be translated
if (err.message && err.message.startsWith('notification')) {
err.message = this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
err.message = this.getToastMessage(err)
// all other messages should be shown as they are
const msg = err.message ? `${prefix}: ${err.message}` : prefix
this.toastDanger(msg, title)
return err.message
}
},
},

View File

@ -1,25 +1,49 @@
export default {
methods: {
toastSuccess (message, title = this.$t('notification:general.success')) {
toastSuccess (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general.success')
}
this.toast(message, { title, variant: 'success' })
},
toastWarning (message, title = this.$t('notification:general.warning')) {
toastWarning (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general.warning')
}
this.toast(message, { title, variant: 'warning' })
},
toastDanger (message, title = this.$t('notification:general.error')) {
this.toast(message, { title, variant: 'danger' })
toastInfo (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general.info')
}
this.toast(message, { title, variant: 'info' })
},
toastInfo (message, title = this.$t('notification:general.info')) {
this.toast(message, { title, variant: 'info' })
toastDanger (message, title = undefined) {
if (title === undefined) {
title = this.$t('notification:general.error')
}
this.toast(message, { title, variant: 'danger' })
},
toast (msg, opt = { variant: 'success' }) {
this.$root.$bvToast.toast(msg, opt)
},
getToastMessage (err) {
if (err.message && err.message.startsWith('notification')) {
return this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
return err.message
},
toastErrorHandler (opt) {
if (typeof opt === 'string') {
opt = { prefix: opt }
@ -28,13 +52,13 @@ export default {
const { prefix, title } = opt
return (err = {}) => {
// only messages starting with 'notification:' or 'notification.' should be translated
if (err.message && err.message.startsWith('notification')) {
err.message = this.$t(`notification:${err.message.substring('notification.'.length)}`)
}
err.message = this.getToastMessage(err)
// all other messages should be shown as they are
const msg = err.message ? `${prefix}: ${err.message}` : prefix
this.toastDanger(msg, title)
return err.message
}
},
},

View File

@ -586,7 +586,7 @@ recordList:
deleted: Show deleted records
existing: Show existing records
recordOrganizer:
onRecordClick: On record click
onRecordClick: Record display mode
openInSameTab: Open in the same tab
openInNewTab: Open in a new tab
openInModal: Open in a modal
@ -614,7 +614,7 @@ recordOrganizer:
preview:
label: 'Record Organizer block for module {{0}}. Label field {{1}}, Description field {{2}}. Value setting field: {{3}}, Sorted by position field: {{4}}.'
moduleNotSelected: Record Organizer module not selected
addNewRecord: + Add new record
addNewRecord: + Add
recordRevisions:
label: Record revisions