2019-01-21 15:08:22 +01:00
< template >
2020-02-18 08:57:00 +01:00
< section class = "section container" >
2020-11-17 19:14:55 +01:00
< h1 class = "title" > { { $t ( "Create a new group" ) } } < / h1 >
2019-09-02 10:50:00 +02:00
2020-08-27 11:53:24 +02:00
< b -message type = "is-danger" v-for ="(value, index) in errors" :key ="index" >
{ { value } }
< / b - m e s s a g e >
2019-09-02 10:50:00 +02:00
2020-08-27 11:53:24 +02:00
< form @submit.prevent ="createGroup" >
2021-09-07 17:52:34 +02:00
< b -field : label = "$t('Group display name')" label -for = " group -display -name " >
< b -input
aria - required = "true"
required
v - model = "group.name"
id = "group-display-name"
/ >
2019-09-02 10:50:00 +02:00
< / b - f i e l d >
2020-08-27 11:53:24 +02:00
< div class = "field" >
2021-09-07 17:52:34 +02:00
< label class = "label" for = "group-preferred-username" > { {
$t ( "Federated Group Name" )
} } < / label >
2020-08-27 11:53:24 +02:00
< div class = "field-body" >
2020-11-17 19:14:55 +01:00
< b -field
2020-11-30 10:24:11 +01:00
: message = "
$t (
'Only alphanumeric lowercased characters and underscores are supported.'
)
"
2020-11-17 19:14:55 +01:00
>
< b -input
ref = "preferredUsernameInput"
aria - required = "true"
required
expanded
v - model = "group.preferredUsername"
pattern = "[a-z0-9_]+"
2021-09-07 17:52:34 +02:00
id = "group-preferred-username"
2020-11-17 19:14:55 +01:00
: useHtml5Validation = "true"
: validation - message = "
group . preferredUsername
2020-11-30 10:24:11 +01:00
? $t (
'Only alphanumeric lowercased characters and underscores are supported.'
)
2020-11-17 19:14:55 +01:00
: null
"
/ >
2020-08-27 11:53:24 +02:00
< p class = "control" >
< span class = "button is-static" > @ { { host } } < / span >
< / p >
< / b - f i e l d >
< / div >
< p
v - html = "
$t (
2020-10-27 10:50:42 +01:00
'This is like your federated username (<code>{username}</code>) for groups. It will allow the group to be found on the federation, and is guaranteed to be unique.' ,
2020-08-27 11:53:24 +02:00
{ username : usernameWithDomain ( currentActor , true ) }
)
"
/ >
< / div >
2021-09-07 17:52:34 +02:00
< b -field :label ="$t('Description')" label -for = " group -summary " >
< b -input v -model = " group.summary " type = "textarea" id = "group-summary" / >
2019-09-02 10:50:00 +02:00
< / b - f i e l d >
< div >
2020-11-17 19:14:55 +01:00
< b > { { $t ( "Avatar" ) } } < / b >
2021-04-12 10:43:04 +02:00
< picture -upload
: textFallback = "$t('Avatar')"
v - model = "avatarFile"
: maxSize = "avatarMaxSize"
/ >
2019-09-02 10:50:00 +02:00
< / div >
< div >
2020-11-17 19:14:55 +01:00
< b > { { $t ( "Banner" ) } } < / b >
2021-04-12 10:43:04 +02:00
< picture -upload
: textFallback = "$t('Banner')"
v - model = "bannerFile"
: maxSize = "bannerMaxSize"
/ >
2019-09-02 10:50:00 +02:00
< / div >
2020-11-30 10:24:11 +01:00
< button class = "button is-primary" native -type = " submit " >
{ { $t ( "Create my group" ) } }
< / button >
2020-08-27 11:53:24 +02:00
< / form >
2020-02-18 08:57:00 +01:00
< / section >
2019-01-21 15:08:22 +01:00
< / template >
< script lang = "ts" >
2020-09-29 09:53:48 +02:00
import { Component , Watch } from "vue-property-decorator" ;
2020-11-27 19:27:44 +01:00
import { Group , IPerson , usernameWithDomain } from "@/types/actor" ;
2020-08-27 11:53:24 +02:00
import { CURRENT _ACTOR _CLIENT , PERSON _MEMBERSHIPS } from "@/graphql/actor" ;
2020-08-14 11:32:23 +02:00
import { CREATE _GROUP } from "@/graphql/group" ;
2020-08-27 11:53:24 +02:00
import { mixins } from "vue-class-component" ;
import IdentityEditionMixin from "@/mixins/identityEdition" ;
2020-12-17 16:01:18 +01:00
import { MemberRole } from "@/types/enums" ;
2020-08-31 12:40:30 +02:00
import RouteName from "../../router/name" ;
2020-08-27 11:53:24 +02:00
import { convertToUsername } from "../../utils/username" ;
2020-11-27 19:27:44 +01:00
import PictureUpload from "../../components/PictureUpload.vue" ;
2021-04-12 10:43:04 +02:00
import { CONFIG } from "@/graphql/config" ;
import { IConfig } from "@/types/config.model" ;
2021-05-12 18:10:07 +02:00
import { ErrorResponse } from "@apollo/client/link/error" ;
import { ServerParseError } from "@apollo/client/link/http" ;
import { ApolloCache , FetchResult , InMemoryCache } from "@apollo/client/core" ;
2019-01-21 15:08:22 +01:00
2019-09-02 10:50:00 +02:00
@ Component ( {
components : {
PictureUpload ,
} ,
apollo : {
2019-09-11 09:59:01 +02:00
currentActor : {
query : CURRENT _ACTOR _CLIENT ,
2019-09-02 10:50:00 +02:00
} ,
2021-04-12 10:43:04 +02:00
config : CONFIG ,
2019-09-02 10:50:00 +02:00
} ,
2021-05-25 16:21:29 +02:00
metaInfo ( ) {
return {
title : this . $t ( "Create a new group" ) as string ,
} ;
} ,
2019-09-02 10:50:00 +02:00
} )
2020-08-27 11:53:24 +02:00
export default class CreateGroup extends mixins ( IdentityEditionMixin ) {
2019-09-11 09:59:01 +02:00
currentActor ! : IPerson ;
2019-01-21 15:08:22 +01:00
2019-09-02 10:50:00 +02:00
group = new Group ( ) ;
2021-04-12 10:43:04 +02:00
config ! : IConfig ;
2019-09-02 10:50:00 +02:00
avatarFile : File | null = null ;
2020-02-18 08:57:00 +01:00
2019-09-02 10:50:00 +02:00
bannerFile : File | null = null ;
2020-08-27 11:53:24 +02:00
errors : string [ ] = [ ] ;
usernameWithDomain = usernameWithDomain ;
2020-09-29 09:53:48 +02:00
async createGroup ( ) : Promise < void > {
2019-09-02 10:50:00 +02:00
try {
2021-04-12 10:43:04 +02:00
this . errors = [ ] ;
2019-09-02 10:50:00 +02:00
await this . $apollo . mutate ( {
mutation : CREATE _GROUP ,
variables : this . buildVariables ( ) ,
2021-05-12 18:10:07 +02:00
update : ( store : ApolloCache < InMemoryCache > , { data } : FetchResult ) => {
2020-08-27 11:53:24 +02:00
const query = {
query : PERSON _MEMBERSHIPS ,
variables : {
id : this . currentActor . id ,
} ,
} ;
const membershipData = store . readQuery < { person : IPerson } > ( query ) ;
if ( ! membershipData ) return ;
2020-08-31 12:40:30 +02:00
const { person } = membershipData ;
2020-08-27 11:53:24 +02:00
person . memberships . elements . push ( {
2021-05-12 18:10:07 +02:00
parent : data ? . createGroup ,
2020-08-27 11:53:24 +02:00
role : MemberRole . ADMINISTRATOR ,
actor : this . currentActor ,
insertedAt : new Date ( ) . toString ( ) ,
updatedAt : new Date ( ) . toString ( ) ,
} ) ;
store . writeQuery ( { ... query , data : { person } } ) ;
2019-09-02 10:50:00 +02:00
} ,
} ) ;
2019-01-21 15:08:22 +01:00
2020-02-18 08:57:00 +01:00
await this . $router . push ( {
name : RouteName . GROUP ,
2020-08-27 11:53:24 +02:00
params : { preferredUsername : usernameWithDomain ( this . group ) } ,
2020-02-18 08:57:00 +01:00
} ) ;
2019-09-02 10:50:00 +02:00
this . $notifier . success (
2020-02-18 08:57:00 +01:00
this . $t ( "Group {displayName} created" , {
displayName : this . group . displayName ( ) ,
} ) as string
2019-09-02 10:50:00 +02:00
) ;
2021-09-29 18:20:33 +02:00
} catch ( err : any ) {
2019-09-02 10:50:00 +02:00
this . handleError ( err ) ;
}
2019-01-21 15:08:22 +01:00
}
2020-09-29 09:53:48 +02:00
// eslint-disable-next-line class-methods-use-this
2020-08-27 11:53:24 +02:00
get host ( ) : string {
return window . location . hostname ;
}
2021-04-12 10:43:04 +02:00
get avatarMaxSize ( ) : number | undefined {
return this ? . config ? . uploadLimits ? . avatar ;
}
get bannerMaxSize ( ) : number | undefined {
return this ? . config ? . uploadLimits ? . banner ;
}
2020-08-27 11:53:24 +02:00
@ Watch ( "group.name" )
updateUsername ( groupName : string ) : void {
this . group . preferredUsername = convertToUsername ( groupName ) ;
}
2019-09-02 10:50:00 +02:00
private buildVariables ( ) {
let avatarObj = { } ;
let bannerObj = { } ;
if ( this . avatarFile ) {
avatarObj = {
avatar : {
2021-01-11 18:02:21 +01:00
media : {
2019-09-02 10:50:00 +02:00
name : this . avatarFile . name ,
alt : ` ${ this . group . preferredUsername } 's avatar ` ,
file : this . avatarFile ,
} ,
} ,
} ;
}
if ( this . bannerFile ) {
bannerObj = {
2020-09-29 09:53:48 +02:00
banner : {
2021-01-11 18:02:21 +01:00
media : {
2020-09-29 09:53:48 +02:00
name : this . bannerFile . name ,
alt : ` ${ this . group . preferredUsername } 's banner ` ,
file : this . bannerFile ,
} ,
2019-09-02 10:50:00 +02:00
} ,
} ;
}
2020-02-18 08:57:00 +01:00
return {
... this . group ,
... avatarObj ,
... bannerObj ,
} ;
2019-09-02 10:50:00 +02:00
}
2021-04-12 10:43:04 +02:00
private handleError ( err : ErrorResponse ) {
if ( err ? . networkError ? . name === "ServerParseError" ) {
const error = err ? . networkError as ServerParseError ;
if ( error ? . response ? . status === 413 ) {
this . errors . push (
this . $t (
"Unable to create the group. One of the pictures may be too heavy."
) as string
) ;
}
}
2020-11-30 10:24:11 +01:00
this . errors . push (
2021-04-12 10:43:04 +02:00
... ( err . graphQLErrors || [ ] ) . map (
( { message } : { message : string } ) => message
)
2020-11-30 10:24:11 +01:00
) ;
2019-01-21 15:08:22 +01:00
}
}
< / script >
< style >
. markdown - render h1 {
font - size : 2 em ;
}
< / style >