Files
yourpart3/frontend/src/components/SettingsWidget.vue
Torsten Schulz (local) 78d43e6859 Update color palette and styles across components for improved visual consistency
- Changed theme color in index.html to a brighter orange for better aesthetics.
- Introduced a modern color palette in styles.scss for enhanced readability and consistency.
- Updated various components (AppFooter, AppNavigation, DialogWidget, etc.) to utilize new color variables, ensuring a cohesive look throughout the application.
- Adjusted button styles and hover effects for improved user interaction feedback.
- Enhanced background colors and text colors for better contrast and visibility.
2026-01-22 12:22:05 +01:00

270 lines
11 KiB
Vue

<template>
<div class="settings-widget">
<table>
<tr v-for="setting in settings" :key="setting.id">
<td>
<InputStringWidget v-if="setting.datatype == 'string'"
:labelTr="`settings.personal.label.${setting.name}`"
:tooltipTr="setting.immutable ? $t('settings.immutable.tooltip') : `settings.personal.tooltip.${setting.name}`"
:value=setting.value
:disabled="setting.immutable && setting.value ? true : false"
:list="languagesList()" @input="handleInput(setting.id, $event)" />
<DateInputWidget v-else-if="setting.datatype == 'date'"
:labelTr="`settings.personal.label.${setting.name}`"
:tooltipTr="setting.immutable ? $t('settings.immutable.tooltip') : `settings.personal.tooltip.${setting.name}`"
:value=setting.value
:disabled="setting.immutable && setting.value ? true : false"
@input="handleInput(setting.id, $event)" />
<SelectDropdownWidget v-else-if="setting.datatype == 'singleselect'"
:labelTr="`settings.personal.label.${setting.name}`"
:tooltipTr="setting.immutable ? $t('settings.immutable.tooltip') : `settings.personal.tooltip.${setting.name}`"
:value=setting.value
:disabled="setting.immutable && setting.value ? true : false"
:list="getSettingOptions(setting.name, setting.options)"
@input="handleInput(setting.id, $event)" />
<InputNumberWidget v-else-if="setting.datatype == 'int'"
:labelTr="`settings.personal.label.${setting.name}`"
:tooltipTr="setting.immutable ? $t('settings.immutable.tooltip') : `settings.personal.tooltip.${setting.name}`"
:value="convertToInt(setting.value)"
:disabled="setting.immutable && setting.value ? true : false"
min="0" max="200" @input="handleInput(setting.id, $event)" />
<FloatInputWidget v-else-if="setting.datatype == 'float'"
:labelTr="`settings.personal.label.${setting.name}`"
:tooltipTr="setting.immutable ? $t('settings.immutable.tooltip') : `settings.personal.tooltip.${setting.name}`"
:value="convertToFloat(setting.value)"
:disabled="setting.immutable && setting.value ? true : false"
@input="handleInput(setting.id, $event)" />
<CheckboxWidget v-else-if="setting.datatype == 'bool'"
:labelTr="`settings.personal.label.${setting.name}`"
:tooltipTr="setting.immutable ? $t('settings.immutable.tooltip') : `settings.personal.tooltip.${setting.name}`"
:value="convertToBool(setting.value)"
:disabled="setting.immutable && setting.value ? true : false"
@input="handleInput(setting.id, $event)" />
<MultiselectWidget v-else-if="setting.datatype == 'multiselect'"
:labelTr="`settings.personal.label.${setting.name}`"
:tooltipTr="setting.immutable ? $t('settings.immutable.tooltip') : `settings.personal.tooltip.${setting.name}`"
:value="setting.value"
:disabled="setting.immutable && setting.value ? true : false"
:list="getSettingOptions(setting.name, setting.options)"
@input="handleInput(setting.id, $event)" />
<div v-else>{{ setting }}</div>
<span v-if="setting.unit">&nbsp;{{ setting.unit }}</span>
</td>
<td>
<select v-model="setting.visibility.id"
@change="handleVisibilityChange(setting.id, setting.visibility.id)">
<option v-for="visibility in possibleVisibilities" :key="visibility.id" :value="visibility.id">
{{ $t(`settings.visibility.${visibility.description}`) }}
</option>
</select>
</td>
<td v-if="setting.immutable && setting.value">
<button @click="openContactDialog" class="contact-button">
{{ $t('settings.immutable.supportContact') }}
</button>
</td>
</tr>
</table>
</div>
</template>
<script>
import apiClient from '@/utils/axios.js';
import { mapGetters } from 'vuex';
import InputStringWidget from '@/components/form/InputStringWidget.vue';
import DateInputWidget from '@/components/form/DateInputWidget.vue';
import SelectDropdownWidget from '@/components/form/SelectDropdownWidget.vue';
import InputNumberWidget from '@/components/form/InputNumberWidget.vue';
import FloatInputWidget from '@/components/form/FloatInputWidget.vue';
import CheckboxWidget from '@/components/form/CheckboxWidget.vue';
import MultiselectWidget from '@/components/form/MultiselectWidget.vue';
export default {
name: "SettingsWidget",
components: {
InputStringWidget,
DateInputWidget,
SelectDropdownWidget,
InputNumberWidget,
FloatInputWidget,
CheckboxWidget,
MultiselectWidget
},
props: {
settingsType: {
type: String,
required: true
}
},
data: {
settings: [],
possibleVisibilities: [],
},
computed: {
...mapGetters(['user']),
},
async mounted() {
await this.fetchSettings();
await this.fetchAccountData();
},
methods: {
async fetchSettings() {
if (this.user && this.user.id) {
try {
const visibilityResponse = await apiClient.get('/api/settings/visibilities');
this.possibleVisibilities = visibilityResponse.data;
const userid = this.user.id;
const response = await apiClient.post('/api/settings/filter', {
userid: userid,
type: this.settingsType
});
this.settings = response.data;
} catch (err) {
this.settings = [];
}
}
},
async fetchAccountData() {
if (this.user && this.user.id) {
try {
const response = await apiClient.post('/api/settings/account', { userId: this.user.id });
this.userEmail = response.data.email;
this.userUsername = response.data.username;
} catch (err) {
console.error('Error fetching account data:', err);
}
}
},
getSettingOptions(fieldName, options) {
return options.map((option) => {
return {
value: option.id,
captionTr: `settings.personal.${fieldName}.${option.value}`
}
});
},
async handleInput(settingId, value) {
if (['object', 'array'].includes(typeof value)) {
return;
}
// Prüfe ob das Setting unveränderlich ist
const setting = this.settings.find(s => s.id === settingId);
if (setting && setting.immutable && setting.value) {
alert(this.$t('settings.immutable.tooltip'));
return;
}
try {
const userid = this.user.id;
await apiClient.post('/api/settings/update', {
userid: userid,
settingId: settingId,
value: value
});
this.fetchSettings();
} catch (err) {
console.error('Error updating setting:', err);
if (err.response && err.response.data && err.response.data.error) {
alert(err.response.data.error);
}
}
},
languagesList() {
return [
{ value: 'en', captionTr: 'settings.personal.languages.en' },
{ value: 'de', captionTr: 'settings.personal.languages.de' },
];
},
convertToInt(value) {
const intValue = parseInt(value, 10);
return isNaN(intValue) ? 0 : intValue;
},
convertToFloat(value) {
const floatValue = parseFloat(value);
return isNaN(floatValue) ? 0.0 : floatValue;
},
convertToBool(value) {
if (value === 'true' || value === true) {
return true;
} else if (value === 'false' || value === false) {
return false;
} else {
return false;
}
},
async handleVisibilityChange(settingId, visibilityId) {
try {
await apiClient.post('/api/settings/update-visibility', {
userParamTypeId: settingId,
visibilityId: visibilityId
});
} catch (err) {
console.error('Error updating visibility:', err);
}
},
openContactDialog() {
// Erstelle vorgefertigte Daten für Support-Anfrage
const prefilledData = {
email: this.userEmail || "",
name: this.userUsername || "",
message: this.createSupportMessage(),
acceptDataSave: true
};
this.$root.$refs.contactDialog.open(prefilledData);
},
createSupportMessage() {
// Erstelle eine vorgefertigte Nachricht für unveränderliche Felder
const immutableFields = this.settings.filter(s => s.immutable && s.value);
if (immutableFields.length === 0) {
return this.$t('settings.immutable.supportMessage.general');
}
const fieldNames = immutableFields.map(field =>
this.$t(`settings.personal.label.${field.name}`)
).join(', ');
return this.$t('settings.immutable.supportMessage.specific', { fields: fieldNames });
},
},
data() {
return {
settings: [],
userEmail: "",
userUsername: "",
};
}
};
</script>
<style lang="scss" scoped>
label {
float: left;
}
.contact-button {
margin-left: 10px;
padding: 5px 12px;
cursor: pointer;
background: #FF6B35;
color: #000000;
border: 1px solid #FF6B35;
border-radius: 4px;
transition: background 0.05s;
border: 1px solid transparent;
font-size: 12px;
}
.contact-button:hover {
background: #FFF4F0;
color: #5D4037;
border: 1px solid #5D4037;
}
</style>