refactor: refactor create team modal to new system
This commit is contained in:
committed by
liyasthomas
parent
079083d0f2
commit
7ab1bbaf62
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<SmartModal v-if="show" :title="$t('team.new')" @close="hideModal">
|
||||
<SmartModal v-if="show" :title="$t('team.new').toString()" @close="hideModal">
|
||||
<template #body>
|
||||
<div class="flex flex-col px-2">
|
||||
<input
|
||||
@@ -19,9 +19,12 @@
|
||||
</template>
|
||||
<template #footer>
|
||||
<span>
|
||||
<ButtonPrimary :label="$t('action.save')" @click.native="addNewTeam" />
|
||||
<ButtonPrimary
|
||||
:label="$t('action.save').toString()"
|
||||
@click.native="addNewTeam"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
:label="$t('action.cancel')"
|
||||
:label="$t('action.cancel').toString()"
|
||||
@click.native="hideModal"
|
||||
/>
|
||||
</span>
|
||||
@@ -29,54 +32,56 @@
|
||||
</SmartModal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import * as teamUtils from "~/helpers/teams/utils"
|
||||
<script setup lang="ts">
|
||||
import { ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { pipe } from "fp-ts/function"
|
||||
import * as TE from "fp-ts/TaskEither"
|
||||
import { createTeam } from "~/helpers/backend/mutations/Team"
|
||||
import { TeamNameCodec } from "~/helpers/backend/types/TeamName"
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
show: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
name: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addNewTeam() {
|
||||
// We save the user input in case of an error
|
||||
const name = this.name
|
||||
// We clear it early to give the UI a snappy feel
|
||||
this.name = ""
|
||||
if (!name) {
|
||||
this.$toast.error(this.$t("empty.team_name"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
return
|
||||
const {
|
||||
app: { i18n },
|
||||
$toast,
|
||||
} = useContext()
|
||||
|
||||
const $t = i18n.t.bind(i18n)
|
||||
|
||||
defineProps<{
|
||||
show: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "hide-modal"): void
|
||||
}>()
|
||||
|
||||
const name = ref<string | null>(null)
|
||||
|
||||
const addNewTeam = () =>
|
||||
pipe(
|
||||
TeamNameCodec.decode(name.value), // Perform decode (returns either)
|
||||
TE.fromEither, // Convert either to a task either
|
||||
TE.mapLeft(() => "invalid_name" as const), // Failure above is an invalid_name, give it an identifiable value
|
||||
TE.chainW(createTeam), // Create the team
|
||||
TE.match(
|
||||
(err) => {
|
||||
// err is of type "invalid_name" | GQLError<Err>
|
||||
if (err === "invalid_name") {
|
||||
$toast.error($t("team.name_length_insufficient").toString(), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
} else {
|
||||
// Handle GQL errors (use err obj)
|
||||
}
|
||||
},
|
||||
() => {
|
||||
// Success logic ?
|
||||
hideModal()
|
||||
}
|
||||
if (name !== null && name.replace(/\s/g, "").length < 6) {
|
||||
this.$toast.error(this.$t("team.name_length_insufficient"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
return
|
||||
}
|
||||
// Call to the graphql mutation
|
||||
teamUtils
|
||||
.createTeam(this.$apollo, name)
|
||||
.then(() => {
|
||||
this.hideModal()
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e)
|
||||
// We restore the initial user input
|
||||
this.name = name
|
||||
})
|
||||
this.hideModal()
|
||||
},
|
||||
hideModal() {
|
||||
this.name = null
|
||||
this.$emit("hide-modal")
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
)()
|
||||
|
||||
const hideModal = () => {
|
||||
name.value = null
|
||||
emit("hide-modal")
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="p-4">
|
||||
<label
|
||||
class="cursor-pointer transition hover:text-secondaryDark"
|
||||
@click="team.myRole === 'OWNER' ? $emit('edit-team') : ''"
|
||||
@click="team.myRole === 'OWNER' ? emit('edit-team') : ''"
|
||||
>
|
||||
{{ team.name || $t("state.nothing_found") }}
|
||||
</label>
|
||||
@@ -36,7 +36,7 @@
|
||||
:label="$t('action.edit').toString()"
|
||||
@click.native="
|
||||
() => {
|
||||
$emit('edit-team')
|
||||
emit('edit-team')
|
||||
$refs.options.tippy().hide()
|
||||
}
|
||||
"
|
||||
@@ -94,6 +94,11 @@ const props = defineProps<{
|
||||
teamID: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "edit-team"): void
|
||||
|
||||
}>()
|
||||
|
||||
const {
|
||||
app: { i18n },
|
||||
$toast,
|
||||
|
||||
@@ -1,12 +1,47 @@
|
||||
import gql from "graphql-tag"
|
||||
import { pipe } from "fp-ts/function"
|
||||
import * as TE from "fp-ts/TaskEither"
|
||||
import { runMutation } from "../GQLClient"
|
||||
import { TeamName } from "../types/TeamName"
|
||||
|
||||
type DeleteTeamErrors =
|
||||
| "team/not_required_role"
|
||||
| "team/invalid_id"
|
||||
| "team/member_not_found"
|
||||
| "ea/not_invite_or_admin"
|
||||
|
||||
type ExitTeamErrors = "team/invalid_id" | "team/member_not_found"
|
||||
type ExitTeamErrors =
|
||||
| "team/invalid_id"
|
||||
| "team/member_not_found"
|
||||
| "ea/not_invite_or_admin"
|
||||
|
||||
type CreateTeamErrors = "team/name_invalid" | "ea/not_invite_or_admin"
|
||||
|
||||
export const createTeam = (name: TeamName) =>
|
||||
pipe(
|
||||
runMutation<
|
||||
{
|
||||
createTeam: {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
},
|
||||
CreateTeamErrors
|
||||
>(
|
||||
gql`
|
||||
mutation CreateTeam($name: String!) {
|
||||
createTeam(name: $name) {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`,
|
||||
{
|
||||
name,
|
||||
}
|
||||
),
|
||||
TE.map(({ createTeam }) => createTeam)
|
||||
)
|
||||
|
||||
export const deleteTeam = (teamID: string) =>
|
||||
runMutation<void, DeleteTeamErrors>(
|
||||
|
||||
@@ -6,7 +6,7 @@ interface TeamNameBrand {
|
||||
|
||||
export const TeamNameCodec = t.brand(
|
||||
t.string,
|
||||
(x): x is t.Branded<string, TeamNameBrand> => x.length > 6,
|
||||
(x): x is t.Branded<string, TeamNameBrand> => x.trim().length > 6,
|
||||
"TeamName"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user