jcloude/dashboard/src/components/SwitchTeamDialog.vue
2025-12-23 21:34:08 +08:00

122 lines
3.0 KiB
Vue

<template>
<Dialog :options="{ title: 'Switch Team' }" v-model="show">
<template #body-content v-if="$team?.pg">
<div class="rounded bg-gray-100 px-3 py-2.5">
<div class="text-base text-gray-900">
You are logged in as the user
<span class="font-medium">{{ $session.user }}</span>
</div>
<div class="mt-2 text-base text-gray-900">
You are viewing dashboard for the team
<component
:is="$team.pg.is_desk_user ? 'a' : 'span'"
class="font-medium"
:class="{ underline: $team.pg.is_desk_user }"
:href="$team.pg.is_desk_user ? `/app/team/${$team.name}` : null"
target="_blank"
>
{{ $team.pg.user }}
</component>
</div>
</div>
<div class="mt-3">
<TextInput
v-if="sortedTeams.length > 5"
size="sm"
placeholder="Search"
:debounce="500"
v-model="searchQuery"
/>
</div>
<div class="-mb-3 mt-3 divide-y">
<div
class="flex items-center justify-between py-3"
v-for="team in filteredTeams"
:key="team.name"
>
<div class="flex items-center space-x-2">
<span class="text-base text-gray-800">
{{ team.user }}
</span>
<Button
v-if="$team.pg.is_desk_user"
icon="external-link"
:link="`/app/team/${team.name}`"
variant="ghost"
/>
</div>
<Badge
class="whitespace-nowrap"
v-if="$team.name === team.name"
label="Currently Active"
theme="green"
/>
<Button v-else @click="switchToTeam(team.name)">Switch</Button>
</div>
</div>
<div class="mt-6 flex items-end gap-2" v-if="$session.isSystemUser">
<LinkControl
class="w-full"
label="Select Team"
:options="{ pagetype: 'Team', filters: { enabled: 1 } }"
v-model="selectedTeam"
description="This feature is only available to system users"
/>
<div class="pb-5">
<Button :disabled="!selectedTeam" @click="switchToTeam(selectedTeam)">
Switch
</Button>
</div>
</div>
</template>
</Dialog>
</template>
<script>
import { TextInput } from 'jingrow-ui';
import { switchToTeam } from '../data/team';
import LinkControl from './LinkControl.vue';
export default {
name: 'SwitchTeamDialog',
props: ['modelValue'],
emits: ['update:modelValue'],
components: { LinkControl, TextInput },
computed: {
show: {
get() {
return this.modelValue;
},
set(value) {
this.$emit('update:modelValue', value);
},
},
sortedTeams() {
if (!this.$team?.pg?.valid_teams) return [];
return [...this.$team.pg.valid_teams].sort((a, b) => {
return a.user.localeCompare(b.user);
});
},
filteredTeams() {
if (!this.searchQuery.trim()) {
return this.sortedTeams;
}
const query = this.searchQuery.toLowerCase();
return this.sortedTeams.filter(
(team) =>
team.user.toLowerCase().includes(query) ||
team.name.toLowerCase().includes(query),
);
},
},
data() {
return {
selectedTeam: null,
searchQuery: '',
};
},
methods: {
switchToTeam,
},
};
</script>