Mitarbeiter-Formular: Standort nach „Allgemein", Login/Rechte als eigenes Modal

- Standort (und Firma-Zuordnung beim Anlegen) in den Tab „Allgemein" verschoben
- „Zugang & NFC" zeigt nur noch NFC-Link + Button „Login & Rechte verwalten",
  der ein separates Modal öffnet → klar erkennbar, dass Login extra aktiviert
  wird (Passwort = Login an)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Thomas Peterson 2026-06-09 20:23:14 +02:00
parent 456decb195
commit d6370724a0

View File

@ -131,6 +131,7 @@ async function saveAccess(e: Employee) {
accessForm.value.password = ''
await load()
editing.value = employees.value.find((x) => x.id === e.id) ?? null
showAccess.value = false
} catch (err: unknown) {
const ex = err as { response?: { data?: { error?: string; detail?: string } } }
alert(ex?.response?.data?.error ?? ex?.response?.data?.detail ?? 'Speichern fehlgeschlagen.')
@ -141,11 +142,20 @@ async function removeLogin(e: Employee) {
await client.delete(`/employees/${e.id}/login`)
await load()
editing.value = employees.value.find((x) => x.id === e.id) ?? null
showAccess.value = false
}
// --- Import ---
const showImport = ref(false)
// --- Login & Rechte (eigenes Modal) ---
const showAccess = ref(false)
function openAccess() {
if (!editing.value) return
accessForm.value = { group: groupOf(editing.value), password: '' }
showAccess.value = true
}
// --- Anlegen / Bearbeiten ---
const showForm = ref(false)
const saving = ref(false)
@ -431,6 +441,19 @@ onMounted(load)
<div class="field"><label>Position</label><input class="input" v-model="form.position" /></div>
<div class="field"><label>Abteilung</label><input class="input" v-model="form.department" /></div>
</div>
<div class="field" v-if="!editing && (auth.isResellerAdmin || auth.isPlatformAdmin)">
<label>Firma</label>
<select class="input" v-model="form.company">
<option v-for="c in companies" :key="c['@id']" :value="c['@id']">{{ c.name }}</option>
</select>
</div>
<div class="field">
<label>Standort</label>
<select class="input" v-model="form.location">
<option value=""> kein </option>
<option v-for="l in availableLocations" :key="l['@id']" :value="l['@id']">{{ l.name }}</option>
</select>
</div>
<div class="field"><label>Slug (URL)</label><input class="input" v-model="form.slug" :placeholder="slugify(form.firstName + '-' + form.lastName)" /></div>
<div class="field"><label>Über mich</label><textarea class="input" rows="3" v-model="form.bio"></textarea></div>
</div>
@ -503,22 +526,6 @@ onMounted(load)
<!-- Zugang & NFC -->
<div v-show="activeTab === 'zugang'" class="panel">
<div class="grid2" v-if="!editing && (auth.isResellerAdmin || auth.isPlatformAdmin)">
<div class="field">
<label>Firma</label>
<select class="input" v-model="form.company">
<option v-for="c in companies" :key="c['@id']" :value="c['@id']">{{ c.name }}</option>
</select>
</div>
</div>
<div class="field">
<label>Standort</label>
<select class="input" v-model="form.location">
<option value=""> kein </option>
<option v-for="l in availableLocations" :key="l['@id']" :value="l['@id']">{{ l.name }}</option>
</select>
</div>
<div v-if="editing && editing.shortCode" class="nfc">
<div class="nfc__label">NFC / QR-Link (stabil auf Tags schreiben)</div>
<div class="nfc__row">
@ -528,26 +535,14 @@ onMounted(load)
</div>
<div v-if="editing && canManageUsers" class="login-box">
<div class="nfc__label">Rechtegruppe & Login</div>
<div class="grid2">
<div class="field">
<label>Rechtegruppe</label>
<select class="input" v-model="accessForm.group">
<option v-for="g in assignableGroups" :key="g" :value="g">{{ GROUP_LABEL[g] ?? g }}</option>
</select>
<div class="nfc__label">Login & Rechtegruppe</div>
<p class="muted small" style="margin:.2rem 0 .7rem">
Aktuell: <strong>{{ GROUP_LABEL[groupOf(editing)] }}</strong> · Login
{{ editing.login ? 'aktiv 🔑' : 'inaktiv' }}. Der Login wird separat über ein Passwort aktiviert.
</p>
<button type="button" class="btn btn-soft btn-sm" @click="openAccess">Login &amp; Rechte verwalten </button>
</div>
<div class="field">
<label>{{ editing.login ? 'Neues Passwort (optional)' : 'Passwort (für Login)' }}</label>
<input class="input" type="password" v-model="accessForm.password" minlength="6" placeholder="leer = kein Login" />
</div>
</div>
<div class="access-actions">
<button type="button" class="btn btn-soft btn-sm" @click="saveAccess(editing)">Rechtegruppe übernehmen</button>
<button v-if="editing.login" type="button" class="btn btn-ghost btn-sm" @click="removeLogin(editing)">Login entziehen</button>
<span class="muted small">Aktuell: {{ GROUP_LABEL[groupOf(editing)] }} · Login {{ editing.login ? 'aktiv' : 'inaktiv' }}</span>
</div>
</div>
<p v-else-if="!editing" class="muted small">Login & Rechtegruppe nach dem Anlegen vergeben.</p>
<p v-else-if="!editing" class="muted small">Login &amp; Rechtegruppe nach dem Anlegen vergeben.</p>
</div>
<p v-if="error" class="error">{{ error }}</p>
@ -558,6 +553,30 @@ onMounted(load)
</form>
</Modal>
<Modal v-if="showAccess && editing" :title="`Login & Rechte ${editing.firstName} ${editing.lastName}`" @close="showAccess = false">
<p class="muted" style="margin-top:0">
Mit einem <strong>Passwort</strong> wird der Login aktiviert. Ohne Passwort bleibt der Eintrag ein reines
Profil (Visitenkarte) ohne Anmeldung.
</p>
<div class="field">
<label>Rechtegruppe</label>
<select class="input" v-model="accessForm.group">
<option v-for="g in assignableGroups" :key="g" :value="g">{{ GROUP_LABEL[g] ?? g }}</option>
</select>
</div>
<div class="field">
<label>{{ editing.login ? 'Neues Passwort (optional)' : 'Passwort (aktiviert Login)' }}</label>
<input class="input" type="password" v-model="accessForm.password" minlength="6" placeholder="leer = kein Login" />
</div>
<p class="muted small">Aktuell: {{ GROUP_LABEL[groupOf(editing)] }} · Login {{ editing.login ? 'aktiv' : 'inaktiv' }}</p>
<div class="actions">
<button v-if="editing.login" type="button" class="btn btn-ghost" @click="removeLogin(editing)">Login entziehen</button>
<span style="flex:1"></span>
<button type="button" class="btn btn-ghost" @click="showAccess = false">Schließen</button>
<button type="button" class="btn btn-primary" @click="saveAccess(editing)">Speichern</button>
</div>
</Modal>
<EmployeeImport v-if="showImport" @close="showImport = false" @done="load" />
</section>
</template>