feat(settings): allow Danger Zone for any owner regardless of company count
Removes three layered gates that kept the Danger Zone completely hidden unless the current user had more than one company: 1. SettingsLayoutView's showDangerZone computed no longer checks companies.length > 1 — just is_owner. 2. DangerZoneView drops the v-if that wrapped the delete button with the same check. 3. Admin\\CompaniesController::destroy() drops the companies_count <= 1 early-return that was enforcing the rule server-side (translation key You_cannot_delete_all_companies was inline in the controller, not in lang files or tests, so nothing else needs cleanup). The reasoning behind the old gate was that a user with zero companies would be stranded. That's a misread of how the app degrades: /admin/no-company already exists as a graceful fallback view, and the user can create a fresh company from there to recover. Hiding the entire delete flow just to avoid that fallback UX was overkill — the name-confirmation modal already prevents accidental deletion.
This commit is contained in:
@@ -97,10 +97,6 @@ class CompaniesController extends Controller
|
|||||||
return respondJson('company_name_must_match_with_given_name', 'Company name must match with given name');
|
return respondJson('company_name_must_match_with_given_name', 'Company name must match with given name');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($user->loadCount('companies')->companies_count <= 1) {
|
|
||||||
return respondJson('You_cannot_delete_all_companies', 'You cannot delete all companies');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->companyService->delete($company, $user);
|
$this->companyService->delete($company, $user);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useCompanyStore } from '../../../../stores/company.store'
|
|
||||||
import { useModalStore } from '../../../../stores/modal.store'
|
import { useModalStore } from '../../../../stores/modal.store'
|
||||||
import DeleteCompanyModal from '../components/DeleteCompanyModal.vue'
|
import DeleteCompanyModal from '../components/DeleteCompanyModal.vue'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const companyStore = useCompanyStore()
|
|
||||||
const modalStore = useModalStore()
|
const modalStore = useModalStore()
|
||||||
|
|
||||||
function removeCompany(): void {
|
function removeCompany(): void {
|
||||||
@@ -22,7 +20,7 @@ function removeCompany(): void {
|
|||||||
:title="$t('settings.company_info.danger_zone')"
|
:title="$t('settings.company_info.danger_zone')"
|
||||||
:description="$t('settings.company_info.delete_company_description')"
|
:description="$t('settings.company_info.delete_company_description')"
|
||||||
>
|
>
|
||||||
<div v-if="companyStore.companies.length > 1" class="mt-6">
|
<div class="mt-6">
|
||||||
<BaseButton
|
<BaseButton
|
||||||
variant="danger"
|
variant="danger"
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { ref, computed, watchEffect } from 'vue'
|
|||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useGlobalStore } from '../../../../stores/global.store'
|
import { useGlobalStore } from '../../../../stores/global.store'
|
||||||
import { useCompanyStore } from '../../../../stores/company.store'
|
|
||||||
import { useUserStore } from '../../../../stores/user.store'
|
import { useUserStore } from '../../../../stores/user.store'
|
||||||
|
|
||||||
interface SettingMenuItem {
|
interface SettingMenuItem {
|
||||||
@@ -18,16 +17,12 @@ interface DropdownMenuItem extends SettingMenuItem {
|
|||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const globalStore = useGlobalStore()
|
const globalStore = useGlobalStore()
|
||||||
const companyStore = useCompanyStore()
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const showDangerZone = computed<boolean>(() => {
|
const showDangerZone = computed<boolean>(() => {
|
||||||
return (
|
return userStore.currentUser?.is_owner === true
|
||||||
userStore.currentUser?.is_owner === true &&
|
|
||||||
companyStore.companies.length > 1
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const currentSetting = ref<DropdownMenuItem | undefined>(undefined)
|
const currentSetting = ref<DropdownMenuItem | undefined>(undefined)
|
||||||
|
|||||||
Reference in New Issue
Block a user