chore: update lockfile and commit all pending release fixes
Some checks failed
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 1s
Monorepo Pipeline / 🧪 Test (push) Successful in 2m2s
Monorepo Pipeline / 🧹 Lint (push) Successful in 2m14s
Monorepo Pipeline / 🚀 Release (push) Has been cancelled
Monorepo Pipeline / 🐳 Build Directus (Base) (push) Has been cancelled
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been cancelled
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been cancelled
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been cancelled
Monorepo Pipeline / 🏗️ Build (push) Has been cancelled
Some checks failed
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 1s
Monorepo Pipeline / 🧪 Test (push) Successful in 2m2s
Monorepo Pipeline / 🧹 Lint (push) Successful in 2m14s
Monorepo Pipeline / 🚀 Release (push) Has been cancelled
Monorepo Pipeline / 🐳 Build Directus (Base) (push) Has been cancelled
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been cancelled
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been cancelled
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been cancelled
Monorepo Pipeline / 🏗️ Build (push) Has been cancelled
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
<template>
|
||||
<private-view title="People Manager">
|
||||
<MintelManagerLayout
|
||||
title="People Manager"
|
||||
:item-title="`${selectedPerson?.first_name} ${selectedPerson?.last_name}` || 'Person wählen'"
|
||||
:is-empty="!selectedPerson"
|
||||
empty-title="Person auswählen"
|
||||
empty-icon="person"
|
||||
:notice="feedback"
|
||||
@close-notice="feedback = null"
|
||||
>
|
||||
<template #navigation>
|
||||
<v-list nav>
|
||||
<v-list-item @click="openCreateDrawer" clickable>
|
||||
@@ -17,7 +25,7 @@
|
||||
v-for="person in people"
|
||||
:key="person.id"
|
||||
:active="selectedPerson?.id === person.id"
|
||||
class="person-item"
|
||||
class="nav-item"
|
||||
clickable
|
||||
@click="selectPerson(person)"
|
||||
>
|
||||
@@ -31,43 +39,42 @@
|
||||
</v-list>
|
||||
</template>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<v-notice v-if="feedback" :type="feedback.type" @close="feedback = null" dismissible>
|
||||
{{ feedback.message }}
|
||||
</v-notice>
|
||||
<template #subtitle>
|
||||
<template v-if="selectedPerson">
|
||||
{{ getCompanyName(selectedPerson) }}
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<div v-if="!selectedPerson" class="empty-state">
|
||||
<v-info title="Person auswählen" icon="person" center>
|
||||
Wähle eine Person in der Navigation aus oder
|
||||
<v-button x-small @click="openCreateDrawer">erstelle eine neue Person</v-button>.
|
||||
</v-info>
|
||||
<template #actions>
|
||||
<v-button secondary rounded icon v-tooltip.bottom="'Person bearbeiten'" @click="openEditDrawer">
|
||||
<v-icon name="edit" />
|
||||
</v-button>
|
||||
<v-button danger rounded icon v-tooltip.bottom="'Person löschen'" @click="deletePerson">
|
||||
<v-icon name="delete" />
|
||||
</v-button>
|
||||
</template>
|
||||
|
||||
<template #empty-state>
|
||||
Wähle eine Person in der Navigation aus oder
|
||||
<v-button x-small @click="openCreateDrawer">erstelle eine neue Person</v-button>.
|
||||
</template>
|
||||
|
||||
<div v-if="selectedPerson" class="details-grid">
|
||||
<div class="detail-item">
|
||||
<span class="label">Vorname</span>
|
||||
<p class="value">{{ selectedPerson.first_name }}</p>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<header class="header">
|
||||
<div class="header-left">
|
||||
<h1 class="title">{{ selectedPerson.first_name }} {{ selectedPerson.last_name }}</h1>
|
||||
<p class="subtitle">{{ getCompanyName(selectedPerson) }}</p>
|
||||
</div>
|
||||
|
||||
<div class="header-right">
|
||||
<v-button secondary rounded icon v-tooltip="'Person bearbeiten'" @click="openEditDrawer">
|
||||
<v-icon name="edit" />
|
||||
</v-button>
|
||||
<v-button danger rounded icon v-tooltip="'Person löschen'" @click="deletePerson">
|
||||
<v-icon name="delete" />
|
||||
</v-button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<v-divider />
|
||||
|
||||
<div class="details-grid">
|
||||
<div class="detail-item">
|
||||
<span class="label">Name</span>
|
||||
<p class="value">{{ selectedPerson.first_name }} {{ selectedPerson.last_name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="label">Nachname</span>
|
||||
<p class="value">{{ selectedPerson.last_name }}</p>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="label">E-Mail</span>
|
||||
<p class="value">{{ selectedPerson.email || '---' }}</p>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="label">Organisation</span>
|
||||
<p class="value">{{ getCompanyName(selectedPerson) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -89,18 +96,20 @@
|
||||
<span class="label">Nachname</span>
|
||||
<v-input v-model="form.last_name" placeholder="Nachname" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">E-Mail</span>
|
||||
<v-input v-model="form.email" placeholder="E-Mail Adresse" type="email" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">Zentrale Firma</span>
|
||||
<v-select
|
||||
<MintelSelect
|
||||
v-model="form.company"
|
||||
:items="companyOptions"
|
||||
placeholder="Bestehende Firma auswählen..."
|
||||
allow-add
|
||||
@add="openQuickAdd('company')"
|
||||
/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label">Firma (Legacy / Neu)</span>
|
||||
<v-input v-model="form.company_name" placeholder="z.B. Mintel" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="drawer-actions">
|
||||
@@ -111,12 +120,13 @@
|
||||
</div>
|
||||
</template>
|
||||
</v-drawer>
|
||||
</private-view>
|
||||
</MintelManagerLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
import { ref, onMounted, computed, nextTick } from 'vue';
|
||||
import { useApi } from '@directus/extensions-sdk';
|
||||
import { MintelManagerLayout, MintelSelect } from '@mintel/directus-extension-toolkit';
|
||||
|
||||
const api = useApi();
|
||||
const people = ref([]);
|
||||
@@ -131,8 +141,8 @@ const form = ref({
|
||||
id: null,
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
company: null,
|
||||
company_name: ''
|
||||
email: '',
|
||||
company: null
|
||||
});
|
||||
|
||||
const companyOptions = computed(() =>
|
||||
@@ -145,9 +155,9 @@ const companyOptions = computed(() =>
|
||||
function getCompanyName(person: any) {
|
||||
if (!person) return '---';
|
||||
if (person.company) {
|
||||
return typeof person.company === 'object' ? person.company.name : (companies.value.find(c => c.id === person.company)?.name || person.company_name);
|
||||
return typeof person.company === 'object' ? person.company.name : (companies.value.find(c => c.id === person.company)?.name || 'Unbekannte Firma');
|
||||
}
|
||||
return person.company_name || '---';
|
||||
return '---';
|
||||
}
|
||||
|
||||
async function fetchData() {
|
||||
@@ -180,8 +190,8 @@ function openCreateDrawer() {
|
||||
id: null,
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
company: null,
|
||||
company_name: ''
|
||||
email: '',
|
||||
company: null
|
||||
};
|
||||
drawerActive.value = true;
|
||||
}
|
||||
@@ -189,23 +199,12 @@ function openCreateDrawer() {
|
||||
function openEditDrawer() {
|
||||
isEditing.value = true;
|
||||
const person = selectedPerson.value;
|
||||
let companyId = null;
|
||||
let companyName = person.company_name || '';
|
||||
|
||||
if (person.company) {
|
||||
if (typeof person.company === 'object') {
|
||||
companyId = person.company.id;
|
||||
} else if (person.company.length === 36) { // Assume UUID
|
||||
companyId = person.company;
|
||||
} else {
|
||||
companyName = person.company;
|
||||
}
|
||||
}
|
||||
|
||||
form.value = {
|
||||
...person,
|
||||
company: companyId,
|
||||
company_name: companyName
|
||||
id: person.id,
|
||||
first_name: person.first_name,
|
||||
last_name: person.last_name,
|
||||
email: person.email,
|
||||
company: person.company?.id || person.company
|
||||
};
|
||||
drawerActive.value = true;
|
||||
}
|
||||
@@ -218,17 +217,20 @@ async function savePerson() {
|
||||
|
||||
saving.value = true;
|
||||
try {
|
||||
let updatedItem;
|
||||
if (isEditing.value) {
|
||||
await api.patch(`/items/people/${form.value.id}`, form.value);
|
||||
const res = await api.patch(`/items/people/${form.value.id}`, form.value);
|
||||
updatedItem = res.data.data;
|
||||
feedback.value = { type: 'success', message: 'Person aktualisiert!' };
|
||||
} else {
|
||||
await api.post('/items/people', form.value);
|
||||
const res = await api.post('/items/people', form.value);
|
||||
updatedItem = res.data.data;
|
||||
feedback.value = { type: 'success', message: 'Person angelegt!' };
|
||||
}
|
||||
drawerActive.value = false;
|
||||
await fetchData();
|
||||
if (isEditing.value) {
|
||||
selectedPerson.value = people.value.find(p => p.id === form.value.id);
|
||||
if (updatedItem) {
|
||||
selectedPerson.value = people.value.find(p => p.id === updatedItem.id) || updatedItem;
|
||||
}
|
||||
} catch (error) {
|
||||
feedback.value = { type: 'danger', message: error.message };
|
||||
@@ -250,50 +252,18 @@ async function deletePerson() {
|
||||
}
|
||||
}
|
||||
|
||||
function openQuickAdd(type: string) {
|
||||
feedback.value = { type: 'info', message: `Firma im Company Manager anlegen.` };
|
||||
}
|
||||
|
||||
onMounted(fetchData);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.content-wrapper {
|
||||
padding: 32px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 24px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: 800;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: var(--theme--foreground-subdued);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.details-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 32px;
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
|
||||
Reference in New Issue
Block a user