trypost/resources/js/components/WorkspaceSwitcher.vue
Paulo Castellano 74c6442728 refactor: code review fixes — policies, enums, data_get, tests
- Refactor WorkspacePolicy to use pivot role instead of workspace.user_id
- Add manageBilling policy (owner only) to BillingController
- Fix ApiKeyController authorization (view → manageTeam for store/destroy)
- Fix WorkspaceInviteController using workspace.user_id for owner checks
- Fix WorkspaceController settings is_owner using workspace.user_id
- Create PostAction enum for UpdatePost/PostController action strings
- Create ApiToken\Status enum
- Add User::SUBSCRIPTION_NAME constant, replace all hardcoded 'default'
- Convert wantsEmailFor to accept NotificationType enum
- Convert all $data[] to data_get() across publishers, controllers, jobs
- Fix SocialLoginController callback missing try/catch
- Fix SocialController::toggleActive missing workspace null check
- Fix UpdatePost NPE on meta merge when postPlatform not found
- Remove HTML5 required attributes from form inputs
- Convert function declarations to arrow functions in Vue components
- Replace hardcoded URLs with Wayfinder route helpers
- Replace new Date() with dayjs
- Add 16 new test files covering policies, authorization, publishing
2026-03-31 00:40:18 -03:00

66 lines
2.4 KiB
Vue

<script setup lang="ts">
import { router, usePage } from '@inertiajs/vue3';
import { IconCheck, IconPlus, IconSelector } from '@tabler/icons-vue';
import { computed } from 'vue';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { create as createWorkspaceRoute, switchMethod } from '@/routes/app/workspaces';
interface Workspace {
id: string;
name: string;
}
const page = usePage();
const currentWorkspace = computed<Workspace | null>(() => page.props.auth.currentWorkspace as Workspace | null);
const workspaces = computed<Workspace[]>(() => page.props.auth.workspaces as Workspace[]);
const switchWorkspace = (workspace: Workspace) => {
router.post(switchMethod.url(workspace.id), {}, {
preserveScroll: true,
});
};
const createWorkspace = () => {
router.visit(createWorkspaceRoute.url());
};
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger :as-child="true">
<Button variant="outline" class="w-full justify-between gap-2 px-3" :class="{ 'text-muted-foreground': !currentWorkspace }">
<span class="truncate">{{ currentWorkspace?.name || 'Select workspace' }}</span>
<IconSelector class="h-4 w-4 shrink-0 opacity-50" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" class="w-56">
<DropdownMenuLabel>Workspaces</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem
v-for="workspace in workspaces"
:key="workspace.id"
class="cursor-pointer"
@click="switchWorkspace(workspace)"
>
<div class="flex w-full items-center justify-between">
<span class="truncate">{{ workspace.name }}</span>
<IconCheck v-if="currentWorkspace?.id === workspace.id" class="h-4 w-4 shrink-0" />
</div>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem class="cursor-pointer" @click="createWorkspace">
<IconPlus class="mr-2 h-4 w-4" />
Create workspace
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</template>