initial commit
This commit is contained in:
20
resources/js/Pages/Teams/Create.vue
Normal file
20
resources/js/Pages/Teams/Create.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<script setup>
|
||||
import AppLayout from '@/Layouts/AppLayout.vue';
|
||||
import CreateTeamForm from '@/Pages/Teams/Partials/CreateTeamForm.vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout title="Create Team">
|
||||
<template #header>
|
||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
||||
Create Team
|
||||
</h2>
|
||||
</template>
|
||||
|
||||
<div>
|
||||
<div class="max-w-7xl mx-auto py-10 sm:px-6 lg:px-8">
|
||||
<CreateTeamForm />
|
||||
</div>
|
||||
</div>
|
||||
</AppLayout>
|
||||
</template>
|
66
resources/js/Pages/Teams/Partials/CreateTeamForm.vue
Normal file
66
resources/js/Pages/Teams/Partials/CreateTeamForm.vue
Normal file
@ -0,0 +1,66 @@
|
||||
<script setup>
|
||||
import { useForm } from '@inertiajs/inertia-vue3';
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
|
||||
const form = useForm({
|
||||
name: '',
|
||||
});
|
||||
|
||||
const createTeam = () => {
|
||||
form.post(route('teams.store'), {
|
||||
errorBag: 'createTeam',
|
||||
preserveScroll: true,
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FormSection @submitted="createTeam">
|
||||
<template #title>
|
||||
Team Details
|
||||
</template>
|
||||
|
||||
<template #description>
|
||||
Create a new team to collaborate with others on projects.
|
||||
</template>
|
||||
|
||||
<template #form>
|
||||
<div class="col-span-6">
|
||||
<InputLabel value="Team Owner" />
|
||||
|
||||
<div class="flex items-center mt-2">
|
||||
<img class="object-cover w-12 h-12 rounded-full" :src="$page.props.user.profile_photo_url" :alt="$page.props.user.name">
|
||||
|
||||
<div class="ml-4 leading-tight">
|
||||
<div>{{ $page.props.user.name }}</div>
|
||||
<div class="text-sm text-gray-700">
|
||||
{{ $page.props.user.email }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<InputLabel for="name" value="Team Name" />
|
||||
<TextInput
|
||||
id="name"
|
||||
v-model="form.name"
|
||||
type="text"
|
||||
class="block w-full mt-1"
|
||||
autofocus
|
||||
/>
|
||||
<InputError :message="form.errors.name" class="mt-2" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
|
||||
Create
|
||||
</PrimaryButton>
|
||||
</template>
|
||||
</FormSection>
|
||||
</template>
|
75
resources/js/Pages/Teams/Partials/DeleteTeamForm.vue
Normal file
75
resources/js/Pages/Teams/Partials/DeleteTeamForm.vue
Normal file
@ -0,0 +1,75 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useForm } from '@inertiajs/inertia-vue3';
|
||||
import ActionSection from '@/Components/ActionSection.vue';
|
||||
import ConfirmationModal from '@/Components/ConfirmationModal.vue';
|
||||
import DangerButton from '@/Components/DangerButton.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
|
||||
const props = defineProps({
|
||||
team: Object,
|
||||
});
|
||||
|
||||
const confirmingTeamDeletion = ref(false);
|
||||
const form = useForm();
|
||||
|
||||
const confirmTeamDeletion = () => {
|
||||
confirmingTeamDeletion.value = true;
|
||||
};
|
||||
|
||||
const deleteTeam = () => {
|
||||
form.delete(route('teams.destroy', props.team), {
|
||||
errorBag: 'deleteTeam',
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ActionSection>
|
||||
<template #title>
|
||||
Delete Team
|
||||
</template>
|
||||
|
||||
<template #description>
|
||||
Permanently delete this team.
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<div class="max-w-xl text-sm text-gray-600">
|
||||
Once a team is deleted, all of its resources and data will be permanently deleted. Before deleting this team, please download any data or information regarding this team that you wish to retain.
|
||||
</div>
|
||||
|
||||
<div class="mt-5">
|
||||
<DangerButton @click="confirmTeamDeletion">
|
||||
Delete Team
|
||||
</DangerButton>
|
||||
</div>
|
||||
|
||||
<!-- Delete Team Confirmation Modal -->
|
||||
<ConfirmationModal :show="confirmingTeamDeletion" @close="confirmingTeamDeletion = false">
|
||||
<template #title>
|
||||
Delete Team
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
Are you sure you want to delete this team? Once a team is deleted, all of its resources and data will be permanently deleted.
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<SecondaryButton @click="confirmingTeamDeletion = false">
|
||||
Cancel
|
||||
</SecondaryButton>
|
||||
|
||||
<DangerButton
|
||||
class="ml-3"
|
||||
:class="{ 'opacity-25': form.processing }"
|
||||
:disabled="form.processing"
|
||||
@click="deleteTeam"
|
||||
>
|
||||
Delete Team
|
||||
</DangerButton>
|
||||
</template>
|
||||
</ConfirmationModal>
|
||||
</template>
|
||||
</ActionSection>
|
||||
</template>
|
396
resources/js/Pages/Teams/Partials/TeamMemberManager.vue
Normal file
396
resources/js/Pages/Teams/Partials/TeamMemberManager.vue
Normal file
@ -0,0 +1,396 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { Inertia } from '@inertiajs/inertia';
|
||||
import { useForm, usePage } from '@inertiajs/inertia-vue3';
|
||||
import ActionMessage from '@/Components/ActionMessage.vue';
|
||||
import ActionSection from '@/Components/ActionSection.vue';
|
||||
import ConfirmationModal from '@/Components/ConfirmationModal.vue';
|
||||
import DangerButton from '@/Components/DangerButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import SectionBorder from '@/Components/SectionBorder.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
|
||||
const props = defineProps({
|
||||
team: Object,
|
||||
availableRoles: Array,
|
||||
userPermissions: Object,
|
||||
});
|
||||
|
||||
const addTeamMemberForm = useForm({
|
||||
email: '',
|
||||
role: null,
|
||||
});
|
||||
|
||||
const updateRoleForm = useForm({
|
||||
role: null,
|
||||
});
|
||||
|
||||
const leaveTeamForm = useForm();
|
||||
const removeTeamMemberForm = useForm();
|
||||
|
||||
const currentlyManagingRole = ref(false);
|
||||
const managingRoleFor = ref(null);
|
||||
const confirmingLeavingTeam = ref(false);
|
||||
const teamMemberBeingRemoved = ref(null);
|
||||
|
||||
const addTeamMember = () => {
|
||||
addTeamMemberForm.post(route('team-members.store', props.team), {
|
||||
errorBag: 'addTeamMember',
|
||||
preserveScroll: true,
|
||||
onSuccess: () => addTeamMemberForm.reset(),
|
||||
});
|
||||
};
|
||||
|
||||
const cancelTeamInvitation = (invitation) => {
|
||||
Inertia.delete(route('team-invitations.destroy', invitation), {
|
||||
preserveScroll: true,
|
||||
});
|
||||
};
|
||||
|
||||
const manageRole = (teamMember) => {
|
||||
managingRoleFor.value = teamMember;
|
||||
updateRoleForm.role = teamMember.membership.role;
|
||||
currentlyManagingRole.value = true;
|
||||
};
|
||||
|
||||
const updateRole = () => {
|
||||
updateRoleForm.put(route('team-members.update', [props.team, managingRoleFor.value]), {
|
||||
preserveScroll: true,
|
||||
onSuccess: () => currentlyManagingRole.value = false,
|
||||
});
|
||||
};
|
||||
|
||||
const confirmLeavingTeam = () => {
|
||||
confirmingLeavingTeam.value = true;
|
||||
};
|
||||
|
||||
const leaveTeam = () => {
|
||||
leaveTeamForm.delete(route('team-members.destroy', [props.team, usePage().props.value.user]));
|
||||
};
|
||||
|
||||
const confirmTeamMemberRemoval = (teamMember) => {
|
||||
teamMemberBeingRemoved.value = teamMember;
|
||||
};
|
||||
|
||||
const removeTeamMember = () => {
|
||||
removeTeamMemberForm.delete(route('team-members.destroy', [props.team, teamMemberBeingRemoved.value]), {
|
||||
errorBag: 'removeTeamMember',
|
||||
preserveScroll: true,
|
||||
preserveState: true,
|
||||
onSuccess: () => teamMemberBeingRemoved.value = null,
|
||||
});
|
||||
};
|
||||
|
||||
const displayableRole = (role) => {
|
||||
return props.availableRoles.find(r => r.key === role).name;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="userPermissions.canAddTeamMembers">
|
||||
<SectionBorder />
|
||||
|
||||
<!-- Add Team Member -->
|
||||
<FormSection @submitted="addTeamMember">
|
||||
<template #title>
|
||||
Add Team Member
|
||||
</template>
|
||||
|
||||
<template #description>
|
||||
Add a new team member to your team, allowing them to collaborate with you.
|
||||
</template>
|
||||
|
||||
<template #form>
|
||||
<div class="col-span-6">
|
||||
<div class="max-w-xl text-sm text-gray-600">
|
||||
Please provide the email address of the person you would like to add to this team.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Member Email -->
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<InputLabel for="email" value="Email" />
|
||||
<TextInput
|
||||
id="email"
|
||||
v-model="addTeamMemberForm.email"
|
||||
type="email"
|
||||
class="mt-1 block w-full"
|
||||
/>
|
||||
<InputError :message="addTeamMemberForm.errors.email" class="mt-2" />
|
||||
</div>
|
||||
|
||||
<!-- Role -->
|
||||
<div v-if="availableRoles.length > 0" class="col-span-6 lg:col-span-4">
|
||||
<InputLabel for="roles" value="Role" />
|
||||
<InputError :message="addTeamMemberForm.errors.role" class="mt-2" />
|
||||
|
||||
<div class="relative z-0 mt-1 border border-gray-200 rounded-lg cursor-pointer">
|
||||
<button
|
||||
v-for="(role, i) in availableRoles"
|
||||
:key="role.key"
|
||||
type="button"
|
||||
class="relative px-4 py-3 inline-flex w-full rounded-lg focus:z-10 focus:outline-none focus:border-blue-300 focus:ring focus:ring-blue-200"
|
||||
:class="{'border-t border-gray-200 rounded-t-none': i > 0, 'rounded-b-none': i != Object.keys(availableRoles).length - 1}"
|
||||
@click="addTeamMemberForm.role = role.key"
|
||||
>
|
||||
<div :class="{'opacity-50': addTeamMemberForm.role && addTeamMemberForm.role != role.key}">
|
||||
<!-- Role Name -->
|
||||
<div class="flex items-center">
|
||||
<div class="text-sm text-gray-600" :class="{'font-semibold': addTeamMemberForm.role == role.key}">
|
||||
{{ role.name }}
|
||||
</div>
|
||||
|
||||
<svg
|
||||
v-if="addTeamMemberForm.role == role.key"
|
||||
class="ml-2 h-5 w-5 text-green-400"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
><path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
||||
</div>
|
||||
|
||||
<!-- Role Description -->
|
||||
<div class="mt-2 text-xs text-gray-600 text-left">
|
||||
{{ role.description }}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<ActionMessage :on="addTeamMemberForm.recentlySuccessful" class="mr-3">
|
||||
Added.
|
||||
</ActionMessage>
|
||||
|
||||
<PrimaryButton :class="{ 'opacity-25': addTeamMemberForm.processing }" :disabled="addTeamMemberForm.processing">
|
||||
Add
|
||||
</PrimaryButton>
|
||||
</template>
|
||||
</FormSection>
|
||||
</div>
|
||||
|
||||
<div v-if="team.team_invitations.length > 0 && userPermissions.canAddTeamMembers">
|
||||
<SectionBorder />
|
||||
|
||||
<!-- Team Member Invitations -->
|
||||
<ActionSection class="mt-10 sm:mt-0">
|
||||
<template #title>
|
||||
Pending Team Invitations
|
||||
</template>
|
||||
|
||||
<template #description>
|
||||
These people have been invited to your team and have been sent an invitation email. They may join the team by accepting the email invitation.
|
||||
</template>
|
||||
|
||||
<!-- Pending Team Member Invitation List -->
|
||||
<template #content>
|
||||
<div class="space-y-6">
|
||||
<div v-for="invitation in team.team_invitations" :key="invitation.id" class="flex items-center justify-between">
|
||||
<div class="text-gray-600">
|
||||
{{ invitation.email }}
|
||||
</div>
|
||||
|
||||
<div class="flex items-center">
|
||||
<!-- Cancel Team Invitation -->
|
||||
<button
|
||||
v-if="userPermissions.canRemoveTeamMembers"
|
||||
class="cursor-pointer ml-6 text-sm text-red-500 focus:outline-none"
|
||||
@click="cancelTeamInvitation(invitation)"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</ActionSection>
|
||||
</div>
|
||||
|
||||
<div v-if="team.users.length > 0">
|
||||
<SectionBorder />
|
||||
|
||||
<!-- Manage Team Members -->
|
||||
<ActionSection class="mt-10 sm:mt-0">
|
||||
<template #title>
|
||||
Team Members
|
||||
</template>
|
||||
|
||||
<template #description>
|
||||
All of the people that are part of this team.
|
||||
</template>
|
||||
|
||||
<!-- Team Member List -->
|
||||
<template #content>
|
||||
<div class="space-y-6">
|
||||
<div v-for="user in team.users" :key="user.id" class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<img class="w-8 h-8 rounded-full" :src="user.profile_photo_url" :alt="user.name">
|
||||
<div class="ml-4">
|
||||
{{ user.name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center">
|
||||
<!-- Manage Team Member Role -->
|
||||
<button
|
||||
v-if="userPermissions.canAddTeamMembers && availableRoles.length"
|
||||
class="ml-2 text-sm text-gray-400 underline"
|
||||
@click="manageRole(user)"
|
||||
>
|
||||
{{ displayableRole(user.membership.role) }}
|
||||
</button>
|
||||
|
||||
<div v-else-if="availableRoles.length" class="ml-2 text-sm text-gray-400">
|
||||
{{ displayableRole(user.membership.role) }}
|
||||
</div>
|
||||
|
||||
<!-- Leave Team -->
|
||||
<button
|
||||
v-if="$page.props.user.id === user.id"
|
||||
class="cursor-pointer ml-6 text-sm text-red-500"
|
||||
@click="confirmLeavingTeam"
|
||||
>
|
||||
Leave
|
||||
</button>
|
||||
|
||||
<!-- Remove Team Member -->
|
||||
<button
|
||||
v-else-if="userPermissions.canRemoveTeamMembers"
|
||||
class="cursor-pointer ml-6 text-sm text-red-500"
|
||||
@click="confirmTeamMemberRemoval(user)"
|
||||
>
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</ActionSection>
|
||||
</div>
|
||||
|
||||
<!-- Role Management Modal -->
|
||||
<DialogModal :show="currentlyManagingRole" @close="currentlyManagingRole = false">
|
||||
<template #title>
|
||||
Manage Role
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<div v-if="managingRoleFor">
|
||||
<div class="relative z-0 mt-1 border border-gray-200 rounded-lg cursor-pointer">
|
||||
<button
|
||||
v-for="(role, i) in availableRoles"
|
||||
:key="role.key"
|
||||
type="button"
|
||||
class="relative px-4 py-3 inline-flex w-full rounded-lg focus:z-10 focus:outline-none focus:border-blue-300 focus:ring focus:ring-blue-200"
|
||||
:class="{'border-t border-gray-200 rounded-t-none': i > 0, 'rounded-b-none': i !== Object.keys(availableRoles).length - 1}"
|
||||
@click="updateRoleForm.role = role.key"
|
||||
>
|
||||
<div :class="{'opacity-50': updateRoleForm.role && updateRoleForm.role !== role.key}">
|
||||
<!-- Role Name -->
|
||||
<div class="flex items-center">
|
||||
<div class="text-sm text-gray-600" :class="{'font-semibold': updateRoleForm.role === role.key}">
|
||||
{{ role.name }}
|
||||
</div>
|
||||
|
||||
<svg
|
||||
v-if="updateRoleForm.role === role.key"
|
||||
class="ml-2 h-5 w-5 text-green-400"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
><path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
||||
</div>
|
||||
|
||||
<!-- Role Description -->
|
||||
<div class="mt-2 text-xs text-gray-600">
|
||||
{{ role.description }}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<SecondaryButton @click="currentlyManagingRole = false">
|
||||
Cancel
|
||||
</SecondaryButton>
|
||||
|
||||
<PrimaryButton
|
||||
class="ml-3"
|
||||
:class="{ 'opacity-25': updateRoleForm.processing }"
|
||||
:disabled="updateRoleForm.processing"
|
||||
@click="updateRole"
|
||||
>
|
||||
Save
|
||||
</PrimaryButton>
|
||||
</template>
|
||||
</DialogModal>
|
||||
|
||||
<!-- Leave Team Confirmation Modal -->
|
||||
<ConfirmationModal :show="confirmingLeavingTeam" @close="confirmingLeavingTeam = false">
|
||||
<template #title>
|
||||
Leave Team
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
Are you sure you would like to leave this team?
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<SecondaryButton @click="confirmingLeavingTeam = false">
|
||||
Cancel
|
||||
</SecondaryButton>
|
||||
|
||||
<DangerButton
|
||||
class="ml-3"
|
||||
:class="{ 'opacity-25': leaveTeamForm.processing }"
|
||||
:disabled="leaveTeamForm.processing"
|
||||
@click="leaveTeam"
|
||||
>
|
||||
Leave
|
||||
</DangerButton>
|
||||
</template>
|
||||
</ConfirmationModal>
|
||||
|
||||
<!-- Remove Team Member Confirmation Modal -->
|
||||
<ConfirmationModal :show="teamMemberBeingRemoved" @close="teamMemberBeingRemoved = null">
|
||||
<template #title>
|
||||
Remove Team Member
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
Are you sure you would like to remove this person from the team?
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<SecondaryButton @click="teamMemberBeingRemoved = null">
|
||||
Cancel
|
||||
</SecondaryButton>
|
||||
|
||||
<DangerButton
|
||||
class="ml-3"
|
||||
:class="{ 'opacity-25': removeTeamMemberForm.processing }"
|
||||
:disabled="removeTeamMemberForm.processing"
|
||||
@click="removeTeamMember"
|
||||
>
|
||||
Remove
|
||||
</DangerButton>
|
||||
</template>
|
||||
</ConfirmationModal>
|
||||
</div>
|
||||
</template>
|
80
resources/js/Pages/Teams/Partials/UpdateTeamNameForm.vue
Normal file
80
resources/js/Pages/Teams/Partials/UpdateTeamNameForm.vue
Normal file
@ -0,0 +1,80 @@
|
||||
<script setup>
|
||||
import { useForm } from '@inertiajs/inertia-vue3';
|
||||
import ActionMessage from '@/Components/ActionMessage.vue';
|
||||
import FormSection from '@/Components/FormSection.vue';
|
||||
import InputError from '@/Components/InputError.vue';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
|
||||
const props = defineProps({
|
||||
team: Object,
|
||||
permissions: Object,
|
||||
});
|
||||
|
||||
const form = useForm({
|
||||
name: props.team.name,
|
||||
});
|
||||
|
||||
const updateTeamName = () => {
|
||||
form.put(route('teams.update', props.team), {
|
||||
errorBag: 'updateTeamName',
|
||||
preserveScroll: true,
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FormSection @submitted="updateTeamName">
|
||||
<template #title>
|
||||
Team Name
|
||||
</template>
|
||||
|
||||
<template #description>
|
||||
The team's name and owner information.
|
||||
</template>
|
||||
|
||||
<template #form>
|
||||
<!-- Team Owner Information -->
|
||||
<div class="col-span-6">
|
||||
<InputLabel value="Team Owner" />
|
||||
|
||||
<div class="flex items-center mt-2">
|
||||
<img class="w-12 h-12 rounded-full object-cover" :src="team.owner.profile_photo_url" :alt="team.owner.name">
|
||||
|
||||
<div class="ml-4 leading-tight">
|
||||
<div>{{ team.owner.name }}</div>
|
||||
<div class="text-gray-700 text-sm">
|
||||
{{ team.owner.email }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Team Name -->
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<InputLabel for="name" value="Team Name" />
|
||||
|
||||
<TextInput
|
||||
id="name"
|
||||
v-model="form.name"
|
||||
type="text"
|
||||
class="mt-1 block w-full"
|
||||
:disabled="! permissions.canUpdateTeam"
|
||||
/>
|
||||
|
||||
<InputError :message="form.errors.name" class="mt-2" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="permissions.canUpdateTeam" #actions>
|
||||
<ActionMessage :on="form.recentlySuccessful" class="mr-3">
|
||||
Saved.
|
||||
</ActionMessage>
|
||||
|
||||
<PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
|
||||
Save
|
||||
</PrimaryButton>
|
||||
</template>
|
||||
</FormSection>
|
||||
</template>
|
42
resources/js/Pages/Teams/Show.vue
Normal file
42
resources/js/Pages/Teams/Show.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<script setup>
|
||||
import AppLayout from '@/Layouts/AppLayout.vue';
|
||||
import DeleteTeamForm from '@/Pages/Teams/Partials/DeleteTeamForm.vue';
|
||||
import SectionBorder from '@/Components/SectionBorder.vue';
|
||||
import TeamMemberManager from '@/Pages/Teams/Partials/TeamMemberManager.vue';
|
||||
import UpdateTeamNameForm from '@/Pages/Teams/Partials/UpdateTeamNameForm.vue';
|
||||
|
||||
defineProps({
|
||||
team: Object,
|
||||
availableRoles: Array,
|
||||
permissions: Object,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout title="Team Settings">
|
||||
<template #header>
|
||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
||||
Team Settings
|
||||
</h2>
|
||||
</template>
|
||||
|
||||
<div>
|
||||
<div class="max-w-7xl mx-auto py-10 sm:px-6 lg:px-8">
|
||||
<UpdateTeamNameForm :team="team" :permissions="permissions" />
|
||||
|
||||
<TeamMemberManager
|
||||
class="mt-10 sm:mt-0"
|
||||
:team="team"
|
||||
:available-roles="availableRoles"
|
||||
:user-permissions="permissions"
|
||||
/>
|
||||
|
||||
<template v-if="permissions.canDeleteTeam && ! team.personal_team">
|
||||
<SectionBorder />
|
||||
|
||||
<DeleteTeamForm class="mt-10 sm:mt-0" :team="team" />
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</AppLayout>
|
||||
</template>
|
Reference in New Issue
Block a user