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

This commit is contained in:
2026-02-14 13:57:46 +01:00
parent ceaf3ae3ea
commit d69ade6268
25 changed files with 941 additions and 598 deletions

View File

@@ -1,5 +1,13 @@
<template>
<private-view title="Company Manager">
<MintelManagerLayout
title="Company Manager"
:item-title="selectedCompany?.name || 'Firma wählen'"
:is-empty="!selectedCompany"
empty-title="Firma auswählen"
empty-icon="business"
:notice="feedback"
@close-notice="feedback = null"
>
<template #navigation>
<v-list nav>
<v-list-item @click="openCreateDrawer" clickable>
@@ -17,7 +25,7 @@
v-for="company in companies"
:key="company.id"
:active="selectedCompany?.id === company.id"
class="company-item"
class="nav-item"
clickable
@click="selectCompany(company)"
>
@@ -31,41 +39,30 @@
</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="selectedCompany">
{{ selectedCompany.domain || 'Keine Domain angegeben' }}
</template>
</template>
<div v-if="!selectedCompany" class="empty-state">
<v-info title="Firma auswählen" icon="business" center>
Wähle eine Firma in der Navigation aus oder
<v-button x-small @click="openCreateDrawer">erstelle eine neue Firma</v-button>.
</v-info>
</div>
<template #actions>
<v-button secondary rounded icon v-tooltip.bottom="'Firma bearbeiten'" @click="openEditDrawer">
<v-icon name="edit" />
</v-button>
<v-button danger rounded icon v-tooltip.bottom="'Firma löschen'" @click="deleteCompany">
<v-icon name="delete" />
</v-button>
</template>
<div v-else>
<header class="header">
<div class="header-left">
<h1 class="title">{{ selectedCompany.name }}</h1>
<p class="subtitle">{{ selectedCompany.domain || 'Keine Domain angegeben' }}</p>
</div>
<template #empty-state>
Wähle eine Firma in der Navigation aus oder
<v-button x-small @click="openCreateDrawer">erstelle eine neue Firma</v-button>.
</template>
<div class="header-right">
<v-button secondary rounded icon v-tooltip="'Firma bearbeiten'" @click="openEditDrawer">
<v-icon name="edit" />
</v-button>
<v-button danger rounded icon v-tooltip="'Firma löschen'" @click="deleteCompany">
<v-icon name="delete" />
</v-button>
</div>
</header>
<v-divider />
<div class="detail-item full">
<span class="label">Notizen / Adresse</span>
<p class="value">{{ selectedCompany.notes || '---' }}</p>
</div>
<div v-if="selectedCompany" class="details-grid">
<div class="detail-item full">
<span class="label">Notizen / Adresse</span>
<p class="value">{{ selectedCompany.notes || '---' }}</p>
</div>
</div>
@@ -101,12 +98,13 @@
</div>
</template>
</v-drawer>
</private-view>
</MintelManagerLayout>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useApi } from '@directus/extensions-sdk';
import { MintelManagerLayout } from '@mintel/directus-extension-toolkit';
const api = useApi();
const companies = ref([]);
@@ -144,14 +142,19 @@ function openCreateDrawer() {
id: null,
name: '',
domain: '',
notes: ''
notes: ''
};
drawerActive.value = true;
}
function openEditDrawer() {
isEditing.value = true;
form.value = { ...selectedCompany.value };
form.value = {
id: selectedCompany.value.id,
name: selectedCompany.value.name,
domain: selectedCompany.value.domain,
notes: selectedCompany.value.notes
};
drawerActive.value = true;
}
@@ -163,17 +166,20 @@ async function saveCompany() {
saving.value = true;
try {
let updatedItem;
if (isEditing.value) {
await api.patch(`/items/companies/${form.value.id}`, form.value);
const res = await api.patch(`/items/companies/${form.value.id}`, form.value);
updatedItem = res.data.data;
feedback.value = { type: 'success', message: 'Firma aktualisiert!' };
} else {
await api.post('/items/companies', form.value);
const res = await api.post('/items/companies', form.value);
updatedItem = res.data.data;
feedback.value = { type: 'success', message: 'Firma angelegt!' };
}
drawerActive.value = false;
await fetchData();
if (isEditing.value) {
selectedCompany.value = companies.value.find(c => c.id === form.value.id);
if (updatedItem) {
selectedCompany.value = companies.value.find(c => c.id === updatedItem.id) || updatedItem;
}
} catch (error) {
feedback.value = { type: 'danger', message: error.message };
@@ -199,13 +205,7 @@ 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: flex; flex-direction: column; gap: 24px; margin-top: 32px; }
.details-grid { display: flex; flex-direction: column; gap: 24px; }
.detail-item { display: flex; flex-direction: column; gap: 8px; }
.detail-item.full { width: 100%; }
.label { font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--theme--foreground-subdued); letter-spacing: 0.5px; }