229 lines
5.1 KiB
Vue
229 lines
5.1 KiB
Vue
<template>
|
|
<q-page padding>
|
|
<q-card
|
|
bordered
|
|
flat
|
|
>
|
|
<q-card-section class="row items-center justify-between">
|
|
<div class="text-h4">
|
|
Application Settings
|
|
</div>
|
|
</q-card-section>
|
|
|
|
<q-separator />
|
|
|
|
<q-card-section v-if="loading">
|
|
<q-spinner-dots size="2em" /> Loading settings...
|
|
</q-card-section>
|
|
|
|
<q-card-section v-else-if="loadError">
|
|
<q-banner
|
|
inline-actions
|
|
class="text-white bg-red"
|
|
>
|
|
<template #avatar>
|
|
<q-icon name="error" />
|
|
</template>
|
|
{{ loadError }}
|
|
<template #action>
|
|
<q-btn
|
|
flat
|
|
color="white"
|
|
label="Retry"
|
|
@click="loadSettings"
|
|
/>
|
|
</template>
|
|
</q-banner>
|
|
</q-card-section>
|
|
|
|
<q-card-section v-else>
|
|
<q-form @submit.prevent="saveSettings">
|
|
<div
|
|
v-for="(group, groupName) in settings"
|
|
:key="groupName"
|
|
class="q-mb-lg"
|
|
>
|
|
<div class="text-h6 q-mb-sm">
|
|
{{ groupName }}
|
|
</div>
|
|
<div
|
|
v-for="setting in group"
|
|
:key="setting.key"
|
|
class="q-mb-md"
|
|
>
|
|
<q-input
|
|
v-model="settingValues[setting.key]"
|
|
:label="setting.name"
|
|
:type="setting.type || 'text'"
|
|
outlined
|
|
dense
|
|
/>
|
|
</div>
|
|
|
|
<q-separator class="q-my-md" />
|
|
</div>
|
|
|
|
<div class="row justify-end">
|
|
<q-btn
|
|
label="Save Settings"
|
|
type="submit"
|
|
color="primary"
|
|
:loading="saving"
|
|
:disable="loading || saving"
|
|
/>
|
|
</div>
|
|
</q-form>
|
|
</q-card-section>
|
|
</q-card>
|
|
</q-page>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { useQuasar } from 'quasar';
|
|
import { ref, onMounted } from 'vue';
|
|
import axios from 'boot/axios'; // Import axios
|
|
|
|
const $q = useQuasar();
|
|
|
|
// Define the structure of settings
|
|
const settings = ref({
|
|
General: [
|
|
{
|
|
name: 'Registration Token',
|
|
key: 'REGISTRATION_TOKEN',
|
|
}
|
|
],
|
|
Mantis: [
|
|
{
|
|
name: 'Mantis API Key',
|
|
key: 'MANTIS_API_KEY',
|
|
},
|
|
{
|
|
name: 'Mantis API Endpoint',
|
|
key: 'MANTIS_API_ENDPOINT'
|
|
},
|
|
{
|
|
name: 'Mantis Prompt',
|
|
key: 'MANTIS_PROMPT',
|
|
type: 'textarea'
|
|
}
|
|
],
|
|
Gemini: [
|
|
{
|
|
name: 'Gemini API Key',
|
|
key: 'GEMINI_API_KEY'
|
|
}
|
|
],
|
|
Database: [
|
|
{
|
|
name: 'MySQL Host',
|
|
key: 'MYSQL_HOST'
|
|
},
|
|
{
|
|
name: 'MySQL Port',
|
|
key: 'MYSQL_PORT'
|
|
},
|
|
{
|
|
name: 'MySQL User',
|
|
key: 'MYSQL_USER'
|
|
},
|
|
{
|
|
name: 'MySQL Password',
|
|
key: 'MYSQL_PASSWORD'
|
|
},
|
|
{
|
|
name: 'MySQL Database',
|
|
key: 'MYSQL_DATABASE'
|
|
}
|
|
]
|
|
});
|
|
|
|
// Reactive state for setting values, loading, saving, and errors
|
|
const settingValues = ref({});
|
|
const loading = ref(true);
|
|
const saving = ref(false);
|
|
const loadError = ref(null);
|
|
|
|
// Function to load settings from the server
|
|
async function loadSettings()
|
|
{
|
|
loading.value = true;
|
|
loadError.value = null;
|
|
settingValues.value = {}; // Reset values
|
|
const allSettingKeys = Object.values(settings.value).flat().map(s => s.key);
|
|
|
|
try
|
|
{
|
|
const responses = await Promise.all(allSettingKeys.map(key => axios.get(`/api/settings/${key}`, {
|
|
validateStatus: status => status === 200 || status === 404 // Accept 404 as a valid response
|
|
})));
|
|
responses.forEach((response, index) =>
|
|
{
|
|
const key = allSettingKeys[index];
|
|
//If the response status is 404, set the value to an empty string
|
|
if (response.status === 404)
|
|
{
|
|
settingValues.value[key] = '';
|
|
return;
|
|
}
|
|
settingValues.value[key] = response.data;
|
|
});
|
|
}
|
|
catch (err)
|
|
{
|
|
console.error('Error loading settings:', err);
|
|
loadError.value = err.response?.data?.error || 'Failed to load settings. Please check the console.';
|
|
$q.notify({
|
|
color: 'negative',
|
|
icon: 'error',
|
|
message: loadError.value,
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
loading.value = false;
|
|
}
|
|
}
|
|
|
|
// Function to save settings to the server
|
|
async function saveSettings()
|
|
{
|
|
saving.value = true;
|
|
loadError.value = null; // Clear previous load errors
|
|
|
|
const allSettingKeys = Object.keys(settingValues.value);
|
|
const requests = allSettingKeys.map(key =>
|
|
axios.put(`/api/settings/${key}`, { value: settingValues.value[key] })
|
|
);
|
|
|
|
try
|
|
{
|
|
await Promise.all(requests);
|
|
$q.notify({
|
|
color: 'positive',
|
|
icon: 'check_circle',
|
|
message: 'Settings saved successfully!',
|
|
});
|
|
}
|
|
catch (err)
|
|
{
|
|
console.error('Error saving settings:', err);
|
|
const errorMessage = err.response?.data?.error || 'Failed to save settings. Please try again.';
|
|
$q.notify({
|
|
color: 'negative',
|
|
icon: 'error',
|
|
message: errorMessage,
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
saving.value = false;
|
|
}
|
|
}
|
|
|
|
// Load settings when the component is mounted
|
|
onMounted(() =>
|
|
{
|
|
loadSettings();
|
|
});
|
|
</script>
|