Änderungen: - Implementierung von neuen Methoden `getAccountSettings` und `setAccountSettings` im `SettingsService`, um Benutzerkontoeinstellungen zu verwalten. - Anpassung der E-Mail-Verschlüsselung im `User`-Modell zur Verwendung von Buffer für die Speicherung und zur Verbesserung der Fehlerbehandlung bei der Entschlüsselung. - Hinzufügung eines neuen `immutable`-Feldes im `UserParamType`-Modell, um unveränderliche Einstellungen zu kennzeichnen. - Anpassungen in den Frontend-Komponenten zur Berücksichtigung von unveränderlichen Feldern und zur Verbesserung der Benutzeroberfläche. Diese Anpassungen verbessern die Sicherheit der Benutzerdaten und erweitern die Funktionalität der Kontoeinstellungen.
145 lines
3.2 KiB
Vue
145 lines
3.2 KiB
Vue
<template>
|
|
<div class="dropdown-container">
|
|
<div class="dropdown-header" @click="disabled ? null : toggleDropdown" :class="{ disabled: disabled }">
|
|
<table>
|
|
<tr>
|
|
<td v-for="(column, index) in columns" :key="column.field">
|
|
{{ selected ? selected[column.field] : index === 0 ? placeholder : '' }}
|
|
</td>
|
|
<td>{{ isOpen ? '▲' : '▼' }}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div v-if="isOpen" class="dropdown-list">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th v-for="column in columns" :key="column.field">{{ column.label }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="option in options" :key="option.id" @click="selectOption(option)"
|
|
:class="{ selected: option.id === selected?.id }">
|
|
<td v-for="column in columns" :key="column.field">{{ option[column.field] }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: "FormattedDropdown",
|
|
props: {
|
|
options: {
|
|
type: Array,
|
|
required: true,
|
|
},
|
|
columns: {
|
|
type: Array,
|
|
required: true,
|
|
},
|
|
modelValue: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
default: "Select an option",
|
|
},
|
|
disabled: {
|
|
type: Boolean,
|
|
required: false,
|
|
default: false
|
|
},
|
|
},
|
|
emits: ['update:modelValue'],
|
|
data() {
|
|
return {
|
|
isOpen: false,
|
|
selected: this.modelValue,
|
|
};
|
|
},
|
|
watch: {
|
|
modelValue(newVal) {
|
|
this.selected = newVal;
|
|
},
|
|
},
|
|
methods: {
|
|
toggleDropdown() {
|
|
if (this.disabled) return;
|
|
this.isOpen = !this.isOpen;
|
|
},
|
|
selectOption(option) {
|
|
this.selected = option;
|
|
this.$emit("update:modelValue", option);
|
|
this.isOpen = false;
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.dropdown-container {
|
|
position: relative;
|
|
display: inline-block;
|
|
}
|
|
|
|
.dropdown-header {
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 2px 3px;
|
|
background-color: #fff;
|
|
}
|
|
|
|
.dropdown-list {
|
|
position: absolute;
|
|
top: 100%;
|
|
left: 0;
|
|
background: white;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
z-index: 50;
|
|
width: auto;
|
|
min-width: 100%;
|
|
max-width: 90vw;
|
|
max-height: 300px;
|
|
overflow-y: auto;
|
|
white-space: nowrap;
|
|
padding: 2px 3px;
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
th,
|
|
td {
|
|
text-align: left;
|
|
padding: 4px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
tr.selected {
|
|
background-color: #f0f0f0;
|
|
font-weight: bold;
|
|
}
|
|
|
|
tr:hover {
|
|
background-color: #e0e0e0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.dropdown-header.disabled {
|
|
background-color: #f5f5f5;
|
|
color: #999;
|
|
cursor: not-allowed;
|
|
}
|
|
</style>
|