jogosultsági szintek RBAC beállítva tesztelve

This commit is contained in:
Roo
2026-06-25 20:41:49 +00:00
parent 52011606ff
commit 36109fc722
242 changed files with 8672 additions and 2237 deletions

View File

@@ -135,17 +135,17 @@
<!-- ID -->
<td class="py-3.5 px-4 text-slate-400 font-mono text-xs">{{ garage.id }}</td>
<!-- Company Name -->
<!-- Company Name (display_name priority, fallback to name) -->
<td class="py-3.5 px-4">
<div class="flex items-center gap-3">
<div
class="w-8 h-8 rounded-lg flex items-center justify-center text-sm font-bold text-white"
:class="getInitialsColor(garage.full_name)"
:class="getInitialsColor(garageDisplayName(garage))"
>
{{ getInitials(garage.full_name) }}
{{ getInitials(garageDisplayName(garage)) }}
</div>
<div>
<p class="text-sm font-medium text-white">{{ garage.full_name }}</p>
<p class="text-sm font-medium text-white">{{ garageDisplayName(garage) }}</p>
<p class="text-xs text-slate-500">{{ garage.city || '—' }} · {{ garage.member_count }} {{ $t('garages.members') }}</p>
</div>
</div>
@@ -180,12 +180,19 @@
<span v-if="garage.subscription_expires_at" class="text-slate-300 text-xs">
{{ formatDate(garage.subscription_expires_at) }}
</span>
<span v-else class="text-slate-500 text-xs"></span>
<span v-else class="text-slate-500 text-xs italic">{{ $t('garages.indefinite') }}</span>
</td>
<!-- Actions -->
<td class="py-3.5 px-4">
<div class="flex items-center gap-2">
<button
@click="openDetails(garage)"
class="px-3 py-1.5 text-xs font-medium bg-slate-600/20 text-slate-300 hover:bg-slate-600/30 rounded-lg transition"
:title="$t('garages.view_details')"
>
{{ $t('garages.view_details') }}
</button>
<button
@click="openSubscriptionModal(garage)"
class="px-3 py-1.5 text-xs font-medium bg-indigo-600/20 text-indigo-300 hover:bg-indigo-600/30 rounded-lg transition"
@@ -234,7 +241,7 @@
<div class="px-6 py-4 border-b border-slate-700 flex items-center justify-between">
<div>
<h3 class="text-lg font-semibold text-white">{{ $t('garages.manage_subscription') }}</h3>
<p class="text-sm text-slate-400 mt-0.5">{{ selectedGarage?.full_name }}</p>
<p class="text-sm text-slate-400 mt-0.5">{{ selectedGarage ? garageDisplayName(selectedGarage) : '' }}</p>
</div>
<button @click="closeSubscriptionModal" class="p-1.5 rounded-lg text-slate-400 hover:text-white hover:bg-slate-700 transition">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -425,10 +432,12 @@ const enterpriseCount = computed(() => {
const filteredGarages = computed(() => {
return garages.value.filter(g => {
// Search filter
// Search filter — search across display_name, name, full_name, and city
if (searchQuery.value) {
const q = searchQuery.value.toLowerCase()
const displayName = garageDisplayName(g).toLowerCase()
const matchesSearch =
displayName.includes(q) ||
g.full_name.toLowerCase().includes(q) ||
g.name.toLowerCase().includes(q) ||
(g.city && g.city.toLowerCase().includes(q))
@@ -527,7 +536,7 @@ async function saveSubscription() {
body: payload,
})
showNotification('success', `"${selectedGarage.value.full_name}" ${useNuxtApp().$i18n.t('garages.subscription_updated')}`)
showNotification('success', `"${garageDisplayName(selectedGarage.value)}" ${useNuxtApp().$i18n.t('garages.subscription_updated')}`)
closeSubscriptionModal()
// Refresh the list
@@ -545,11 +554,23 @@ async function saveSubscription() {
async function toggleStatus(garage: Garage) {
// This would call a PATCH endpoint to toggle is_active
// For now, we just show a notification that this is not yet implemented
showNotification('error', `Status toggle for "${garage.full_name}" not yet implemented via API`)
showNotification('error', `Status toggle for "${garageDisplayName(garage)}" not yet implemented via API`)
}
// ── Helpers ────────────────────────────────────────────────────────
/**
* Returns the display name for a garage, prioritizing display_name over name.
* This ensures clean, human-readable names are shown in the UI.
*/
function garageDisplayName(garage: Garage): string {
return garage.display_name || garage.name || garage.full_name
}
function openDetails(garage: Garage) {
navigateTo(`/garages/${garage.id}`)
}
function getInitials(name: string): string {
return name
.split(' ')