feat(tenancy): add delete button on table + add-to-store in edit modal
All checks were successful
CI / ruff (push) Successful in 13s
CI / pytest (push) Successful in 2h33m59s
CI / validate (push) Successful in 31s
CI / dependency-scanning (push) Successful in 35s
CI / docs (push) Successful in 49s
CI / deploy (push) Successful in 1m13s

Table actions now show view + edit + delete (trash icon) for non-owner
members. Delete opens the existing remove-from-all-stores modal.

Edit modal enhanced with "Add to another store" section:
- Shows a dashed-border card with store dropdown + role dropdown + add button
- Only appears when the member is not yet in all merchant stores
- Uses the existing invite API to add the member to the selected store

i18n: 2 new keys (add_to_store, select_store) in 4 locales.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-30 21:36:42 +02:00
parent 50d50fcbd0
commit a247622d23
6 changed files with 94 additions and 5 deletions

View File

@@ -137,11 +137,18 @@
<span x-html="$icon('eye', 'w-4 h-4')"></span>
</button>
<template x-if="!member.is_owner">
<button @click="openEditModal(member)"
class="p-1.5 text-gray-500 hover:text-purple-600 dark:text-gray-400 dark:hover:text-purple-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
:title="$t('tenancy.team.edit_member')">
<span x-html="$icon('pencil', 'w-4 h-4')"></span>
</button>
<div class="flex items-center gap-2">
<button @click="openEditModal(member)"
class="p-1.5 text-gray-500 hover:text-purple-600 dark:text-gray-400 dark:hover:text-purple-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
:title="$t('tenancy.team.edit_member')">
<span x-html="$icon('pencil', 'w-4 h-4')"></span>
</button>
<button @click="openRemoveModal(member)"
class="p-1.5 text-gray-500 hover:text-red-600 dark:text-gray-400 dark:hover:text-red-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
:title="$t('tenancy.team.remove_member')">
<span x-html="$icon('trash', 'w-4 h-4')"></span>
</button>
</div>
</template>
<template x-if="member.is_owner">
<span class="inline-flex items-center px-2 py-1 text-xs text-purple-600 dark:text-purple-400">
@@ -347,6 +354,34 @@
</div>
</template>
<!-- Add to another store -->
<template x-if="getAvailableStores(selectedMember).length > 0">
<div class="p-3 border border-dashed border-gray-300 dark:border-gray-600 rounded-lg">
<h5 class="text-xs font-medium text-gray-500 dark:text-gray-400 mb-2">{{ _('tenancy.team.add_to_store') }}</h5>
<div class="flex items-center gap-2">
<select x-model="addStoreForm.store_id"
class="flex-1 px-2 py-1 text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md focus:border-purple-400 focus:outline-none">
<option value="">{{ _('tenancy.team.select_store') }}</option>
<template x-for="s in getAvailableStores(selectedMember)" :key="s.id">
<option :value="s.id" x-text="s.name"></option>
</template>
</select>
<select x-model="addStoreForm.role_name"
class="px-2 py-1 text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md focus:border-purple-400 focus:outline-none">
<template x-for="role in roleOptions" :key="role.value">
<option :value="role.value" x-text="role.label"></option>
</template>
</select>
<button @click="addMemberToStore(selectedMember)"
:disabled="saving || !addStoreForm.store_id"
class="px-3 py-1 text-xs font-medium text-white bg-purple-600 rounded-md hover:bg-purple-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors">
<span x-show="saving" x-html="$icon('spinner', 'w-3 h-3')"></span>
<span x-show="!saving" x-html="$icon('plus', 'w-3 h-3')"></span>
</button>
</div>
</div>
</template>
<!-- Remove from all stores link -->
<div x-show="selectedMember?.stores?.length > 1" class="text-center pt-2">
<button @click="showEditModal = false; openRemoveModal(selectedMember)"