add linter, prettier and typescript support for jetstream (#1)

* add linter, prettier and typescript support for jetstream

* add github actions for lint, build and typecheck

* add composer install to build action

* fix composer lock

* add ext-intl and fixed php version

* fix intl php extension install

* add tip php extension to github npm build action

* fix php version to 8.3.1

* change github php base action

* fix primary button default type

* updated typescript types from Team to Organization

---------

Co-authored-by: Gregor Vostrak <gregorvostrak@Gregors-MacBook-Pro.local>
This commit is contained in:
Gregor Vostrak
2024-01-21 22:35:43 +01:00
committed by GitHub
parent 0a8d958ccc
commit 27140d4ffc
73 changed files with 4727 additions and 886 deletions

View File

@@ -1,4 +1,4 @@
<script setup>
<script setup lang="ts">
import AppLayout from '@/Layouts/AppLayout.vue';
import CreateTeamForm from '@/Pages/Teams/Partials/CreateTeamForm.vue';
</script>
@@ -6,7 +6,8 @@ import CreateTeamForm from '@/Pages/Teams/Partials/CreateTeamForm.vue';
<template>
<AppLayout title="Create Team">
<template #header>
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
<h2
class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
Create Team
</h2>
</template>

View File

@@ -1,10 +1,11 @@
<script setup>
import { useForm } from '@inertiajs/vue3';
<script setup lang="ts">
import { useForm, usePage } from '@inertiajs/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';
import type { User } from '@/types/models';
const form = useForm({
name: '',
@@ -16,13 +17,16 @@ const createTeam = () => {
preserveScroll: true,
});
};
const page = usePage<{
auth: {
user: User;
};
}>();
</script>
<template>
<FormSection @submitted="createTeam">
<template #title>
Team Details
</template>
<template #title> Team Details</template>
<template #description>
Create a new team to collaborate with others on projects.
@@ -33,12 +37,17 @@ const createTeam = () => {
<InputLabel value="Team Owner" />
<div class="flex items-center mt-2">
<img class="object-cover w-12 h-12 rounded-full" :src="$page.props.auth.user.profile_photo_url" :alt="$page.props.auth.user.name">
<img
class="object-cover w-12 h-12 rounded-full"
:src="page.props.auth.user.profile_photo_url"
:alt="page.props.auth.user.name" />
<div class="ms-4 leading-tight">
<div class="text-gray-900 dark:text-white">{{ $page.props.auth.user.name }}</div>
<div class="text-gray-900 dark:text-white">
{{ page.props.auth.user.name }}
</div>
<div class="text-sm text-gray-700 dark:text-gray-300">
{{ $page.props.auth.user.email }}
{{ page.props.auth.user.email }}
</div>
</div>
</div>
@@ -51,14 +60,15 @@ const createTeam = () => {
v-model="form.name"
type="text"
class="block w-full mt-1"
autofocus
/>
autofocus />
<InputError :message="form.errors.name" class="mt-2" />
</div>
</template>
<template #actions>
<PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
<PrimaryButton
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing">
Create
</PrimaryButton>
</template>

View File

@@ -1,4 +1,4 @@
<script setup>
<script setup lang="ts">
import { ref } from 'vue';
import { useForm } from '@inertiajs/vue3';
import ActionSection from '@/Components/ActionSection.vue';
@@ -26,17 +26,16 @@ const deleteTeam = () => {
<template>
<ActionSection>
<template #title>
Delete Team
</template>
<template #title> Delete Team </template>
<template #description>
Permanently delete this team.
</template>
<template #description> Permanently delete this team. </template>
<template #content>
<div class="max-w-xl text-sm text-gray-600 dark:text-gray-400">
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.
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">
@@ -46,13 +45,15 @@ const deleteTeam = () => {
</div>
<!-- Delete Organization Confirmation Modal -->
<ConfirmationModal :show="confirmingTeamDeletion" @close="confirmingTeamDeletion = false">
<template #title>
Delete Team
</template>
<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.
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>
@@ -64,8 +65,7 @@ const deleteTeam = () => {
class="ms-3"
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing"
@click="deleteTeam"
>
@click="deleteTeam">
Delete Team
</DangerButton>
</template>

View File

@@ -1,5 +1,5 @@
<script setup>
import { ref } from 'vue';
<script setup lang="ts">
import { computed, ref } from 'vue';
import { router, useForm, usePage } from '@inertiajs/vue3';
import ActionMessage from '@/Components/ActionMessage.vue';
import ActionSection from '@/Components/ActionSection.vue';
@@ -13,57 +13,79 @@ import PrimaryButton from '@/Components/PrimaryButton.vue';
import SecondaryButton from '@/Components/SecondaryButton.vue';
import SectionBorder from '@/Components/SectionBorder.vue';
import TextInput from '@/Components/TextInput.vue';
import type {
Organization,
OrganizationInvitation,
User,
} from '@/types/models';
import type { Membership, Permissions, Role } from '@/types/jetstream';
const props = defineProps({
team: Object,
availableRoles: Array,
userPermissions: Object,
type UserWithMembership = User & { membership: Membership };
const props = defineProps<{
team: Organization;
availableRoles: Role[];
userPermissions: Permissions;
}>();
const users = computed(() => {
return props.team.users as Array<UserWithMembership>;
});
const page = usePage();
const page = usePage<{
auth: {
user: User;
};
}>();
const addTeamMemberForm = useForm({
email: '',
role: null,
role: null as string | null,
});
const updateRoleForm = useForm({
role: null,
role: null as string | null,
});
const leaveTeamForm = useForm({});
const removeTeamMemberForm = useForm({});
const currentlyManagingRole = ref(false);
const managingRoleFor = ref(null);
const managingRoleFor = ref<User | null>(null);
const confirmingLeavingTeam = ref(false);
const teamMemberBeingRemoved = ref(null);
const teamMemberBeingRemoved = ref<User | null>(null);
const addTeamMember = () => {
addTeamMemberForm.post(route('team-members.store', props.team), {
addTeamMemberForm.post(route('team-members.store', props.team.id), {
errorBag: 'addTeamMember',
preserveScroll: true,
onSuccess: () => addTeamMemberForm.reset(),
});
};
const cancelTeamInvitation = (invitation) => {
router.delete(route('team-invitations.destroy', invitation), {
const cancelTeamInvitation = (invitation: OrganizationInvitation) => {
router.delete(route('team-invitations.destroy', invitation.id), {
preserveScroll: true,
});
};
const manageRole = (teamMember) => {
const manageRole = (teamMember: User & { membership: Membership }) => {
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,
});
updateRoleForm.put(
route('team-members.update', {
team: props.team.id,
user: managingRoleFor.value?.id,
}),
{
preserveScroll: true,
onSuccess: () => (currentlyManagingRole.value = false),
}
);
};
const confirmLeavingTeam = () => {
@@ -71,24 +93,32 @@ const confirmLeavingTeam = () => {
};
const leaveTeam = () => {
leaveTeamForm.delete(route('team-members.destroy', [props.team, page.props.auth.user]));
leaveTeamForm.delete(
route('team-members.destroy', [props.team.id, page.props.auth.user.id])
);
};
const confirmTeamMemberRemoval = (teamMember) => {
const confirmTeamMemberRemoval = (teamMember: User) => {
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,
});
removeTeamMemberForm.delete(
route('team-members.destroy', {
team: props.team.id,
user: teamMemberBeingRemoved.value?.id,
}),
{
errorBag: 'removeTeamMember',
preserveScroll: true,
preserveState: true,
onSuccess: () => (teamMemberBeingRemoved.value = null),
}
);
};
const displayableRole = (role) => {
return props.availableRoles.find(r => r.key === role).name;
const displayableRole = (role: string) => {
return props.availableRoles.find((r) => r.key === role)?.name;
};
</script>
@@ -99,18 +129,19 @@ const displayableRole = (role) => {
<!-- Add Organization Member -->
<FormSection @submitted="addTeamMember">
<template #title>
Add Team Member
</template>
<template #title> Add Team Member</template>
<template #description>
Add a new team member to your team, allowing them to collaborate with you.
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 dark:text-gray-400">
Please provide the email address of the person you would like to add to this team.
<div
class="max-w-xl text-sm text-gray-600 dark:text-gray-400">
Please provide the email address of the person you
would like to add to this team.
</div>
</div>
@@ -121,39 +152,75 @@ const displayableRole = (role) => {
id="email"
v-model="addTeamMemberForm.email"
type="email"
class="mt-1 block w-full"
/>
<InputError :message="addTeamMemberForm.errors.email" class="mt-2" />
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">
<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" />
<InputError
:message="addTeamMemberForm.errors.role"
class="mt-2" />
<div class="relative z-0 mt-1 border border-gray-200 dark:border-gray-700 rounded-lg cursor-pointer">
<div
class="relative z-0 mt-1 border border-gray-200 dark:border-gray-700 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-indigo-500 dark:focus:border-indigo-600 focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-600"
:class="{'border-t border-gray-200 dark:border-gray-700 focus:border-none 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}">
:class="{
'border-t border-gray-200 dark:border-gray-700 focus:border-none 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 dark:text-gray-400" :class="{'font-semibold': addTeamMemberForm.role == role.key}">
<div
class="text-sm text-gray-600 dark:text-gray-400"
:class="{
'font-semibold':
addTeamMemberForm.role ==
role.key,
}">
{{ role.name }}
</div>
<svg v-if="addTeamMemberForm.role == role.key" class="ms-2 h-5 w-5 text-green-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
<svg
v-if="
addTeamMemberForm.role ==
role.key
"
class="ms-2 h-5 w-5 text-green-400"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<!-- Role Description -->
<div class="mt-2 text-xs text-gray-600 dark:text-gray-400 text-start">
<div
class="mt-2 text-xs text-gray-600 dark:text-gray-400 text-start">
{{ role.description }}
</div>
</div>
@@ -163,34 +230,45 @@ const displayableRole = (role) => {
</template>
<template #actions>
<ActionMessage :on="addTeamMemberForm.recentlySuccessful" class="me-3">
<ActionMessage
:on="addTeamMemberForm.recentlySuccessful"
class="me-3">
Added.
</ActionMessage>
<PrimaryButton :class="{ 'opacity-25': addTeamMemberForm.processing }" :disabled="addTeamMemberForm.processing">
<PrimaryButton
:class="{ 'opacity-25': addTeamMemberForm.processing }"
:disabled="addTeamMemberForm.processing">
Add
</PrimaryButton>
</template>
</FormSection>
</div>
<div v-if="team.team_invitations.length > 0 && userPermissions.canAddTeamMembers">
<div
v-if="
team.team_invitations.length > 0 &&
userPermissions.canAddTeamMembers
">
<SectionBorder />
<!-- Organization Member Invitations -->
<ActionSection class="mt-10 sm:mt-0">
<template #title>
Pending Team Invitations
</template>
<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.
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 Organization 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
v-for="invitation in team.team_invitations"
:key="invitation.id"
class="flex items-center justify-between">
<div class="text-gray-600 dark:text-gray-400">
{{ invitation.email }}
</div>
@@ -200,8 +278,7 @@ const displayableRole = (role) => {
<button
v-if="userPermissions.canRemoveTeamMembers"
class="cursor-pointer ms-6 text-sm text-red-500 focus:outline-none"
@click="cancelTeamInvitation(invitation)"
>
@click="cancelTeamInvitation(invitation)">
Cancel
</button>
</div>
@@ -211,14 +288,12 @@ const displayableRole = (role) => {
</ActionSection>
</div>
<div v-if="team.users.length > 0">
<div v-if="users.length > 0">
<SectionBorder />
<!-- Manage Organization Members -->
<ActionSection class="mt-10 sm:mt-0">
<template #title>
Team Members
</template>
<template #title> Team Members</template>
<template #description>
All of the people that are part of this team.
@@ -227,9 +302,15 @@ const displayableRole = (role) => {
<!-- Organization 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
v-for="user in users"
:key="user.id"
class="flex items-center justify-between">
<div class="flex items-center">
<img class="w-8 h-8 rounded-full object-cover" :src="user.profile_photo_url" :alt="user.name">
<img
class="w-8 h-8 rounded-full object-cover"
:src="user.profile_photo_url"
:alt="user.name" />
<div class="ms-4 dark:text-white">
{{ user.name }}
</div>
@@ -238,32 +319,36 @@ const displayableRole = (role) => {
<div class="flex items-center">
<!-- Manage Organization Member Role -->
<button
v-if="userPermissions.canUpdateTeamMembers && availableRoles.length"
v-if="
userPermissions.canUpdateTeamMembers &&
availableRoles.length
"
class="ms-2 text-sm text-gray-400 underline"
@click="manageRole(user)"
>
@click="manageRole(user)">
{{ displayableRole(user.membership.role) }}
</button>
<div v-else-if="availableRoles.length" class="ms-2 text-sm text-gray-400">
<div
v-else-if="availableRoles.length"
class="ms-2 text-sm text-gray-400">
{{ displayableRole(user.membership.role) }}
</div>
<!-- Leave Organization -->
<button
v-if="$page.props.auth.user.id === user.id"
v-if="page.props.auth.user.id === user.id"
class="cursor-pointer ms-6 text-sm text-red-500"
@click="confirmLeavingTeam"
>
@click="confirmLeavingTeam">
Leave
</button>
<!-- Remove Organization Member -->
<button
v-else-if="userPermissions.canRemoveTeamMembers"
v-else-if="
userPermissions.canRemoveTeamMembers
"
class="cursor-pointer ms-6 text-sm text-red-500"
@click="confirmTeamMemberRemoval(user)"
>
@click="confirmTeamMemberRemoval(user)">
Remove
</button>
</div>
@@ -274,36 +359,64 @@ const displayableRole = (role) => {
</div>
<!-- Role Management Modal -->
<DialogModal :show="currentlyManagingRole" @close="currentlyManagingRole = false">
<template #title>
Manage Role
</template>
<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 dark:border-gray-700 rounded-lg cursor-pointer">
<div
class="relative z-0 mt-1 border border-gray-200 dark:border-gray-700 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-indigo-500 dark:focus:border-indigo-600 focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-600"
:class="{'border-t border-gray-200 dark:border-gray-700 focus:border-none 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}">
:class="{
'border-t border-gray-200 dark:border-gray-700 focus:border-none 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 dark:text-gray-400" :class="{'font-semibold': updateRoleForm.role === role.key}">
<div
class="text-sm text-gray-600 dark:text-gray-400"
:class="{
'font-semibold':
updateRoleForm.role ===
role.key,
}">
{{ role.name }}
</div>
<svg v-if="updateRoleForm.role == role.key" class="ms-2 h-5 w-5 text-green-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
<svg
v-if="updateRoleForm.role == role.key"
class="ms-2 h-5 w-5 text-green-400"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<!-- Role Description -->
<div class="mt-2 text-xs text-gray-600 dark:text-gray-400">
<div
class="mt-2 text-xs text-gray-600 dark:text-gray-400">
{{ role.description }}
</div>
</div>
@@ -321,18 +434,17 @@ const displayableRole = (role) => {
class="ms-3"
:class="{ 'opacity-25': updateRoleForm.processing }"
:disabled="updateRoleForm.processing"
@click="updateRole"
>
@click="updateRole">
Save
</PrimaryButton>
</template>
</DialogModal>
<!-- Leave Organization Confirmation Modal -->
<ConfirmationModal :show="confirmingLeavingTeam" @close="confirmingLeavingTeam = false">
<template #title>
Leave Team
</template>
<ConfirmationModal
:show="confirmingLeavingTeam"
@close="confirmingLeavingTeam = false">
<template #title> Leave Team</template>
<template #content>
Are you sure you would like to leave this team?
@@ -347,18 +459,17 @@ const displayableRole = (role) => {
class="ms-3"
:class="{ 'opacity-25': leaveTeamForm.processing }"
:disabled="leaveTeamForm.processing"
@click="leaveTeam"
>
@click="leaveTeam">
Leave
</DangerButton>
</template>
</ConfirmationModal>
<!-- Remove Organization Member Confirmation Modal -->
<ConfirmationModal :show="teamMemberBeingRemoved" @close="teamMemberBeingRemoved = null">
<template #title>
Remove Team Member
</template>
<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?
@@ -373,8 +484,7 @@ const displayableRole = (role) => {
class="ms-3"
:class="{ 'opacity-25': removeTeamMemberForm.processing }"
:disabled="removeTeamMemberForm.processing"
@click="removeTeamMember"
>
@click="removeTeamMember">
Remove
</DangerButton>
</template>

View File

@@ -1,4 +1,4 @@
<script setup>
<script setup lang="ts">
import { useForm } from '@inertiajs/vue3';
import ActionMessage from '@/Components/ActionMessage.vue';
import FormSection from '@/Components/FormSection.vue';
@@ -6,18 +6,20 @@ import InputError from '@/Components/InputError.vue';
import InputLabel from '@/Components/InputLabel.vue';
import PrimaryButton from '@/Components/PrimaryButton.vue';
import TextInput from '@/Components/TextInput.vue';
import type { Organization } from '@/types/models';
import type { Permissions } from '@/types/jetstream';
const props = defineProps({
team: Object,
permissions: Object,
});
const props = defineProps<{
team: Organization;
permissions: Permissions;
}>();
const form = useForm({
name: props.team.name,
});
const updateTeamName = () => {
form.put(route('teams.update', props.team), {
form.put(route('teams.update', props.team.id), {
errorBag: 'updateTeamName',
preserveScroll: true,
});
@@ -26,9 +28,7 @@ const updateTeamName = () => {
<template>
<FormSection @submitted="updateTeamName">
<template #title>
Team Name
</template>
<template #title> Team Name</template>
<template #description>
The team's name and owner information.
@@ -40,10 +40,15 @@ const updateTeamName = () => {
<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">
<img
class="w-12 h-12 rounded-full object-cover"
:src="team.owner.profile_photo_url"
:alt="team.owner.name" />
<div class="ms-4 leading-tight">
<div class="text-gray-900 dark:text-white">{{ team.owner.name }}</div>
<div class="text-gray-900 dark:text-white">
{{ team.owner.name }}
</div>
<div class="text-gray-700 dark:text-gray-300 text-sm">
{{ team.owner.email }}
</div>
@@ -60,8 +65,7 @@ const updateTeamName = () => {
v-model="form.name"
type="text"
class="mt-1 block w-full"
:disabled="! permissions.canUpdateTeam"
/>
:disabled="!permissions.canUpdateTeam" />
<InputError :message="form.errors.name" class="mt-2" />
</div>
@@ -72,7 +76,9 @@ const updateTeamName = () => {
Saved.
</ActionMessage>
<PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
<PrimaryButton
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing">
Save
</PrimaryButton>
</template>

View File

@@ -1,21 +1,24 @@
<script setup>
<script setup lang="ts">
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';
import type { Organization } from '@/types/models';
import type { Permissions, Role } from '@/types/jetstream';
defineProps({
team: Object,
availableRoles: Array,
permissions: Object,
});
defineProps<{
team: Organization;
availableRoles: Role[];
permissions: Permissions;
}>();
</script>
<template>
<AppLayout title="Team Settings">
<template #header>
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
<h2
class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
Team Settings
</h2>
</template>
@@ -28,10 +31,10 @@ defineProps({
class="mt-10 sm:mt-0"
:team="team"
:available-roles="availableRoles"
:user-permissions="permissions"
/>
:user-permissions="permissions" />
<template v-if="permissions.canDeleteTeam && ! team.personal_team">
<template
v-if="permissions.canDeleteTeam && !team.personal_team">
<SectionBorder />
<DeleteTeamForm class="mt-10 sm:mt-0" :team="team" />