mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-09-06 15:14:13 +00:00
Backport of InvoiceShelf/InvoiceShelf#704 to 2.x. Fixes InvoiceShelf/docker#79. A fresh install using the shipped docker-compose.mysql.yml cannot get past the database step, because that compose file sets DB_CONNECTION=mariadb. getDatabaseEnvironment() switched on sqlite, pgsql and mysql with no arm for mariadb and no default, so it answered {"config":[]}. The wizard renders <component :is="database_connection">, which resolves to nothing, so the step came out blank — and nothing reached the log, because the app never errored, it just replied with nothing. Adds the mariadb arm plus a default, so an unrecognised driver is echoed back with server defaults rather than producing an unrenderable response. MariaDB is registered as an alias of the MySQL form, whose fields are identical, and offered in each driver picker. Tested against the original controller, where three of the new cases fail with "Failed asserting that null is identical to 'mariadb'".
156 lines
4.4 KiB
Vue
156 lines
4.4 KiB
Vue
<template>
|
|
<BaseWizardStep
|
|
:title="$t('wizard.database.database')"
|
|
:description="$t('wizard.database.desc')"
|
|
step-container="w-full p-8 mb-8 bg-white border border-gray-200 border-solid rounded md:w-full"
|
|
>
|
|
<component
|
|
:is="databaseData.database_connection"
|
|
:config-data="databaseData"
|
|
:is-saving="isSaving"
|
|
@on-change-driver="getDatabaseConfig"
|
|
@submit-data="next"
|
|
/>
|
|
</BaseWizardStep>
|
|
</template>
|
|
|
|
<script>
|
|
import { ref, computed, onMounted, watch } from 'vue'
|
|
import Mysql from './database/MysqlDatabase.vue'
|
|
import Pgsql from './database/PgsqlDatabase.vue'
|
|
import Sqlite from './database/SqliteDatabase.vue'
|
|
import { useNotificationStore } from '@/scripts/stores/notification'
|
|
import { useInstallationStore } from '@/scripts/admin/stores/installation'
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
export default {
|
|
components: {
|
|
Mysql,
|
|
Pgsql,
|
|
Sqlite,
|
|
// Resolved by <component :is="database_connection">. MariaDB takes the same
|
|
// fields as MySQL, so it reuses that form rather than duplicating it —
|
|
// without an entry here the step renders blank. See InvoiceShelf/docker#79.
|
|
Mariadb: Mysql,
|
|
},
|
|
|
|
emits: ['next'],
|
|
|
|
setup(props, { emit }) {
|
|
const database_connection = ref('mysql')
|
|
const isSaving = ref(false)
|
|
const { t } = useI18n()
|
|
const { global } = window.i18n
|
|
|
|
const notificationStore = useNotificationStore()
|
|
const installationStore = useInstallationStore()
|
|
|
|
const databaseData = computed(() => installationStore.currentDataBaseData)
|
|
|
|
watch(() => global.locale.value, (newLocale) => {
|
|
installationStore.currentDataBaseData.app_locale = newLocale
|
|
}, { immediate: true })
|
|
|
|
async function getDatabaseConfig(connection) {
|
|
let params = {}
|
|
if (connection) {
|
|
params.connection = connection
|
|
}
|
|
|
|
const res = await installationStore.fetchInstallationDatabase(params)
|
|
|
|
if (res.data.success) {
|
|
databaseData.value.database_connection =
|
|
res.data.config.database_connection
|
|
}
|
|
|
|
if (res.data.config.database_connection === 'sqlite') {
|
|
databaseData.value.database_name = res.data.config.database_name
|
|
} else {
|
|
databaseData.value.database_name = null
|
|
if (res.data.config.database_host) {
|
|
databaseData.value.database_hostname = res.data.config.database_host
|
|
}
|
|
if (res.data.config.database_port) {
|
|
databaseData.value.database_port = res.data.config.database_port
|
|
}
|
|
}
|
|
}
|
|
|
|
async function next(databaseData) {
|
|
isSaving.value = true
|
|
|
|
try {
|
|
let res = await installationStore.addInstallationDatabase(databaseData)
|
|
isSaving.value = false
|
|
|
|
if (res.data.success) {
|
|
await installationStore.addInstallationFinish()
|
|
|
|
emit('next', 3)
|
|
|
|
let language = {
|
|
profile_language: global.locale.value,
|
|
}
|
|
await installationStore.addInstallationLanguage(language)
|
|
|
|
|
|
notificationStore.showNotification({
|
|
type: 'success',
|
|
message: t('wizard.success.' + res.data.success),
|
|
})
|
|
|
|
return
|
|
} else if (res.data.error) {
|
|
if (res.data.requirement) {
|
|
notificationStore.showNotification({
|
|
type: 'error',
|
|
message: t('wizard.errors.' + res.data.error, {
|
|
version: res.data.requirement.minimum,
|
|
name: databaseData.value.database_connection,
|
|
}),
|
|
})
|
|
return
|
|
}
|
|
|
|
notificationStore.showNotification({
|
|
type: 'error',
|
|
message: t('wizard.errors.' + res.data.error),
|
|
})
|
|
} else if (res.data.errors) {
|
|
notificationStore.showNotification({
|
|
type: 'error',
|
|
message: res.data.errors[0],
|
|
})
|
|
} else if (res.data.error_message) {
|
|
notificationStore.showNotification({
|
|
type: 'error',
|
|
message: res.data.error_message,
|
|
})
|
|
}
|
|
} catch (e) {
|
|
notificationStore.showNotification({
|
|
type: 'error',
|
|
message: t('validation.something_went_wrong'),
|
|
})
|
|
isSaving.value = false
|
|
} finally {
|
|
isSaving.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
getDatabaseConfig()
|
|
})
|
|
|
|
return {
|
|
databaseData,
|
|
database_connection,
|
|
isSaving,
|
|
getDatabaseConfig,
|
|
next,
|
|
}
|
|
},
|
|
}
|
|
</script>
|