jogosultsági szintek RBAC beállítva tesztelve
This commit is contained in:
@@ -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(' ')
|
||||
|
||||
Reference in New Issue
Block a user