Skip to content
Snippets Groups Projects
Verified Commit c893416b authored by Martin Weise's avatar Martin Weise
Browse files

Fixed the error messaging from the backend

parent 0d5559dd
Branches
Tags
1 merge request!262Dev
......@@ -136,6 +136,7 @@
<script>
import BlobUpload from '@/components/table/BlobUpload'
import {localizedMessage} from '@/utils'
export default {
components: {
......@@ -311,9 +312,7 @@ export default {
this.$toast.success(this.$t('success.data.add'))
})
.catch((error) => {
const { code, message } = error.response.data
console.error('Failed to insert tuple', error)
this.$toast.error(this.$t(code) + ' ' + message)
this.$toast.error(localizedMessage(this.$t, error, null))
})
},
onUpload (event) {
......
......@@ -121,6 +121,7 @@
<script>
import { useCacheStore } from '@/stores/cache'
import {localizedMessage} from '@/utils'
export default {
props: {
......
......@@ -11,11 +11,11 @@
<v-spacer />
<v-btn
v-if="user"
:disabled="!valid || isExecuted"
:disabled="!canExecute"
color="secondary"
variant="flat"
:prepend-icon="$vuetify.display.lgAndUp ? 'mdi-run' : null"
:text="$t('navigation.continue')"
:text="$t('navigation.create')"
@click="execute" />
</v-toolbar>
<v-toolbar flat>
......@@ -35,13 +35,10 @@
rounded="0"
variant="flat">
<v-card-text>
<v-window v-model="tabs">
<v-window-item
value="0">
<v-form
ref="formView"
v-model="validView"
@submit.prevent="preventView">
v-model="valid"
@submit.prevent="prevent">
<v-row
v-if="isView"
class="mt-1"
......@@ -74,12 +71,24 @@
<v-row
v-if="isView"
dense>
<v-col cols="6">
<v-switch
<v-col md="8">
<v-select
v-model="view.is_public"
:label="view.is_public ? $t('toolbars.database.public') : $t('toolbars.database.private')" />
:items="visibilities"
persistent-hint
:variant="inputVariant"
required
clearable
:label="$t('pages.view.subpages.create.visibility.label')"
:hint="$t('pages.view.subpages.create.visibility.hint')"
:rules="[v => !!v || $t('validation.required')]" />
</v-col>
</v-row>
<v-window
class="mt-4"
v-model="tabs">
<v-window-item
value="0">
<v-row dense>
<v-col md="4">
<v-select
......@@ -89,6 +98,7 @@
item-title="name"
return-object
persistent-hint
clearable
:variant="inputVariant"
:label="$t('pages.view.subpages.create.table.label')"
:hint="$t('pages.view.subpages.create.table.hint')"
......@@ -101,6 +111,7 @@
:disabled="!table || isExecuted"
:items="columns"
persistent-hint
clearable
:variant="inputVariant"
:label="$t('pages.view.subpages.create.columns.label')"
:hint="$t('pages.view.subpages.create.columns.hint')"
......@@ -209,7 +220,8 @@
</div>
<v-row
dense>
<v-col v-text="$t('pages.subset.subpages.create.subtitle')" />
<v-col
v-text="$t('pages.subset.subpages.create.generated')" />
</v-row>
<v-row
id="query-raw"
......@@ -221,7 +233,6 @@
class="mt-2" />
</v-col>
</v-row>
</v-form>
</v-window-item>
<v-window-item
value="1">
......@@ -249,6 +260,7 @@
</v-row>
</v-window-item>
</v-window>
</v-form>
</v-card-text>
</v-card>
<Results
......@@ -265,6 +277,7 @@ import Results from '@/components/subset/Results'
import { useCacheStore } from '@/stores/cache'
import { useUserStore } from '@/stores/user'
import { format } from 'sql-formatter'
import { localizedMessage } from '@/utils'
export default {
components: {
......@@ -286,6 +299,10 @@ export default {
views: [],
timestamp: null,
executeDifferentTimestamp: false,
visibilities: [
{ title: this.$t('toolbars.database.public'), value: true },
{ title: this.$t('toolbars.database.private'), value: false },
],
operators: [
'=',
'<',
......@@ -330,8 +347,7 @@ export default {
],
tableDetails: null,
resultId: null,
validView: false,
validSubset: false,
valid: false,
errorKeyword: null,
query: {
raw: null,
......@@ -402,7 +418,7 @@ export default {
},
valid () {
if (this.isView) {
return this.validView && !this.hasUnsupported
return this.valid && !this.hasUnsupported
}
return this.sql.length > 0 && !this.hasUnsupported
},
......@@ -425,6 +441,12 @@ export default {
}
return false
},
canExecute () {
if (this.isView) {
return this.view.name !== null && this.view.is_public !== null && this.view.query !== null
}
return this.valid
},
inputVariant () {
const runtimeConfig = useRuntimeConfig()
return this.$vuetify.theme.global.name.toLowerCase().endsWith('contrast') ? runtimeConfig.public.variant.input.contrast : runtimeConfig.public.variant.input.normal
......@@ -450,7 +472,7 @@ export default {
this.selectTable()
},
methods: {
preventView () {
prevent () {
this.$refs.formView.validate()
},
validViewName (name) {
......@@ -491,8 +513,7 @@ export default {
this.$router.push(`/database/${this.$route.params.database_id}/subset/${subset.id}/data`)
})
.catch((error) => {
const { code } = error.response.data
this.$toast.error(this.$t(code))
this.$toast.error(localizedMessage(this.$t, error, null))
})
},
createView () {
......@@ -508,8 +529,7 @@ export default {
this.$router.push(`/database/${this.$route.params.database_id}/view/${view.id}/data`)
})
.catch((error) => {
console.error('Failed to create view', error)
this.$toast.error(this.$t('error.view.create'))
this.$toast.error(localizedMessage(this.$t, error, this.$t('error.view.create')))
this.loadingQuery = false
})
.finally(() => {
......@@ -527,6 +547,9 @@ export default {
return
}
this.query.raw = raw
if (this.isView) {
this.view.query = raw
}
this.query.formatted = formatted
},
canAdd (idx) {
......@@ -560,6 +583,9 @@ export default {
const { raw } = event
if (raw) {
this.query.raw = raw
if (this.isView) {
this.view.query = raw
}
this.query.formatted = format(raw, {
language: 'mysql',
keywordCase: 'upper'
......
......@@ -9,6 +9,8 @@
</div>
</template>
<script>
import {localizedMessage} from '@/utils'
export default {
props: {
column: {
......@@ -40,8 +42,7 @@ export default {
this.$emit('blob', { column: this.column, s3key: this.value })
})
.catch((error) => {
console.error(`Failed to set column value: ${this.column.internal_name}`, error)
this.$toast.error(this.$t('error.data.value') + ' ' + this.column.internal_name)
this.$toast.error(localizedMessage(this.$t, error, null))
})
}
}
......
......@@ -244,7 +244,7 @@
</template>
<script>
import { isNonNegativeInteger } from '@/utils'
import {isNonNegativeInteger, localizedMessage} from '@/utils'
import { useCacheStore } from '@/stores/cache'
export default {
......@@ -418,7 +418,6 @@ export default {
this.analyse(s3key)
})
.catch((error) => {
console.error('Failed to upload', error)
this.$toast.error(this.$t('error.upload.dataset'))
this.loading = false
})
......@@ -459,7 +458,7 @@ export default {
this.$emit('analyse', {columns: this.columns, filename, line_termination})
})
.catch((error) => {
console.error('Failed to analyse dataset', error)
this.$toast.error(localizedMessage(this.$t, error, null))
this.loading = false
})
.finally(() => {
......
......@@ -44,6 +44,7 @@
<script>
import { useUserStore } from '@/stores/user'
import { useCacheStore } from '@/stores/cache'
import {localizedMessage} from '@/utils'
export default {
components: {
......@@ -132,8 +133,7 @@ export default {
this.$router.push(`/database/${this.$route.params.database_id}/view`)
})
.catch((error) => {
const { code, message } = error.response.data
this.$toast.error(this.$t(code) + ' ' + message)
this.$toast.error(localizedMessage(this.$t, error, null))
})
.finally(() => {
this.loadingDelete = false
......
......@@ -833,7 +833,8 @@
"hint": "Required."
},
"visibility": {
"warn": "The view metadata, i.e. view name, query, will still be public. The data however will only be visible to people with at least read access to this database."
"label": "Data Visibility",
"hint": "Required. When private, the view metadata will still be public but the data will only be visible to people with at least read access to this database."
}
}
}
......
......@@ -105,7 +105,7 @@
import TimeTravel from '@/components/dialogs/TimeTravel'
import TimeDrift from '@/components/TimeDrift'
import TableToolbar from '@/components/table/TableToolbar'
import { formatTimestampUTC, formatDateUTC, formatTimestamp } from '@/utils'
import {formatTimestampUTC, formatDateUTC, formatTimestamp, localizedMessage} from '@/utils'
import { useUserStore } from '@/stores/user'
import { useCacheStore } from '@/stores/cache'
import EditTuple from '@/components/dialogs/EditTuple'
......@@ -398,9 +398,7 @@ export default {
this.dateColumns = this.table.columns.filter(c => (c.column_type === 'date' || c.column_type === 'timestamp'))
console.debug('date columns are', this.dateColumns)
} catch (error) {
console.error('Failed to map table details', error)
const { message } = error.response
this.$toast.error('Failed to map table details: ' + message)
this.$toast.error(localizedMessage(this.$t, error, 'Failed to map table details'))
}
this.loading = false
},
......@@ -430,7 +428,7 @@ export default {
})
})
.catch((error) => {
console.error('load data resulted in error', error)
this.$toast.error(localizedMessage(this.$t, error, 'Failed to load data'))
this.error = true
})
.finally(() => {
......
......@@ -80,6 +80,7 @@
<script>
import {useUserStore} from '@/stores/user'
import {localizedMessage} from '@/utils'
export default {
data() {
......@@ -141,7 +142,7 @@ export default {
if (status === 401) {
this.$toast.error(this.$t('error.user.credentials'))
} else {
this.$toast.error(`Failed to login: ${error}`)
this.$toast.error(localizedMessage(this.$t, error, null))
}
this.loading = false
})
......
......@@ -4,7 +4,7 @@ import 'vue-toast-notification/dist/theme-default.css';
const config: any = {
position: 'top-right',
duration: 6000,
dismissible: true
dismissible: false /* allow copy of error message */
}
export default defineNuxtPlugin((app) => {
......
import {format} from 'date-fns'
import moment from 'moment'
import type {AxiosError} from 'axios'
export function notEmpty(str: string) {
if (!str) {
......@@ -8,6 +10,14 @@ export function notEmpty (str: string) {
return str.trim().length > 0
}
export function localizedMessage(t: any, error: AxiosError<ApiErrorDto>, message: string | null): string {
if (error.response && error.response.data) {
const data = error.response.data as ApiErrorDto
return `${t(data.code)}: ${data.message}`
}
return `${error.message}: ${message}`
}
export function notFile(files: [File[]]) {
if (!files) {
return false
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment