2020-07-09 17:24:28 +02:00
< template >
< div >
< nav class = "breadcrumb" aria -label = " breadcrumbs " >
< ul >
< li >
< router -link
: to = " {
name : RouteName . GROUP ,
params : { preferredUsername : usernameWithDomain ( group ) } ,
} "
> { { group . name } } < / r o u t e r - l i n k
>
< / li >
< li >
< router -link
: to = " {
name : RouteName . GROUP _SETTINGS ,
params : { preferredUsername : usernameWithDomain ( group ) } ,
} "
> { { $t ( "Settings" ) } } < / r o u t e r - l i n k
>
< / li >
< li class = "is-active" >
< router -link
: to = " {
name : RouteName . GROUP _PUBLIC _SETTINGS ,
params : { preferredUsername : usernameWithDomain ( group ) } ,
} "
> { { $t ( "Group settings" ) } } < / r o u t e r - l i n k
>
< / li >
< / ul >
< / nav >
2020-11-30 10:24:11 +01:00
< section
class = "container section"
v - if = "group && isCurrentActorAGroupAdmin"
>
2020-07-09 17:24:28 +02:00
< form @submit.prevent ="updateGroup" >
< b -field : label = "$t('Group name')" >
2021-06-15 17:25:33 +02:00
< b -input v -model = " editableGroup.name " / >
2020-07-09 17:24:28 +02:00
< / b - f i e l d >
< b -field : label = "$t('Group short description')" >
2021-06-15 17:25:33 +02:00
< editor mode = "basic" v -model = " editableGroup.summary " :maxSize ="500"
2020-07-09 17:24:28 +02:00
/ > < / b - f i e l d >
2020-09-29 09:53:48 +02:00
< b -field :label ="$t('Avatar')" >
< picture -upload
: textFallback = "$t('Avatar')"
v - model = "avatarFile"
2020-11-20 18:34:13 +01:00
: defaultImage = "group.avatar"
2021-04-12 10:43:04 +02:00
: maxSize = "avatarMaxSize"
2020-09-29 09:53:48 +02:00
/ >
< / b - f i e l d >
< b -field :label ="$t('Banner')" >
< picture -upload
: textFallback = "$t('Banner')"
v - model = "bannerFile"
2020-11-20 18:34:13 +01:00
: defaultImage = "group.banner"
2021-04-12 10:43:04 +02:00
: maxSize = "bannerMaxSize"
2020-09-29 09:53:48 +02:00
/ >
< / b - f i e l d >
2020-08-05 16:44:08 +02:00
< p class = "label" > { { $t ( "Group visibility" ) } } < / p >
< div class = "field" >
< b -radio
2021-06-15 17:25:33 +02:00
v - model = "editableGroup.visibility"
2020-08-05 16:44:08 +02:00
name = "groupVisibility"
: native - value = "GroupVisibility.PUBLIC"
>
{ { $t ( "Visible everywhere on the web" ) } } < br / >
< small > { {
$t (
"The group will be publicly listed in search results and may be suggested in the explore section. Only public informations will be shown on it's page."
)
} } < / small >
< / b - r a d i o >
< / div >
< div class = "field" >
< b -radio
2021-06-15 17:25:33 +02:00
v - model = "editableGroup.visibility"
2020-08-05 16:44:08 +02:00
name = "groupVisibility"
2020-12-17 15:25:58 +01:00
: native - value = "GroupVisibility.PRIVATE"
2020-08-05 16:44:08 +02:00
> { { $t ( "Only accessible through link" ) } } < br / >
< small > { {
2020-09-02 10:00:39 +02:00
$t (
"You'll need to transmit the group URL so people may access the group's profile. The group won't be findable in Mobilizon's search or regular search engines."
)
2020-08-05 16:44:08 +02:00
} } < / small >
< / b - r a d i o >
< p class = "control" >
< code > { { group . url } } < / code >
< b -tooltip
v - if = "canShowCopyButton"
: label = "$t('URL copied to clipboard')"
: active = "showCopiedTooltip"
always
type = "is-success"
position = "is-left"
>
< b -button
type = "is-primary"
icon - right = "content-paste"
native - type = "button"
@ click = "copyURL"
@ keyup . enter = "copyURL"
/ >
< / b - t o o l t i p >
< / p >
< / div >
2020-11-06 11:34:32 +01:00
< p class = "label" > { { $t ( "New members" ) } } < / p >
< div class = "field" >
2020-11-30 10:24:11 +01:00
< b -radio
2021-06-15 17:25:33 +02:00
v - model = "editableGroup.openness"
2020-11-30 10:24:11 +01:00
name = "groupOpenness"
: native - value = "Openness.OPEN"
>
2020-11-06 11:34:32 +01:00
{ { $t ( "Anyone can join freely" ) } } < br / >
< small > { {
$t (
"Anyone wanting to be a member from your group will be able to from your group page."
)
} } < / small >
< / b - r a d i o >
< / div >
< div class = "field" >
< b -radio
2021-06-15 17:25:33 +02:00
v - model = "editableGroup.openness"
2020-11-06 11:34:32 +01:00
name = "groupOpenness"
: native - value = "Openness.INVITE_ONLY"
> { { $t ( "Manually invite new members" ) } } < br / >
< small > { {
$t (
"The only way for your group to get new members is if an admininistrator invites them."
)
} } < / small >
< / b - r a d i o >
< / div >
2021-01-20 18:16:44 +01:00
< b -field
: label = "$t('Followers')"
: message = "$t('Followers will receive new public events and posts.')"
>
2021-06-15 17:25:33 +02:00
< b -checkbox v-model ="editableGroup.manuallyApprovesFollowers" >
2021-01-20 18:16:44 +01:00
{ { $t ( "Manually approve new followers" ) } }
< / b - c h e c k b o x >
< / b - f i e l d >
2020-08-05 16:44:08 +02:00
< full -address -auto -complete
: label = "$t('Group address')"
2021-06-15 17:25:33 +02:00
v - model = "editableGroup.physicalAddress"
2020-08-05 16:44:08 +02:00
: value = "currentAddress"
/ >
2020-08-27 11:53:24 +02:00
< div class = "buttons" >
2020-11-30 10:24:11 +01:00
< b -button native -type = " submit " type = "is-primary" > { {
$t ( "Update group" )
} } < / b - b u t t o n >
< b -button @click ="confirmDeleteGroup" type = "is-danger" > { {
$t ( "Delete group" )
} } < / b - b u t t o n >
2020-08-27 11:53:24 +02:00
< / div >
2020-07-09 17:24:28 +02:00
< / form >
2021-04-12 10:43:04 +02:00
< b -message type = "is-danger" v-for ="(value, index) in errors" :key ="index" >
{ { value } }
< / b - m e s s a g e >
2020-07-09 17:24:28 +02:00
< / section >
2020-10-14 19:10:57 +02:00
< b -message v-else >
2020-10-09 15:26:37 +02:00
{ { $t ( "You are not an administrator for this group." ) } }
< / b - m e s s a g e >
2020-07-09 17:24:28 +02:00
< / div >
< / template >
< script lang = "ts" >
2021-06-15 17:25:33 +02:00
import { Component , Watch } from "vue-property-decorator" ;
2020-08-31 12:40:30 +02:00
import FullAddressAutoComplete from "@/components/Event/FullAddressAutoComplete.vue" ;
2020-09-02 17:42:17 +02:00
import { Route } from "vue-router" ;
2020-09-29 09:53:48 +02:00
import PictureUpload from "@/components/PictureUpload.vue" ;
2020-10-09 15:26:37 +02:00
import { mixins } from "vue-class-component" ;
import GroupMixin from "@/mixins/group" ;
2020-12-17 15:25:58 +01:00
import { GroupVisibility , Openness } from "@/types/enums" ;
2020-10-09 15:26:37 +02:00
import { UPDATE _GROUP , DELETE _GROUP } from "../../graphql/group" ;
2020-11-27 19:27:44 +01:00
import { IGroup , usernameWithDomain } from "../../types/actor" ;
2020-08-05 16:44:08 +02:00
import { Address , IAddress } from "../../types/address.model" ;
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 { ServerParseError } from "@apollo/client/link/http" ;
import { ErrorResponse } from "@apollo/client/link/error" ;
2021-06-15 17:25:33 +02:00
import RouteName from "@/router/name" ;
2020-07-09 17:24:28 +02:00
@ Component ( {
2020-08-05 16:44:08 +02:00
components : {
FullAddressAutoComplete ,
2020-09-29 09:53:48 +02:00
PictureUpload ,
2020-09-02 17:42:17 +02:00
editor : ( ) => import ( "../../components/Editor.vue" ) ,
2020-08-05 16:44:08 +02:00
} ,
2021-04-12 10:43:04 +02:00
apollo : {
config : CONFIG ,
} ,
2021-05-25 16:21:29 +02:00
metaInfo ( ) {
return {
title : this . $t ( "Group settings" ) as string ,
} ;
} ,
2020-07-09 17:24:28 +02:00
} )
2020-10-09 15:26:37 +02:00
export default class GroupSettings extends mixins ( GroupMixin ) {
2020-07-09 17:24:28 +02:00
loading = true ;
RouteName = RouteName ;
2021-04-12 10:43:04 +02:00
config ! : IConfig ;
2020-07-09 17:24:28 +02:00
newMemberUsername = "" ;
2021-04-12 10:43:04 +02:00
errors : string [ ] = [ ] ;
2020-09-29 09:53:48 +02:00
avatarFile : File | null = null ;
bannerFile : File | null = null ;
2020-07-09 17:24:28 +02:00
usernameWithDomain = usernameWithDomain ;
2020-12-17 15:25:58 +01:00
GroupVisibility = GroupVisibility ;
2020-08-05 16:44:08 +02:00
2020-11-06 11:34:32 +01:00
Openness = Openness ;
2020-08-05 16:44:08 +02:00
showCopiedTooltip = false ;
2021-06-15 17:25:33 +02:00
editableGroup ! : IGroup ;
2020-09-02 17:42:17 +02:00
async updateGroup ( ) : Promise < void > {
2021-04-12 10:43:04 +02:00
try {
const variables = this . buildVariables ( ) ;
2021-06-15 17:25:33 +02:00
console . log ( variables ) ;
2021-04-12 10:43:04 +02:00
await this . $apollo . mutate < { updateGroup : IGroup } > ( {
mutation : UPDATE _GROUP ,
variables ,
} ) ;
this . $notifier . success ( this . $t ( "Group settings saved" ) as string ) ;
} catch ( err ) {
this . handleError ( err ) ;
}
2020-07-09 17:24:28 +02:00
}
2020-08-05 16:44:08 +02:00
2020-09-02 17:42:17 +02:00
confirmDeleteGroup ( ) : void {
2020-08-27 11:53:24 +02:00
this . $buefy . dialog . confirm ( {
title : this . $t ( "Delete group" ) as string ,
message : this . $t (
"Are you sure you want to <b>completely delete</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>."
) as string ,
confirmText : this . $t ( "Delete group" ) as string ,
cancelText : this . $t ( "Cancel" ) as string ,
type : "is-danger" ,
hasIcon : true ,
onConfirm : ( ) => this . deleteGroup ( ) ,
} ) ;
}
2020-09-02 17:42:17 +02:00
async deleteGroup ( ) : Promise < Route > {
2020-08-27 11:53:24 +02:00
await this . $apollo . mutate < { deleteGroup : IGroup } > ( {
mutation : DELETE _GROUP ,
variables : {
groupId : this . group . id ,
} ,
} ) ;
return this . $router . push ( { name : RouteName . MY _GROUPS } ) ;
}
2020-09-02 17:42:17 +02:00
async copyURL ( ) : Promise < void > {
2020-08-05 16:44:08 +02:00
await window . navigator . clipboard . writeText ( this . group . url ) ;
this . showCopiedTooltip = true ;
setTimeout ( ( ) => {
this . showCopiedTooltip = false ;
} , 2000 ) ;
}
2021-06-15 17:25:33 +02:00
@ Watch ( "group" )
async watchUpdateGroup ( ) : Promise < void > {
this . editableGroup = { ... this . group } ;
}
2020-09-29 09:53:48 +02:00
private buildVariables ( ) {
let avatarObj = { } ;
let bannerObj = { } ;
2021-06-15 17:25:33 +02:00
const variables = { ... this . editableGroup } ;
const physicalAddress = {
... variables . physicalAddress ,
} ;
2020-09-29 09:53:48 +02:00
// eslint-disable-next-line
// @ts-ignore
delete variables . _ _typename ;
2021-06-15 17:25:33 +02:00
if ( physicalAddress ) {
2020-09-29 09:53:48 +02:00
// eslint-disable-next-line
// @ts-ignore
2021-06-15 17:25:33 +02:00
delete physicalAddress . _ _typename ;
2020-09-29 09:53:48 +02:00
}
delete variables . avatar ;
delete variables . banner ;
if ( this . avatarFile ) {
avatarObj = {
avatar : {
2020-11-26 11:41:13 +01:00
media : {
2020-09-29 09:53:48 +02:00
name : this . avatarFile . name ,
2021-06-15 17:25:33 +02:00
alt : ` ${ this . editableGroup . preferredUsername } 's avatar ` ,
2020-09-29 09:53:48 +02:00
file : this . avatarFile ,
} ,
} ,
} ;
}
if ( this . bannerFile ) {
bannerObj = {
banner : {
2020-11-26 11:41:13 +01:00
media : {
2020-09-29 09:53:48 +02:00
name : this . bannerFile . name ,
2021-06-15 17:25:33 +02:00
alt : ` ${ this . editableGroup . preferredUsername } 's banner ` ,
2020-09-29 09:53:48 +02:00
file : this . bannerFile ,
} ,
} ,
} ;
}
return {
2021-06-15 17:25:33 +02:00
id : this . group . id ,
name : this . editableGroup . name ,
summary : this . editableGroup . summary ,
visibility : this . editableGroup . visibility ,
openness : this . editableGroup . openness ,
manuallyApprovesFollowers : this . editableGroup . manuallyApprovesFollowers ,
physicalAddress ,
2020-09-29 09:53:48 +02:00
... avatarObj ,
... bannerObj ,
} ;
}
2020-09-02 17:42:17 +02:00
// eslint-disable-next-line class-methods-use-this
2020-08-05 16:44:08 +02:00
get canShowCopyButton ( ) : boolean {
return window . isSecureContext ;
}
get currentAddress ( ) : IAddress {
2021-06-15 17:25:33 +02:00
return new Address ( this . editableGroup . physicalAddress ) ;
2020-08-05 16:44:08 +02:00
}
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 ;
}
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
) ;
}
}
this . errors . push (
... ( err . graphQLErrors || [ ] ) . map (
( { message } : { message : string } ) => message
)
) ;
}
2020-07-09 17:24:28 +02:00
}
< / script >