2019-04-26 23:58:53 +02:00
/// <reference path="../../../ui/elements/modal.ts" />
/// <reference path="../../../ConnectionHandler.ts" />
/// <reference path="../../../proto.ts" />
2018-09-30 21:50:59 +02:00
2019-01-19 13:03:51 +01:00
/ *
TODO : Check needed permissions and may not even try to request , because we dont have the permission . Permissions :
b_virtualserver_servergroup_permission_list
b_virtualserver_channel_permission_list
b_virtualserver_client_permission_list
b_virtualserver_channelgroup_permission_list
b_virtualserver_channelclient_permission_list
b_virtualserver_playlist_permission_list
* /
2019-02-17 16:08:10 +01:00
interface JQuery < TElement = HTMLElement > {
dropdown : any ;
}
2018-09-30 21:50:59 +02:00
namespace Modals {
2019-08-21 10:00:01 +02:00
export namespace PermissionEditor {
2019-02-17 16:08:10 +01:00
export interface PermissionEntry {
tag : JQuery ;
tag_value : JQuery ;
tag_grant : JQuery ;
tag_flag_negate : JQuery ;
tag_flag_skip : JQuery ;
id : number ;
filter : string ;
is_bool : boolean ;
2018-12-02 18:55:08 +01:00
}
2019-02-17 16:08:10 +01:00
export interface PermissionValue {
remove : boolean ; /* if set remove the set permission (value or granted) */
2018-12-02 18:55:08 +01:00
2019-02-17 16:08:10 +01:00
granted? : number ;
value? : number ;
2018-12-02 18:55:08 +01:00
2019-02-17 16:08:10 +01:00
flag_skip? : boolean ;
flag_negate? : boolean ;
}
2018-09-30 21:50:59 +02:00
2019-08-21 10:00:01 +02:00
export type change_listener_t = ( permission : PermissionInfo , value? : PermissionEditor.PermissionValue ) = > Promise < void > ;
2019-02-17 16:08:10 +01:00
}
2019-08-21 10:00:01 +02:00
export enum PermissionEditorMode {
2019-02-17 16:08:10 +01:00
VISIBLE ,
NO_PERMISSION ,
UNSET
}
2018-09-30 21:50:59 +02:00
2019-08-21 10:00:01 +02:00
export abstract class AbstractPermissionEditor {
protected _permissions : GroupedPermissions [ ] ;
protected _listener_update : ( ) = > any ;
protected _listener_change : PermissionEditor.change_listener_t = ( ) = > Promise . resolve ( ) ;
protected _toggle_callback : ( ) = > string ;
2019-04-26 23:50:21 +02:00
2019-05-25 12:20:57 +02:00
icon_resolver : ( id : number ) = > Promise < HTMLImageElement > ;
icon_selector : ( current_id : number ) = > Promise < number > ;
2019-08-21 10:00:01 +02:00
protected constructor ( ) { }
2018-09-30 21:50:59 +02:00
2019-08-21 10:00:01 +02:00
abstract set_mode ( mode : PermissionEditorMode ) ;
2018-09-30 21:50:59 +02:00
2019-08-21 10:00:01 +02:00
abstract initialize ( permissions : GroupedPermissions [ ] ) ;
abstract html_tag ( ) : JQuery ;
abstract set_permissions ( permissions? : PermissionValue [ ] ) ;
2018-12-02 18:55:08 +01:00
2019-02-17 16:08:10 +01:00
set_listener ( listener? : PermissionEditor.change_listener_t ) {
2019-08-21 10:00:01 +02:00
this . _listener_change = listener || ( ( ) = > Promise . resolve ( ) ) ;
2019-02-17 16:08:10 +01:00
}
2018-12-02 18:55:08 +01:00
2019-08-21 10:00:01 +02:00
set_listener_update ( listener ? : ( ) = > any ) { this . _listener_update = listener ; }
trigger_update() { if ( this . _listener_update ) this . _listener_update ( ) ; }
2018-12-02 18:55:08 +01:00
2019-08-21 10:00:01 +02:00
abstract set_toggle_button ( callback : ( ) = > string , initial : string ) ;
}
2018-12-02 18:55:08 +01:00
2019-08-21 10:00:01 +02:00
export type OptionsServerGroup = { } ;
export type OptionsChannelGroup = { } ;
export type OptionsClientPermissions = { unique_id? : string } ;
export type OptionsChannelPermissions = { channel_id? : number } ;
export type OptionsClientChannelPermissions = OptionsClientPermissions & OptionsChannelPermissions ;
export interface OptionMap {
"sg" : OptionsServerGroup ,
"cg" : OptionsChannelGroup ,
"clp" : OptionsClientPermissions ,
"chp" : OptionsChannelPermissions ,
"clchp" : OptionsClientChannelPermissions
}
2019-04-26 23:50:21 +02:00
2019-08-21 10:00:01 +02:00
export function _space() {
const now = Date . now ( ) ;
while ( now + 100 > Date . now ( ) ) ;
2019-02-17 16:08:10 +01:00
}
2018-12-02 18:55:08 +01:00
2019-08-21 10:00:01 +02:00
export function spawnPermissionEdit < T extends keyof OptionMap > ( connection : ConnectionHandler , selected_tab? : T , options? : OptionMap [ T ] ) : Modal {
options = options || { } ;
2019-04-26 23:50:21 +02:00
const modal = createModal ( {
2019-02-17 16:08:10 +01:00
header : function ( ) {
return tr ( "Server Permissions" ) ;
} ,
body : function ( ) {
let properties : any = { } ;
let tag = $ ( "#tmpl_server_permissions" ) . renderTag ( properties ) ;
2019-08-21 10:00:01 +02:00
/* build the permission editor */
const permission_editor : AbstractPermissionEditor = ( ( ) = > {
const editor = new pe . HTMLPermissionEditor ( ) ;
editor . initialize ( connection . permissions . groupedPermissions ( ) ) ;
editor . icon_resolver = id = > connection . fileManager . icons . resolve_icon ( id ) . then ( async icon = > {
if ( ! icon )
return undefined ;
const tag = document . createElement ( "img" ) ;
await new Promise ( ( resolve , reject ) = > {
tag . onerror = reject ;
tag . onload = resolve ;
tag . src = icon . url ;
} ) ;
return tag ;
2019-05-25 12:20:57 +02:00
} ) ;
2019-08-21 10:00:01 +02:00
editor . icon_selector = current_icon = > new Promise < number > ( resolve = > {
spawnIconSelect ( connection , id = > resolve ( new Int32Array ( [ id ] ) [ 0 ] ) , current_icon ) ;
} ) ;
if ( editor instanceof pe . CanvasPermissionEditor )
setTimeout ( ( ) = > editor . update_ui ( ) , 500 ) ;
return editor ;
} ) ( ) ;
2019-05-25 12:20:57 +02:00
2019-08-21 10:00:01 +02:00
const container_tab_list = tag . find ( ".right > .header" ) ;
2019-02-17 16:08:10 +01:00
{
2019-08-21 10:00:01 +02:00
const label_current = tag . find ( ".left .container-selected" ) ;
const create_tab = ( tab_entry : JQuery , container_name : string ) = > {
const target_container = tag . find ( ".body .container." + container_name ) ;
tab_entry . on ( 'click' , ( ) = > {
/* Using a timeout here prevents unnecessary style calculations required by other click event handlers */
setTimeout ( ( ) = > {
container_tab_list . find ( ".selected" ) . removeClass ( "selected" ) ;
tab_entry . addClass ( "selected" ) ;
label_current . text ( tab_entry . find ( "a" ) . text ( ) ) ;
/* dont use show() here because it causes a style recalculation */
for ( const element of tag . find ( ".body .container" ) )
( < HTMLElement > element ) . style . display = "none" ;
permission_editor . html_tag ( ) [ 0 ] . remove ( ) ;
target_container . find ( ".permission-editor" ) . trigger ( 'show' ) ;
target_container . find ( ".permission-editor" ) . append ( permission_editor . html_tag ( ) ) ;
for ( const element of target_container )
( < HTMLElement > element ) . style . display = null ;
} , 0 ) ;
} ) ;
} ;
create_tab ( container_tab_list . find ( ".sg" ) , "container-view-server-groups" ) ;
create_tab ( container_tab_list . find ( ".cg" ) , "container-view-channel-groups" ) ;
create_tab ( container_tab_list . find ( ".chp" ) , "container-view-channel-permissions" ) ;
create_tab ( container_tab_list . find ( ".clp" ) , "container-view-client-permissions" ) ;
create_tab ( container_tab_list . find ( ".clchp" ) , "container-view-client-channel-permissions" ) ;
2019-02-17 16:08:10 +01:00
}
2019-08-21 10:00:01 +02:00
apply_server_groups ( connection , permission_editor , tag . find ( ".left .container-view-server-groups" ) , tag . find ( ".right .container-view-server-groups" ) ) ;
apply_channel_groups ( connection , permission_editor , tag . find ( ".left .container-view-channel-groups" ) , tag . find ( ".right .container-view-channel-groups" ) ) ;
apply_channel_permission ( connection , permission_editor , tag . find ( ".left .container-view-channel-permissions" ) , tag . find ( ".right .container-view-channel-permissions" ) ) ;
apply_client_permission ( connection , permission_editor , tag . find ( ".left .container-view-client-permissions" ) , tag . find ( ".right .container-view-client-permissions" ) , selected_tab == "clp" ? < any > options : { } ) ;
apply_client_channel_permission ( connection , permission_editor , tag . find ( ".left .container-view-client-channel-permissions" ) , tag . find ( ".right .container-view-client-channel-permissions" ) , selected_tab == "clchp" ? < any > options : { } ) ;
setTimeout ( ( ) = > container_tab_list . find ( "." + ( selected_tab || "sg" ) ) . trigger ( 'click' ) , 0 ) ;
return tag . dividerfy ( ) ;
2019-02-17 16:08:10 +01:00
} ,
footer : undefined ,
2019-08-21 10:00:01 +02:00
min_width : "30em" ,
2019-02-17 16:08:10 +01:00
height : "80%" ,
trigger_tab : false ,
full_size : true
} ) ;
2019-04-26 23:50:21 +02:00
const tag = modal . htmlTag ;
2019-08-21 10:00:01 +02:00
tag . find ( ".modal-body" ) . addClass ( "modal-permission-editor" ) ;
if ( selected_tab )
setTimeout ( ( ) = > tag . find ( ".tab-header .entry[x-id=" + selected_tab + "]" ) . first ( ) . trigger ( "click" ) , 1 ) ;
2019-02-17 16:08:10 +01:00
tag . find ( ".btn_close" ) . on ( 'click' , ( ) = > {
2019-04-26 23:50:21 +02:00
modal . close ( ) ;
2019-02-17 16:08:10 +01:00
} ) ;
2018-12-02 18:55:08 +01:00
2019-04-26 23:50:21 +02:00
return modal ;
2018-09-30 21:50:59 +02:00
}
2019-08-21 10:00:01 +02:00
function build_channel_tree ( connection : ConnectionHandler , channel_list : JQuery , selected_channel : number , select_callback : ( channel : ChannelEntry , icon_update : ( id : number ) = > any ) = > any ) {
2019-04-04 21:47:52 +02:00
const root = connection . channelTree . get_first_channel ( ) ;
2019-02-17 16:08:10 +01:00
if ( ! root ) return ;
2019-08-21 10:00:01 +02:00
const build_channel = ( channel : ChannelEntry , level : number ) = > {
let tag = $ . spawn ( "div" ) . addClass ( "channel" ) . css ( "padding-left" , "calc(0.25em + " + ( level * 16 ) + "px)" ) . attr ( "channel-id" , channel . channelId ) ;
2019-05-25 12:26:24 +02:00
let icon_tag = connection . fileManager . icons . generateTag ( channel . properties . channel_icon_id ) ;
icon_tag . appendTo ( tag ) ;
const _update_icon = icon_id = > icon_tag . replaceWith ( icon_tag = connection . fileManager . icons . generateTag ( icon_id ) ) ;
2018-09-30 21:50:59 +02:00
{
let name = $ . spawn ( "a" ) . text ( channel . channelName ( ) + " (" + channel . channelId + ")" ) . addClass ( "name" ) ;
name . appendTo ( tag ) ;
}
tag . on ( 'click' , event = > {
channel_list . find ( ".selected" ) . removeClass ( "selected" ) ;
tag . addClass ( "selected" ) ;
2019-05-25 12:26:24 +02:00
select_callback ( channel , _update_icon ) ;
2018-09-30 21:50:59 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
return tag ;
} ;
2019-08-21 10:00:01 +02:00
const build_channels = ( root : ChannelEntry , level : number ) = > {
build_channel ( root , level ) . appendTo ( channel_list ) ;
const child_head = root . children ( false ) . find ( e = > e . channel_previous === undefined ) ;
if ( child_head )
build_channels ( child_head , level + 1 ) ;
if ( root . channel_next )
build_channels ( root . channel_next , level )
2019-02-17 16:08:10 +01:00
} ;
2019-08-21 10:00:01 +02:00
build_channels ( root , 0 ) ;
let selected_channel_tag = channel_list . find ( ".channel[channel-id=" + selected_channel + "]" ) ;
if ( ! selected_channel_tag || selected_channel_tag . length < 1 )
selected_channel_tag = channel_list . find ( '.channel' ) . first ( ) ;
setTimeout ( ( ) = > selected_channel_tag . trigger ( 'click' ) , 0 ) ;
2018-09-30 21:50:59 +02:00
}
2019-08-21 10:00:01 +02:00
function apply_client_channel_permission ( connection : ConnectionHandler , editor : AbstractPermissionEditor , tab_left : JQuery , tab_right : JQuery , options : OptionsClientChannelPermissions ) {
2019-02-17 16:08:10 +01:00
let current_cldbid : number = 0 ;
let current_channel : ChannelEntry ;
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
/* the editor */
{
2019-08-21 10:00:01 +02:00
const pe_client = tab_right . find ( ".permission-editor" ) ;
tab_right . on ( 'show' , event = > {
editor . set_toggle_button ( undefined , undefined ) ;
pe_client . append ( editor . html_tag ( ) ) ;
2019-04-04 21:47:52 +02:00
if ( connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_CLIENT_PERMISSION_LIST ) . granted ( 1 ) ) {
2019-02-17 16:08:10 +01:00
if ( current_cldbid && current_channel )
editor . set_mode ( PermissionEditorMode . VISIBLE ) ;
else
editor . set_mode ( PermissionEditorMode . UNSET ) ;
} else {
editor . set_mode ( PermissionEditorMode . NO_PERMISSION ) ;
return ;
}
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
editor . set_listener_update ( ( ) = > {
if ( ! current_cldbid || ! current_channel ) return ;
2018-09-30 21:50:59 +02:00
2019-04-04 21:47:52 +02:00
connection . permissions . requestClientChannelPermissions ( current_cldbid , current_channel . channelId ) . then ( result = > {
2019-02-17 16:08:10 +01:00
editor . set_permissions ( result ) ;
editor . set_mode ( PermissionEditorMode . VISIBLE ) ;
} ) . catch ( error = > {
console . log ( error ) ; //TODO handling?
} ) ;
2018-09-30 21:50:59 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
2019-08-21 10:00:01 +02:00
/* TODO: Error handling? */
editor . set_listener ( async ( permission , value ) = > {
2019-02-17 16:08:10 +01:00
if ( ! current_cldbid )
2019-08-21 10:00:01 +02:00
throw "unset client" ;
2019-02-17 16:08:10 +01:00
if ( ! current_channel )
2019-08-21 10:00:01 +02:00
throw "unset channel" ;
2019-02-17 16:08:10 +01:00
if ( value . remove ) {
/* remove the permission */
if ( typeof ( value . value ) !== "undefined" ) {
log . info ( LogCategory . PERMISSIONS , tr ( "Removing client channel permission %s. permission.id: %o" ) ,
permission . name ,
permission . id ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channelclientdelperm" , {
2019-02-17 16:08:10 +01:00
cldbid : current_cldbid ,
cid : current_channel.channelId ,
permid : permission.id ,
} ) ;
} else {
log . info ( LogCategory . PERMISSIONS , tr ( "Removing client channel grant permission %s. permission.id: %o" ) ,
permission . name ,
permission . id_grant ( ) ,
value . granted ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channelclientdelperm" , {
2019-02-17 16:08:10 +01:00
cldbid : current_cldbid ,
cid : current_channel.channelId ,
permid : permission.id_grant ( ) ,
} ) ;
}
} else {
/* add the permission */
if ( typeof ( value . value ) !== "undefined" ) {
log . info ( LogCategory . PERMISSIONS , tr ( "Adding or updating client channel permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}" ) ,
permission . name ,
permission . id ,
value . value ,
value . flag_skip ,
value . flag_negate
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channelclientaddperm" , {
2019-02-17 16:08:10 +01:00
cldbid : current_cldbid ,
cid : current_channel.channelId ,
permid : permission.id ,
permvalue : value.value ,
permskip : value.flag_skip ,
2019-08-21 10:00:01 +02:00
permnegated : value.flag_negate
2019-02-17 16:08:10 +01:00
} ) ;
} else {
log . info ( LogCategory . PERMISSIONS , tr ( "Adding or updating client channel grant permission %s. permission.{id: %o, value: %o}" ) ,
permission . name ,
permission . id_grant ( ) ,
value . granted ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channelclientaddperm" , {
2019-02-17 16:08:10 +01:00
cldbid : current_cldbid ,
cid : current_channel.channelId ,
permid : permission.id_grant ( ) ,
permvalue : value.granted ,
permskip : false ,
2019-08-21 10:00:01 +02:00
permnegated : false
2019-02-17 16:08:10 +01:00
} ) ;
}
}
2018-09-30 21:50:59 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
/* FIXME: Use cached permissions */
editor . trigger_update ( ) ;
} ) ;
}
2018-09-30 21:50:59 +02:00
2019-08-21 10:00:01 +02:00
build_channel_tree ( connection , tab_left . find ( ".list-channel .entries" ) , options . channel_id || 0 , channel = > {
2019-02-17 16:08:10 +01:00
if ( current_channel == channel ) return ;
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
current_channel = channel ;
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
/* TODO: Test for visibility */
editor . trigger_update ( ) ;
2018-09-30 21:50:59 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
{
2019-08-21 10:00:01 +02:00
const tag_select = tab_left . find ( ".client-select" ) ;
const tag_select_uid = tag_select . find ( "input" ) ;
const tag_select_error = tag_select . find ( ".invalid-feedback" ) ;
const tag_client_name = tab_left . find ( ".client-name" ) ;
const tag_client_uid = tab_left . find ( ".client-uid" ) ;
const tag_client_dbid = tab_left . find ( ".client-dbid" ) ;
2019-02-17 16:08:10 +01:00
const resolve_client = ( ) = > {
let client_uid = tag_select_uid . val ( ) as string ;
2019-04-04 21:47:52 +02:00
connection . serverConnection . command_helper . info_from_uid ( client_uid ) . then ( result = > {
2019-02-17 16:08:10 +01:00
if ( ! result || result . length == 0 ) return Promise . reject ( "invalid data" ) ;
2019-08-21 10:00:01 +02:00
tag_select . removeClass ( 'is-invalid' ) ;
2019-02-17 16:08:10 +01:00
tag_client_name . val ( result [ 0 ] . client_nickname ) ;
tag_client_uid . val ( result [ 0 ] . client_unique_id ) ;
tag_client_dbid . val ( result [ 0 ] . client_database_id ) ;
current_cldbid = result [ 0 ] . client_database_id ;
editor . trigger_update ( ) ;
} ) . catch ( error = > {
console . log ( error ) ;
if ( error instanceof CommandResult ) {
if ( error . id == ErrorID . EMPTY_RESULT )
error = "unknown client" ;
else
error = error . extra_message || error . message ;
}
tag_client_name . val ( "" ) ;
tag_client_uid . val ( "" ) ;
tag_client_dbid . val ( "" ) ;
tag_select_error . text ( error ) ;
2019-08-21 10:00:01 +02:00
tag_select . addClass ( 'is-invalid' ) ;
2019-02-17 16:08:10 +01:00
editor . set_mode ( PermissionEditorMode . UNSET ) ;
2018-09-30 21:50:59 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
} ;
2019-08-21 10:00:01 +02:00
tag_select_uid . on ( 'change' , event = > resolve_client ( ) ) ;
if ( options . unique_id ) {
tag_select_uid . val ( options . unique_id ) ;
setTimeout ( ( ) = > resolve_client ( ) ) ;
}
2019-02-17 16:08:10 +01:00
}
}
2019-08-21 10:00:01 +02:00
function apply_client_permission ( connection : ConnectionHandler , editor : AbstractPermissionEditor , tab_left : JQuery , tab_right : JQuery , options : OptionsClientPermissions ) {
2019-02-17 16:08:10 +01:00
let current_cldbid : number = 0 ;
/* the editor */
{
2019-08-21 10:00:01 +02:00
const pe_client = tab_right . find ( "permission-editor.client" ) ;
tab_right . on ( 'show' , event = > {
editor . set_toggle_button ( undefined , undefined ) ;
pe_client . append ( editor . html_tag ( ) ) ;
2019-04-04 21:47:52 +02:00
if ( connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_CLIENT_PERMISSION_LIST ) . granted ( 1 ) ) {
2019-02-17 16:08:10 +01:00
if ( current_cldbid )
editor . set_mode ( PermissionEditorMode . VISIBLE ) ;
else
editor . set_mode ( PermissionEditorMode . UNSET ) ;
} else {
editor . set_mode ( PermissionEditorMode . NO_PERMISSION ) ;
return ;
}
editor . set_listener_update ( ( ) = > {
if ( ! current_cldbid ) return ;
2019-04-04 21:47:52 +02:00
connection . permissions . requestClientPermissions ( current_cldbid ) . then ( result = > {
2019-02-17 16:08:10 +01:00
editor . set_permissions ( result ) ;
editor . set_mode ( PermissionEditorMode . VISIBLE ) ;
} ) . catch ( error = > {
console . log ( error ) ; //TODO handling?
} ) ;
2018-09-30 21:50:59 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
2019-08-21 10:00:01 +02:00
/* TODO: Error handling? */
editor . set_listener ( async ( permission , value ) = > {
2019-02-17 16:08:10 +01:00
if ( ! current_cldbid )
2019-08-21 10:00:01 +02:00
throw "unset client" ;
2019-02-17 16:08:10 +01:00
if ( value . remove ) {
/* remove the permission */
if ( typeof ( value . value ) !== "undefined" ) {
log . info ( LogCategory . PERMISSIONS , tr ( "Removing client permission %s. permission.id: %o" ) ,
permission . name ,
permission . id ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "clientdelperm" , {
2019-02-17 16:08:10 +01:00
cldbid : current_cldbid ,
permid : permission.id ,
} ) ;
} else {
log . info ( LogCategory . PERMISSIONS , tr ( "Removing client grant permission %s. permission.id: %o" ) ,
permission . name ,
permission . id_grant ( ) ,
value . granted ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "clientdelperm" , {
2019-02-17 16:08:10 +01:00
cldbid : current_cldbid ,
permid : permission.id_grant ( ) ,
} ) ;
}
} else {
/* add the permission */
if ( typeof ( value . value ) !== "undefined" ) {
log . info ( LogCategory . PERMISSIONS , tr ( "Adding or updating client permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}" ) ,
permission . name ,
permission . id ,
value . value ,
value . flag_skip ,
value . flag_negate
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "clientaddperm" , {
2019-02-17 16:08:10 +01:00
cldbid : current_cldbid ,
permid : permission.id ,
permvalue : value.value ,
permskip : value.flag_skip ,
2019-08-21 10:00:01 +02:00
permnegated : value.flag_negate
2019-02-17 16:08:10 +01:00
} ) ;
} else {
log . info ( LogCategory . PERMISSIONS , tr ( "Adding or updating client grant permission %s. permission.{id: %o, value: %o}" ) ,
permission . name ,
permission . id_grant ( ) ,
value . granted ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "clientaddperm" , {
2019-02-17 16:08:10 +01:00
cldbid : current_cldbid ,
permid : permission.id_grant ( ) ,
permvalue : value.granted ,
permskip : false ,
2019-08-21 10:00:01 +02:00
permnegated : false
2019-02-17 16:08:10 +01:00
} ) ;
}
}
2018-09-30 21:50:59 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
/* FIXME: Use cached permissions */
editor . trigger_update ( ) ;
} ) ;
}
2019-08-21 10:00:01 +02:00
const tag_select = tab_left . find ( ".client-select" ) ;
const tag_select_uid = tag_select . find ( "input" ) ;
const tag_select_error = tag_select . find ( ".invalid-feedback" ) ;
2019-02-17 16:08:10 +01:00
2019-08-21 10:00:01 +02:00
const tag_client_name = tab_left . find ( ".client-name" ) ;
const tag_client_uid = tab_left . find ( ".client-uid" ) ;
const tag_client_dbid = tab_left . find ( ".client-dbid" ) ;
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
const resolve_client = ( ) = > {
let client_uid = tag_select_uid . val ( ) as string ;
2019-04-04 21:47:52 +02:00
connection . serverConnection . command_helper . info_from_uid ( client_uid ) . then ( result = > {
2018-09-30 21:50:59 +02:00
if ( ! result || result . length == 0 ) return Promise . reject ( "invalid data" ) ;
2019-08-21 10:00:01 +02:00
tag_select . removeClass ( "is-invalid" ) ;
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
tag_client_name . val ( result [ 0 ] . client_nickname ) ;
tag_client_uid . val ( result [ 0 ] . client_unique_id ) ;
tag_client_dbid . val ( result [ 0 ] . client_database_id ) ;
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
current_cldbid = result [ 0 ] . client_database_id ;
editor . trigger_update ( ) ;
2018-09-30 21:50:59 +02:00
} ) . catch ( error = > {
2019-02-17 16:08:10 +01:00
console . log ( error ) ;
if ( error instanceof CommandResult ) {
if ( error . id == ErrorID . EMPTY_RESULT )
error = "unknown client" ;
else
error = error . extra_message || error . message ;
}
tag_client_name . val ( "" ) ;
tag_client_uid . val ( "" ) ;
tag_client_dbid . val ( "" ) ;
tag_select_error . text ( error ) ;
2019-08-21 10:00:01 +02:00
tag_select . addClass ( "is-invalid" ) ;
2019-02-17 16:08:10 +01:00
editor . set_mode ( PermissionEditorMode . UNSET ) ;
2018-09-30 21:50:59 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
} ;
2019-08-21 10:00:01 +02:00
tag_select_uid . on ( 'change' , event = > resolve_client ( ) ) ;
if ( options . unique_id ) {
tag_select_uid . val ( options . unique_id ) ;
setTimeout ( ( ) = > resolve_client ( ) ) ;
}
2018-09-30 21:50:59 +02:00
}
2019-08-21 10:00:01 +02:00
function apply_channel_permission ( connection : ConnectionHandler , editor : AbstractPermissionEditor , tab_left : JQuery , tab_right : JQuery ) {
2019-02-17 16:08:10 +01:00
let current_channel : ChannelEntry | undefined ;
2019-05-25 12:26:24 +02:00
let update_channel_icon : ( id : number ) = > any ;
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
/* the editor */
{
2019-08-21 10:00:01 +02:00
const pe_channel = tab_right . find ( ".permission-editor" ) ;
tab_right . on ( 'show' , event = > {
editor . set_toggle_button ( undefined , undefined ) ;
pe_channel . append ( editor . html_tag ( ) ) ;
2019-04-04 21:47:52 +02:00
if ( connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_CHANNEL_PERMISSION_LIST ) . granted ( 1 ) )
2019-02-17 16:08:10 +01:00
editor . set_mode ( PermissionEditorMode . VISIBLE ) ;
else {
editor . set_mode ( PermissionEditorMode . NO_PERMISSION ) ;
return ;
}
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
editor . set_listener_update ( ( ) = > {
if ( ! current_channel ) return ;
2018-09-30 21:50:59 +02:00
2019-04-04 21:47:52 +02:00
connection . permissions . requestChannelPermissions ( current_channel . channelId ) . then ( result = > editor . set_permissions ( result ) ) . catch ( error = > {
2019-02-17 16:08:10 +01:00
console . log ( error ) ; //TODO handling?
} ) ;
2018-09-30 21:50:59 +02:00
} ) ;
2019-08-21 10:00:01 +02:00
editor . set_listener ( async ( permission , value ) = > {
2019-02-17 16:08:10 +01:00
if ( ! current_channel )
2019-08-21 10:00:01 +02:00
throw "unset channel" ;
2019-02-17 16:08:10 +01:00
if ( value . remove ) {
/* remove the permission */
if ( typeof ( value . value ) !== "undefined" ) {
log . info ( LogCategory . PERMISSIONS , tr ( "Removing channel permission %s. permission.id: %o" ) ,
permission . name ,
permission . id ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channeldelperm" , {
2019-02-17 16:08:10 +01:00
cid : current_channel.channelId ,
permid : permission.id ,
2019-05-25 12:26:24 +02:00
} ) . then ( e = > {
if ( permission . name === "i_icon_id" && update_channel_icon )
update_channel_icon ( undefined ) ;
return e ;
2019-02-17 16:08:10 +01:00
} ) ;
} else {
/* TODO Remove this because its totally useless. Remove this from the UI as well */
log . info ( LogCategory . PERMISSIONS , tr ( "Removing channel grant permission %s. permission.id: %o" ) ,
permission . name ,
permission . id_grant ( ) ,
value . granted ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channeldelperm" , {
2019-02-17 16:08:10 +01:00
cid : current_channel.channelId ,
permid : permission.id_grant ( ) ,
} ) ;
}
} else {
/* add the permission */
if ( typeof ( value . value ) !== "undefined" ) {
log . info ( LogCategory . PERMISSIONS , tr ( "Adding or updating channel permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}" ) ,
permission . name ,
permission . id ,
value . value ,
value . flag_skip ,
value . flag_negate
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channeladdperm" , {
2019-02-17 16:08:10 +01:00
cid : current_channel.channelId ,
permid : permission.id ,
permvalue : value.value ,
permskip : value.flag_skip ,
2019-08-21 10:00:01 +02:00
permnegated : value.flag_negate
2019-05-25 12:26:24 +02:00
} ) . then ( e = > {
if ( permission . name === "i_icon_id" && update_channel_icon )
update_channel_icon ( value . value ) ;
return e ;
2019-02-17 16:08:10 +01:00
} ) ;
} else {
/* TODO Remove this because its totally useless. Remove this from the UI as well */
log . info ( LogCategory . PERMISSIONS , tr ( "Adding or updating channel grant permission %s. permission.{id: %o, value: %o}" ) ,
permission . name ,
permission . id_grant ( ) ,
value . granted ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channeladdperm" , {
2019-02-17 16:08:10 +01:00
cid : current_channel.channelId ,
permid : permission.id_grant ( ) ,
permvalue : value.granted ,
permskip : false ,
2019-08-21 10:00:01 +02:00
permnegated : false
2019-02-17 16:08:10 +01:00
} ) ;
}
}
} ) ;
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
/* FIXME: Use cached permissions */
editor . trigger_update ( ) ;
2018-09-30 21:50:59 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
}
2019-08-21 10:00:01 +02:00
let channel_list = tab_left . find ( ".list-channel .entries" ) ;
build_channel_tree ( connection , channel_list , 0 , ( channel , update ) = > {
2019-02-17 16:08:10 +01:00
current_channel = channel ;
2019-05-25 12:26:24 +02:00
update_channel_icon = update ;
2019-02-17 16:08:10 +01:00
editor . trigger_update ( ) ;
2018-09-30 21:50:59 +02:00
} ) ;
}
2019-08-21 10:00:01 +02:00
function apply_channel_groups ( connection : ConnectionHandler , editor : AbstractPermissionEditor , tab_left : JQuery , tab_right : JQuery ) {
2019-02-17 16:08:10 +01:00
let current_group ;
2019-05-25 12:26:24 +02:00
let update_group_icon : ( id : number ) = > any ;
2019-08-21 10:00:01 +02:00
let update_groups : ( selected_group : number ) = > any ;
let update_buttons : ( ) = > any ;
2019-02-17 16:08:10 +01:00
/* the editor */
{
2019-08-21 10:00:01 +02:00
const pe_server = tab_right . find ( ".permission-editor" ) ;
tab_right . on ( 'show' , event = > {
editor . set_toggle_button ( undefined , undefined ) ;
pe_server . append ( editor . html_tag ( ) ) ;
2019-04-04 21:47:52 +02:00
if ( connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_CHANNELGROUP_PERMISSION_LIST ) . granted ( 1 ) )
2019-02-17 16:08:10 +01:00
editor . set_mode ( PermissionEditorMode . VISIBLE ) ;
else {
editor . set_mode ( PermissionEditorMode . NO_PERMISSION ) ;
return ;
}
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
editor . set_listener_update ( ( ) = > {
if ( ! current_group ) return ;
2018-09-30 21:50:59 +02:00
2019-04-04 21:47:52 +02:00
connection . groups . request_permissions ( current_group ) . then ( result = > editor . set_permissions ( result ) ) . catch ( error = > {
2019-02-17 16:08:10 +01:00
console . log ( error ) ; //TODO handling?
} ) ;
2018-09-30 21:50:59 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
2019-08-21 10:00:01 +02:00
editor . set_listener ( async ( permission , value ) = > {
2019-02-17 16:08:10 +01:00
if ( ! current_group )
2019-08-21 10:00:01 +02:00
throw "unset channel group" ;
2019-02-17 16:08:10 +01:00
if ( value . remove ) {
/* remove the permission */
if ( typeof ( value . value ) !== "undefined" ) {
log . info ( LogCategory . PERMISSIONS , tr ( "Removing channel group permission %s. permission.id: %o" ) ,
permission . name ,
permission . id ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channelgroupdelperm" , {
2019-02-17 16:08:10 +01:00
cgid : current_group.id ,
permid : permission.id ,
2019-05-25 12:26:24 +02:00
} ) . then ( e = > {
if ( permission . name === "i_icon_id" && update_group_icon )
update_group_icon ( undefined ) ;
return e ;
2019-02-17 16:08:10 +01:00
} ) ;
} else {
log . info ( LogCategory . PERMISSIONS , tr ( "Removing channel group grant permission %s. permission.id: %o" ) ,
permission . name ,
permission . id_grant ( ) ,
value . granted ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channelgroupdelperm" , {
2019-02-17 16:08:10 +01:00
cgid : current_group.id ,
permid : permission.id_grant ( ) ,
} ) ;
}
} else {
/* add the permission */
if ( typeof ( value . value ) !== "undefined" ) {
log . info ( LogCategory . PERMISSIONS , tr ( "Adding or updating channel group permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}" ) ,
permission . name ,
permission . id ,
value . value ,
value . flag_skip ,
value . flag_negate
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channelgroupaddperm" , {
2019-02-17 16:08:10 +01:00
cgid : current_group.id ,
permid : permission.id ,
permvalue : value.value ,
permskip : value.flag_skip ,
2019-08-21 10:00:01 +02:00
permnegated : value.flag_negate
2019-05-25 12:26:24 +02:00
} ) . then ( e = > {
if ( permission . name === "i_icon_id" && update_group_icon )
update_group_icon ( value . value ) ;
return e ;
2019-02-17 16:08:10 +01:00
} ) ;
} else {
log . info ( LogCategory . PERMISSIONS , tr ( "Adding or updating channel group grant permission %s. permission.{id: %o, value: %o}" ) ,
permission . name ,
permission . id_grant ( ) ,
value . granted ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "channelgroupaddperm" , {
2019-02-17 16:08:10 +01:00
cgid : current_group.id ,
permid : permission.id_grant ( ) ,
permvalue : value.granted ,
permskip : false ,
2019-08-21 10:00:01 +02:00
permnegated : false
2019-02-17 16:08:10 +01:00
} ) ;
}
}
2018-09-30 21:50:59 +02:00
} ) ;
2019-02-17 16:08:10 +01:00
/* FIXME: Use cached permissions */
editor . trigger_update ( ) ;
} ) ;
}
/* list all channel groups */
2018-09-30 21:50:59 +02:00
{
2019-08-21 10:00:01 +02:00
let group_list = tab_left . find ( ".list-groups .entries" ) ;
update_groups = ( selected_group : number ) = > {
group_list . children ( ) . remove ( ) ;
const allow_query_groups = connection . permissions . neededPermission ( PermissionType . B_SERVERINSTANCE_MODIFY_QUERYGROUP ) . granted ( 1 ) ;
const allow_template_groups = connection . permissions . neededPermission ( PermissionType . B_SERVERINSTANCE_MODIFY_TEMPLATES ) . granted ( 1 ) ;
for ( let group of connection . groups . channelGroups . sort ( GroupManager . sorter ( ) ) ) {
if ( group . type == GroupType . QUERY ) {
if ( ! allow_query_groups )
continue ;
} else if ( group . type == GroupType . TEMPLATE ) {
if ( ! allow_template_groups )
continue ;
}
2019-04-04 21:47:52 +02:00
2019-08-21 10:00:01 +02:00
let tag = $ . spawn ( "div" ) . addClass ( "group" ) . attr ( "group-id" , group . id ) ;
let icon_tag = connection . fileManager . icons . generateTag ( group . properties . iconid ) ;
icon_tag . appendTo ( tag ) ;
const _update_icon = icon_id = > icon_tag . replaceWith ( icon_tag = connection . fileManager . icons . generateTag ( icon_id ) ) ;
{
let name = $ . spawn ( "a" ) . text ( group . name + " (" + group . id + ")" ) . addClass ( "name" ) ;
if ( group . properties . savedb )
name . addClass ( "savedb" ) ;
if ( connection . channelTree . server . properties . virtualserver_default_channel_group == group . id )
name . addClass ( "default" ) ;
name . appendTo ( tag ) ;
}
tag . appendTo ( group_list ) ;
2019-05-25 12:26:24 +02:00
2019-08-21 10:00:01 +02:00
tag . on ( 'click' , event = > {
current_group = group ;
update_group_icon = _update_icon ;
group_list . find ( ".selected" ) . removeClass ( "selected" ) ;
tag . addClass ( "selected" ) ;
update_buttons ( ) ;
//TODO trigger only if the editor is in channel group mode!
editor . trigger_update ( ) ;
} ) ;
tag . on ( 'contextmenu' , event = > {
if ( event . isDefaultPrevented ( ) )
return ;
contextmenu . spawn_context_menu ( event . pageX , event . pageY , {
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Create a channel group" ) ,
icon_class : 'client-add' ,
invalidPermission : ! connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_CHANNELGROUP_CREATE ) . granted ( 1 ) ,
callback : ( ) = > tab_left . find ( ".button-add" ) . trigger ( 'click' )
} , {
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Rename channel group" ) ,
icon_class : 'client-edit' ,
invalidPermission : ! connection . permissions . neededPermission ( PermissionType . I_CHANNEL_GROUP_MODIFY_POWER ) . granted ( current_group . requiredModifyPower ) ,
callback : ( ) = > tab_left . find ( ".button-rename" ) . trigger ( 'click' )
} , {
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Duplicate channel group" ) ,
icon_class : 'client-copy' ,
callback : ( ) = > tab_left . find ( ".button-duplicate" ) . trigger ( 'click' )
} , {
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Delete channel group" ) ,
icon_class : 'client-delete' ,
invalidPermission : ! connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_CHANNELGROUP_DELETE ) . granted ( 1 ) ,
callback : ( ) = > tab_left . find ( ".button-delete" ) . trigger ( 'click' )
} ) ;
event . preventDefault ( ) ;
} ) ;
if ( group . id === selected_group ) {
setTimeout ( ( ) = > tag . trigger ( 'click' ) , 0 ) ;
selected_group = undefined ;
}
}
/* because the server menu is the first which will be shown */
if ( typeof ( selected_group ) !== "undefined" ) {
setTimeout ( ( ) = > group_list . find ( '.group' ) . first ( ) . trigger ( 'click' ) , 0 ) ;
2018-09-30 21:50:59 +02:00
}
2019-08-21 10:00:01 +02:00
} ;
2018-09-30 21:50:59 +02:00
2019-08-21 10:00:01 +02:00
tab_left . find ( ".list-groups" ) . on ( 'contextmenu' , event = > {
if ( event . isDefaultPrevented ( ) )
return ;
2018-09-30 21:50:59 +02:00
2019-08-21 10:00:01 +02:00
contextmenu . spawn_context_menu ( event . pageX , event . pageY , {
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Create a channel group" ) ,
icon_class : 'client-add' ,
callback : ( ) = > tab_left . find ( ".button-add" ) . trigger ( 'click' )
2019-02-17 16:08:10 +01:00
} ) ;
2019-08-21 10:00:01 +02:00
event . preventDefault ( ) ;
} ) ;
}
{
const container_buttons = tab_left . find ( ".container-buttons" ) ;
const button_add = container_buttons . find ( ".button-add" ) ;
const button_rename = container_buttons . find ( ".button-rename" ) ;
const button_duplicate = container_buttons . find ( ".button-duplicate" ) ;
const button_delete = container_buttons . find ( ".button-delete" ) ;
button_add . prop ( "disabled" , ! connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_CHANNELGROUP_CREATE ) . granted ( 1 ) ) ;
button_delete . prop ( "disabled" , ! connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_CHANNELGROUP_CREATE ) . granted ( 1 ) ) ;
update_buttons = ( ) = > {
const permission_modify = current_group && connection . permissions . neededPermission ( PermissionType . I_CHANNEL_GROUP_MODIFY_POWER ) . granted ( current_group . requiredModifyPower ) ;
button_rename . prop ( "disabled" , ! permission_modify ) ;
button_duplicate . prop ( "disabled" , ! connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_CHANNELGROUP_CREATE ) . granted ( 1 ) ) ;
} ;
2018-09-30 21:50:59 +02:00
2019-08-21 10:00:01 +02:00
button_add . on ( 'click' , ( ) = > {
spawnGroupAdd ( false , connection . permissions , ( name , type ) = > name . length > 0 && ! connection . groups . channelGroups . find ( e = > e . target == GroupTarget . CHANNEL && e . name . toLowerCase ( ) === name . toLowerCase ( ) && e . type == type ) , ( name , type ) = > {
console . log ( "Creating channel group: %o, %o" , name , type ) ;
connection . serverConnection . send_command ( 'channelgroupadd' , {
name : name ,
type : type
} ) . then ( ( ) = > {
createInfoModal ( tr ( "Group created" ) , tr ( "The channel group has been created." ) ) . open ( ) ;
update_groups ( 0 ) ; //TODO: May get the created group?
} ) . catch ( error = > {
console . warn ( tr ( "Failed to create channel group: %o" ) , error ) ;
if ( error instanceof CommandResult ) {
error = error . extra_message || error . message ;
}
createErrorModal ( tr ( "Failed to create group" ) , MessageHelper . formatMessage ( tr ( "Failed to create group:{:br:}" ) , error ) ) . open ( ) ;
} ) ;
} ) ;
} ) ;
button_rename . on ( 'click' , ( ) = > {
if ( ! current_group )
return ;
createInputModal ( tr ( "Rename group" ) , tr ( "Enter the new group name" ) , name = > name . length > 0 && ! connection . groups . channelGroups . find ( e = > e . target == GroupTarget . CHANNEL && e . name . toLowerCase ( ) === name . toLowerCase ( ) && e . type == current_group . type ) , result = > {
if ( typeof ( result ) !== "string" || ! result )
return ;
connection . serverConnection . send_command ( 'channelgrouprename' , {
cgid : current_group.id ,
name : result
} ) . then ( ( ) = > {
createInfoModal ( tr ( "Group renamed" ) , tr ( "The channel group has been renamed." ) ) . open ( ) ;
update_groups ( current_group . id ) ;
} ) . catch ( error = > {
console . warn ( tr ( "Failed to rename channel group: %o" ) , error ) ;
if ( error instanceof CommandResult ) {
error = error . extra_message || error . message ;
}
createErrorModal ( tr ( "Failed to rename group" ) , MessageHelper . formatMessage ( tr ( "Failed to rename group:{:br:}" ) , error ) ) . open ( ) ;
} ) ;
} ) . open ( ) ;
} ) ;
button_duplicate . on ( 'click' , ( ) = > {
createErrorModal ( tr ( "Not implemented yet" ) , tr ( "This function hasn't been implemented yet!" ) ) . open ( ) ;
} ) ;
button_delete . on ( 'click' , ( ) = > {
if ( ! current_group )
return ;
spawnYesNo ( tr ( "Are you sure?" ) , MessageHelper . formatMessage ( tr ( "Do you really want to delete the group {}?" ) , current_group . name ) , result = > {
if ( result !== true )
return ;
connection . serverConnection . send_command ( "channelgroupdel" , {
cgid : current_group.id ,
force : true
} ) . then ( ( ) = > {
createInfoModal ( tr ( "Group deleted" ) , tr ( "The channel group has been deleted." ) ) . open ( ) ;
update_groups ( 0 ) ;
} ) . catch ( error = > {
console . warn ( tr ( "Failed to delete channel group: %o" ) , error ) ;
if ( error instanceof CommandResult ) {
error = error . extra_message || error . message ;
}
createErrorModal ( tr ( "Failed to delete group" ) , MessageHelper . formatMessage ( tr ( "Failed to delete group:{:br:}" ) , error ) ) . open ( ) ;
} ) ;
} ) ;
} ) ;
2019-02-17 16:08:10 +01:00
}
2019-08-21 10:00:01 +02:00
update_groups ( 0 ) ;
2018-09-30 21:50:59 +02:00
}
2019-08-21 10:00:01 +02:00
function apply_server_groups ( connection : ConnectionHandler , editor : AbstractPermissionEditor , tab_left : JQuery , tab_right : JQuery ) {
2019-05-25 13:13:03 +02:00
let current_group : Group ;
2019-08-21 10:00:01 +02:00
let current_group_changed : ( ( ) = > any ) [ ] = [ ] ;
2018-09-30 21:50:59 +02:00
2019-08-21 10:00:01 +02:00
let update_buttons : ( ) = > any ;
2019-02-17 16:08:10 +01:00
/* list all groups */
2019-08-21 10:00:01 +02:00
let update_icon : ( ( icon_id : number ) = > any ) [ ] = [ ] ;
let update_groups : ( selected_group : number ) = > any ;
2018-09-30 21:50:59 +02:00
{
2019-08-21 10:00:01 +02:00
let group_list = tab_left . find ( ".container-group-list .list-groups .entries" ) ;
let group_list_update_icon : ( i : number ) = > any ;
update_icon . push ( i = > group_list_update_icon ( i ) ) ;
update_groups = ( selected_group : number ) = > {
group_list . children ( ) . remove ( ) ;
const allow_query_groups = connection . permissions . neededPermission ( PermissionType . B_SERVERINSTANCE_MODIFY_QUERYGROUP ) . granted ( 1 ) ;
const allow_template_groups = connection . permissions . neededPermission ( PermissionType . B_SERVERINSTANCE_MODIFY_TEMPLATES ) . granted ( 1 ) ;
for ( const group of connection . groups . serverGroups . sort ( GroupManager . sorter ( ) ) ) {
if ( group . type == GroupType . QUERY ) {
if ( ! allow_query_groups )
continue ;
} else if ( group . type == GroupType . TEMPLATE ) {
if ( ! allow_template_groups )
continue ;
}
let tag = $ . spawn ( "div" ) . addClass ( "group" ) . attr ( "group-id" , group . id ) ;
let icon_tag = connection . fileManager . icons . generateTag ( group . properties . iconid ) ;
icon_tag . appendTo ( tag ) ;
const _update_icon = icon_id = > icon_tag . replaceWith ( icon_tag = connection . fileManager . icons . generateTag ( icon_id ) ) ;
{
let name = $ . spawn ( "div" ) . text ( group . name + " (" + group . id + ")" ) . addClass ( "name" ) ;
if ( group . properties . savedb )
name . addClass ( "savedb" ) ;
if ( connection . channelTree . server . properties . virtualserver_default_server_group == group . id )
name . addClass ( "default" ) ;
name . appendTo ( tag ) ;
}
tag . appendTo ( group_list ) ;
tag . on ( 'click' , event = > {
if ( current_group === group )
return ;
current_group = group ;
group_list_update_icon = _update_icon ;
if ( update_buttons )
update_buttons ( ) ;
for ( const entry of current_group_changed )
entry ( ) ;
group_list . find ( ".selected" ) . removeClass ( "selected" ) ;
tag . addClass ( "selected" ) ;
editor . trigger_update ( ) ;
} ) ;
tag . on ( 'contextmenu' , event = > {
if ( event . isDefaultPrevented ( ) )
return ;
contextmenu . spawn_context_menu ( event . pageX , event . pageY , {
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Create a server group" ) ,
icon_class : 'client-add' ,
invalidPermission : ! connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_SERVERGROUP_CREATE ) . granted ( 1 ) ,
callback : ( ) = > tab_left . find ( ".button-add" ) . trigger ( 'click' )
} , {
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Rename server group" ) ,
icon_class : 'client-edit' ,
invalidPermission : ! connection . permissions . neededPermission ( PermissionType . I_SERVER_GROUP_MODIFY_POWER ) . granted ( current_group . requiredModifyPower ) ,
callback : ( ) = > tab_left . find ( ".button-rename" ) . trigger ( 'click' )
} , {
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Duplicate server group" ) ,
icon_class : 'client-copy' ,
callback : ( ) = > tab_left . find ( ".button-duplicate" ) . trigger ( 'click' )
} , {
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Delete server group" ) ,
icon_class : 'client-delete' ,
invalidPermission : ! connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_SERVERGROUP_DELETE ) . granted ( 1 ) ,
callback : ( ) = > tab_left . find ( ".button-delete" ) . trigger ( 'click' )
} ) ;
event . preventDefault ( ) ;
} ) ;
if ( group . id === selected_group ) {
setTimeout ( ( ) = > tag . trigger ( 'click' ) , 0 ) ;
selected_group = undefined ;
}
2019-04-04 21:47:52 +02:00
}
2019-05-25 12:20:57 +02:00
2019-08-21 10:00:01 +02:00
/* because the server menu is the first which will be shown */
if ( typeof ( selected_group ) !== "undefined" ) {
setTimeout ( ( ) = > group_list . find ( '.group' ) . first ( ) . trigger ( 'click' ) , 0 ) ;
2018-09-30 21:50:59 +02:00
}
2019-08-21 10:00:01 +02:00
} ;
2018-09-30 21:50:59 +02:00
2019-05-25 13:13:03 +02:00
2019-08-21 10:00:01 +02:00
tab_left . find ( ".list-groups" ) . on ( 'contextmenu' , event = > {
if ( event . isDefaultPrevented ( ) )
return ;
2019-05-25 13:13:03 +02:00
2019-08-21 10:00:01 +02:00
contextmenu . spawn_context_menu ( event . pageX , event . pageY , {
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Create a server group" ) ,
icon_class : 'client-add' ,
callback : ( ) = > tab_left . find ( ".button-add" ) . trigger ( 'click' )
2018-09-30 21:50:59 +02:00
} ) ;
2019-08-21 10:00:01 +02:00
event . preventDefault ( ) ;
} ) ;
}
{
const container_buttons = tab_left . find ( ".container-group-list .container-buttons" ) ;
const button_add = container_buttons . find ( ".button-add" ) ;
const button_rename = container_buttons . find ( ".button-rename" ) ;
const button_duplicate = container_buttons . find ( ".button-duplicate" ) ;
const button_delete = container_buttons . find ( ".button-delete" ) ;
button_add . prop ( "disabled" , ! connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_SERVERGROUP_CREATE ) . granted ( 1 ) ) ;
button_delete . prop ( "disabled" , ! connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_SERVERGROUP_DELETE ) . granted ( 1 ) ) ;
update_buttons = ( ) = > {
const permission_modify = current_group && connection . permissions . neededPermission ( PermissionType . I_SERVER_GROUP_MODIFY_POWER ) . granted ( current_group . requiredModifyPower ) ;
button_rename . prop ( "disabled" , ! permission_modify ) ;
button_duplicate . prop ( "disabled" , ! connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_SERVERGROUP_CREATE ) . granted ( 1 ) ) ;
} ;
button_add . on ( 'click' , ( ) = > {
spawnGroupAdd ( true , connection . permissions , ( name , type ) = > name . length > 0 && ! connection . groups . serverGroups . find ( e = > e . target == GroupTarget . SERVER && e . name . toLowerCase ( ) === name . toLowerCase ( ) && e . type == type ) , ( name , type ) = > {
console . log ( "Creating group: %o, %o" , name , type ) ;
connection . serverConnection . send_command ( 'servergroupadd' , {
name : name ,
type : type
} ) . then ( ( ) = > {
createInfoModal ( tr ( "Group created" ) , tr ( "The server group has been created." ) ) . open ( ) ;
update_groups ( 0 ) ; //TODO: May get the created group?
} ) . catch ( error = > {
console . warn ( tr ( "Failed to create server group: %o" ) , error ) ;
if ( error instanceof CommandResult ) {
error = error . extra_message || error . message ;
}
createErrorModal ( tr ( "Failed to create group" ) , MessageHelper . formatMessage ( tr ( "Failed to create group:{:br:}" ) , error ) ) . open ( ) ;
} ) ;
} ) ;
} ) ;
button_rename . on ( 'click' , ( ) = > {
if ( ! current_group )
return ;
createInputModal ( tr ( "Rename group" ) , tr ( "Enter the new group name" ) , name = > name . length > 0 && ! connection . groups . serverGroups . find ( e = > e . target == GroupTarget . SERVER && e . name . toLowerCase ( ) === name . toLowerCase ( ) && e . type == current_group . type ) , result = > {
if ( typeof ( result ) !== "string" || ! result )
return ;
connection . serverConnection . send_command ( 'servergrouprename' , {
sgid : current_group.id ,
name : result
} ) . then ( ( ) = > {
createInfoModal ( tr ( "Group renamed" ) , tr ( "The server group has been renamed." ) ) . open ( ) ;
update_groups ( current_group . id ) ;
} ) . catch ( error = > {
console . warn ( tr ( "Failed to rename server group: %o" ) , error ) ;
if ( error instanceof CommandResult ) {
error = error . extra_message || error . message ;
}
createErrorModal ( tr ( "Failed to rename group" ) , MessageHelper . formatMessage ( tr ( "Failed to rename group:{:br:}" ) , error ) ) . open ( ) ;
} ) ;
} ) . open ( ) ;
} ) ;
button_duplicate . on ( 'click' , ( ) = > {
createErrorModal ( tr ( "Not implemented yet" ) , tr ( "This function hasn't been implemented yet!" ) ) . open ( ) ;
} ) ;
2019-02-17 16:08:10 +01:00
2019-08-21 10:00:01 +02:00
button_delete . on ( 'click' , ( ) = > {
if ( ! current_group )
return ;
spawnYesNo ( tr ( "Are you sure?" ) , MessageHelper . formatMessage ( tr ( "Do you really want to delete the group {}?" ) , current_group . name ) , result = > {
if ( result !== true )
return ;
connection . serverConnection . send_command ( "servergroupdel" , {
sgid : current_group.id ,
force : true
} ) . then ( ( ) = > {
createInfoModal ( tr ( "Group deleted" ) , tr ( "The server group has been deleted." ) ) . open ( ) ;
update_groups ( 0 ) ;
} ) . catch ( error = > {
console . warn ( tr ( "Failed to delete server group: %o" ) , error ) ;
if ( error instanceof CommandResult ) {
error = error . extra_message || error . message ;
}
createErrorModal ( tr ( "Failed to delete group" ) , MessageHelper . formatMessage ( tr ( "Failed to delete group:{:br:}" ) , error ) ) . open ( ) ;
} ) ;
} ) ;
} ) ;
2018-09-30 21:50:59 +02:00
}
2019-08-21 10:00:01 +02:00
update_groups ( 0 ) ;
2018-09-30 21:50:59 +02:00
2019-02-17 16:08:10 +01:00
/* the editor */
{
2019-08-21 10:00:01 +02:00
const pe_server = tab_right . find ( ".permission-editor" ) ;
tab_right . on ( 'show' , event = > {
pe_server . append ( editor . html_tag ( ) ) ;
2019-04-04 21:47:52 +02:00
if ( connection . permissions . neededPermission ( PermissionType . B_VIRTUALSERVER_SERVERGROUP_PERMISSION_LIST ) . granted ( 1 ) )
2019-02-17 16:08:10 +01:00
editor . set_mode ( PermissionEditorMode . VISIBLE ) ;
else {
editor . set_mode ( PermissionEditorMode . NO_PERMISSION ) ;
return ;
}
editor . set_listener_update ( ( ) = > {
2019-08-21 10:00:01 +02:00
console . log ( "Updating permissions" ) ;
2019-04-04 21:47:52 +02:00
connection . groups . request_permissions ( current_group ) . then ( result = > editor . set_permissions ( result ) ) . catch ( error = > {
2019-02-17 16:08:10 +01:00
console . log ( error ) ; //TODO handling?
} ) ;
} ) ;
2018-09-30 21:50:59 +02:00
2019-08-21 10:00:01 +02:00
editor . set_listener ( async ( permission , value ) = > {
2019-02-17 16:08:10 +01:00
if ( ! current_group )
2019-08-21 10:00:01 +02:00
throw "unset server group" ;
2019-02-17 16:08:10 +01:00
if ( value . remove ) {
/* remove the permission */
if ( typeof ( value . value ) !== "undefined" ) {
log . info ( LogCategory . PERMISSIONS , tr ( "Removing server group permission %s. permission.id: %o" ) ,
permission . name ,
permission . id ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "servergroupdelperm" , {
2019-02-17 16:08:10 +01:00
sgid : current_group.id ,
permid : permission.id ,
2019-05-25 12:20:57 +02:00
} ) . then ( e = > {
2019-08-21 10:00:01 +02:00
if ( permission . name === "i_icon_id" )
for ( const c of update_icon )
c ( 0 ) ;
2019-05-25 12:20:57 +02:00
return e ;
2019-02-17 16:08:10 +01:00
} ) ;
} else {
log . info ( LogCategory . PERMISSIONS , tr ( "Removing server group grant permission %s. permission.id: %o" ) ,
permission . name ,
permission . id_grant ( ) ,
value . granted ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "servergroupdelperm" , {
2019-02-17 16:08:10 +01:00
sgid : current_group.id ,
permid : permission.id_grant ( ) ,
} ) ;
}
} else {
/* add the permission */
if ( typeof ( value . value ) !== "undefined" ) {
log . info ( LogCategory . PERMISSIONS , tr ( "Adding or updating server group permission %s. permission.{id: %o, value: %o, flag_skip: %o, flag_negate: %o}" ) ,
permission . name ,
permission . id ,
value . value ,
value . flag_skip ,
value . flag_negate
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "servergroupaddperm" , {
2019-02-17 16:08:10 +01:00
sgid : current_group.id ,
permid : permission.id ,
permvalue : value.value ,
permskip : value.flag_skip ,
2019-08-21 10:00:01 +02:00
permnegated : value.flag_negate
2019-05-25 12:20:57 +02:00
} ) . then ( e = > {
2019-08-21 10:00:01 +02:00
if ( permission . name === "i_icon_id" )
for ( const c of update_icon )
c ( value . value ) ;
2019-05-25 12:20:57 +02:00
return e ;
2019-02-17 16:08:10 +01:00
} ) ;
} else {
log . info ( LogCategory . PERMISSIONS , tr ( "Adding or updating server group grant permission %s. permission.{id: %o, value: %o}" ) ,
permission . name ,
permission . id_grant ( ) ,
value . granted ,
) ;
2019-08-21 10:00:01 +02:00
await connection . serverConnection . send_command ( "servergroupaddperm" , {
2019-02-17 16:08:10 +01:00
sgid : current_group.id ,
permid : permission.id_grant ( ) ,
permvalue : value.granted ,
permskip : false ,
2019-08-21 10:00:01 +02:00
permnegated : false
2019-02-17 16:08:10 +01:00
} ) ;
}
}
} ) ;
editor . trigger_update ( ) ;
} ) ;
}
2019-05-25 13:13:03 +02:00
/* client list */
{
2019-08-21 10:00:01 +02:00
//container-client-list container-group-list
let clients_visible = false ;
let selected_client : {
tag : JQuery ,
dbid : number
} ;
const container_client_list = tab_left . find ( ".container-client-list" ) . addClass ( "hidden" ) ;
const container_group_list = tab_left . find ( ".container-group-list" ) ;
const container_selected_group = container_client_list . find ( ".container-current-group" ) ;
const container_clients = container_client_list . find ( ".list-clients .entries" ) ;
const input_filter = container_client_list . find ( ".filter-client-list" ) ;
const button_add = container_client_list . find ( ".button-add" ) ;
const button_delete = container_client_list . find ( ".button-delete" ) ;
2019-05-25 13:13:03 +02:00
const update_filter = ( ) = > {
const filter_text = ( input_filter . val ( ) || "" ) . toString ( ) . toLowerCase ( ) ;
if ( ! filter_text ) {
2019-08-21 10:00:01 +02:00
container_clients . find ( ".entry" ) . css ( 'display' , 'block' ) ;
2019-05-25 13:13:03 +02:00
} else {
2019-08-21 10:00:01 +02:00
const entries = container_clients . find ( ".entry" ) ;
2019-05-25 13:13:03 +02:00
for ( const _entry of entries ) {
const entry = $ ( _entry ) ;
if ( entry . attr ( "search-string" ) . toLowerCase ( ) . indexOf ( filter_text ) !== - 1 )
entry . css ( 'display' , 'block' ) ;
else
entry . css ( 'display' , 'none' ) ;
}
}
} ;
const update_client_list = ( ) = > {
2019-08-21 10:00:01 +02:00
container_clients . empty ( ) ;
button_delete . prop ( 'disabled' , true ) ;
2019-05-25 13:13:03 +02:00
connection . serverConnection . command_helper . request_clients_by_server_group ( current_group . id ) . then ( clients = > {
for ( const client of clients ) {
2019-08-21 10:00:01 +02:00
const tag = $ . spawn ( "div" ) . addClass ( "client" ) . text ( client . client_nickname ) ;
2019-05-25 13:13:03 +02:00
tag . attr ( "search-string" , client . client_nickname + "-" + client . client_unique_identifier + "-" + client . client_database_id ) ;
2019-08-21 10:00:01 +02:00
container_clients . append ( tag ) ;
2019-05-25 13:13:03 +02:00
tag . on ( 'click contextmenu' , event = > {
2019-08-21 10:00:01 +02:00
container_clients . find ( ".selected" ) . removeClass ( "selected" ) ;
2019-05-25 13:13:03 +02:00
tag . addClass ( "selected" ) ;
2019-08-21 10:00:01 +02:00
selected_client = {
tag : tag ,
dbid : client.client_database_id
} ;
button_delete . prop ( 'disabled' , false ) ;
2019-05-25 13:13:03 +02:00
} ) ;
tag . on ( 'contextmenu' , event = > {
if ( event . isDefaultPrevented ( ) )
return ;
event . preventDefault ( ) ;
2019-06-30 16:03:28 +02:00
contextmenu . spawn_context_menu ( event . pageX , event . pageY , {
2019-08-21 10:00:01 +02:00
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Add client" ) ,
icon_class : 'client-add' ,
callback : ( ) = > button_add . trigger ( 'click' )
} , {
2019-06-30 16:03:28 +02:00
type : contextmenu . MenuEntryType . ENTRY ,
2019-05-25 13:13:03 +02:00
name : tr ( "Remove client" ) ,
2019-06-30 16:03:28 +02:00
icon_class : 'client-delete' ,
2019-08-21 10:00:01 +02:00
callback : ( ) = > button_delete . trigger ( 'click' )
2019-05-25 13:13:03 +02:00
} , {
2019-06-30 16:03:28 +02:00
type : contextmenu . MenuEntryType . ENTRY ,
2019-05-25 13:13:03 +02:00
name : tr ( "Copy unique id" ) ,
2019-06-30 16:03:28 +02:00
icon_class : 'client-copy' ,
2019-05-25 13:13:03 +02:00
callback : ( ) = > copy_to_clipboard ( client . client_unique_identifier )
} )
} ) ;
}
update_filter ( ) ;
} ) . catch ( error = > {
if ( error instanceof CommandResult && error . id === ErrorID . PERMISSION_ERROR )
return ;
console . warn ( tr ( "Failed to receive server group clients for group %d: %o" ) , current_group . id , error ) ;
2019-08-21 10:00:01 +02:00
} ) ;
2019-05-25 13:13:03 +02:00
} ;
2019-08-21 10:00:01 +02:00
current_group_changed . push ( update_client_list ) ;
button_delete . on ( 'click' , event = > {
const client = selected_client ;
if ( ! client ) return ;
connection . serverConnection . send_command ( "servergroupdelclient" , {
sgid : current_group.id ,
cldbid : client.dbid
} ) . then ( ( ) = > {
selected_client . tag . detach ( ) ;
button_delete . prop ( 'disabled' , true ) ; /* nothing is selected */
} ) . catch ( error = > {
console . log ( tr ( "Failed to delete client %o from server group %o: %o" ) , client . dbid , current_group . id , error ) ;
if ( error instanceof CommandResult )
error = error . extra_message || error . message ;
createErrorModal ( tr ( "Failed to remove client" ) , tr ( "Failed to remove client from server group" ) ) . open ( ) ;
} ) ;
} ) ;
button_add . on ( 'click' , event = > {
createInputModal ( tr ( "Add client to server group" ) , tr ( "Enter the client unique id or database id" ) , text = > {
if ( ! text ) return false ;
if ( ! ! text . match ( /^[0-9]+$/ ) )
return true ;
try {
return atob ( text ) . length >= 20 ;
} catch ( error ) {
return false ;
}
} , async text = > {
if ( typeof ( text ) !== "string" )
return ;
let dbid ;
if ( ! ! text . match ( /^[0-9]+$/ ) ) {
dbid = parseInt ( text ) ;
debugger ;
} else {
try {
const data = await connection . serverConnection . command_helper . info_from_uid ( text . trim ( ) ) ;
dbid = data [ 0 ] . client_database_id ;
} catch ( error ) {
console . log ( tr ( "Failed to resolve client database id from unique id (%s): %o" ) , text , error ) ;
if ( error instanceof CommandResult )
error = error . extra_message || error . message ;
createErrorModal ( tr ( "Failed to add client" ) , MessageHelper . formatMessage ( tr ( "Failed to add client to server group\nFailed to resolve database id: {}." ) , error ) ) . open ( ) ;
return ;
}
}
if ( ! dbid ) {
console . log ( tr ( "Failed to resolve client database id from unique id (%s): Client not found" ) ) ;
createErrorModal ( tr ( "Failed to add client" ) , tr ( "Failed to add client to server group\nClient database id not found" ) ) . open ( ) ;
return ;
}
connection . serverConnection . send_command ( "servergroupaddclient" , {
sgid : current_group.id ,
cldbid : dbid
} ) . then ( ( ) = > {
update_client_list ( ) ;
} ) . catch ( error = > {
console . log ( tr ( "Failed to add client %o to server group %o: %o" ) , dbid , current_group . id , error ) ;
if ( error instanceof CommandResult )
error = error . extra_message || error . message ;
createErrorModal ( tr ( "Failed to add client" ) , tr ( "Failed to add client to server group\n" + error ) ) . open ( ) ;
} ) ;
} ) . open ( ) ;
} ) ;
container_client_list . on ( 'contextmenu' , event = > {
if ( event . isDefaultPrevented ( ) )
return ;
event . preventDefault ( ) ;
contextmenu . spawn_context_menu ( event . pageX , event . pageY , {
type : contextmenu . MenuEntryType . ENTRY ,
name : tr ( "Add client" ) ,
icon_class : 'client-add' ,
callback : ( ) = > button_add . trigger ( 'click' )
} )
} ) ;
/* icon handler and current group display */
{
let update_icon_callback : ( i : number ) = > any ;
update_icon . push ( i = > update_icon_callback ( i ) ) ;
input_filter . on ( 'change keyup' , event = > update_filter ( ) ) ;
current_group_changed . push ( ( ) = > {
container_selected_group . empty ( ) ;
if ( ! current_group ) return ;
let icon_container = $ . spawn ( "div" ) . addClass ( "icon-container" ) . appendTo ( container_selected_group ) ;
connection . fileManager . icons . generateTag ( current_group . properties . iconid ) . appendTo ( icon_container ) ;
update_icon_callback = icon = > {
icon_container . empty ( ) ;
connection . fileManager . icons . generateTag ( icon ) . appendTo ( icon_container ) ;
} ;
$ . spawn ( "div" ) . addClass ( "name" ) . text ( current_group . name + " (" + current_group . id + ")" ) . appendTo ( container_selected_group ) ;
} ) ;
}
tab_right . on ( 'show' , event = > {
editor . set_toggle_button ( ( ) = > {
clients_visible = ! clients_visible ;
2019-05-25 13:13:03 +02:00
2019-08-21 10:00:01 +02:00
container_client_list . toggleClass ( "hidden" , ! clients_visible ) ;
container_group_list . toggleClass ( "hidden" , clients_visible ) ;
return clients_visible ? tr ( "Hide clients in group" ) : tr ( "Show clients in group" ) ;
} , clients_visible ? tr ( "Hide clients in group" ) : tr ( "Show clients in group" ) ) ;
} ) ;
2019-05-25 13:13:03 +02:00
}
2018-09-30 21:50:59 +02:00
}
2019-08-21 10:00:01 +02:00
function spawnGroupAdd ( server_group : boolean , permissions : PermissionManager , valid_name : ( name : string , group_type : number ) = > boolean , callback : ( group_name : string , group_type : number ) = > any ) {
let modal : Modal ;
modal = createModal ( {
header : tr ( "Create a new group" ) ,
body : ( ) = > {
let tag = $ ( "#tmpl_group_add" ) . renderTag ( {
server_group : server_group
} ) ;
tag . find ( ".group-type-template" ) . prop ( "disabled" , ! permissions . neededPermission ( PermissionType . B_SERVERINSTANCE_MODIFY_TEMPLATES ) . granted ( 1 ) ) ;
tag . find ( ".group-type-query" ) . prop ( "disabled" , ! permissions . neededPermission ( PermissionType . B_SERVERINSTANCE_MODIFY_QUERYGROUP ) . granted ( 1 ) ) ;
const container_name = tag . find ( ".group-name" ) ;
const button_create = tag . find ( ".button-create" ) ;
const group_type = ( ) = > ( tag . find ( ".group-type" ) [ 0 ] as HTMLSelectElement ) . selectedIndex ;
container_name . on ( 'keyup change' , ( event : Event ) = > {
if ( event . type === 'keyup' ) {
const kevent = event as KeyboardEvent ;
if ( ! kevent . shiftKey && kevent . key == 'Enter' ) {
button_create . trigger ( 'click' ) ;
return ;
}
}
const valid = valid_name ( container_name . val ( ) as string , group_type ( ) ) ;
button_create . prop ( "disabled" , ! valid ) ;
container_name . parent ( ) . toggleClass ( "is-invalid" , ! valid ) ;
} ) . trigger ( 'change' ) ;
tag . find ( ".group-type" ) . on ( 'change' , ( ) = > container_name . trigger ( 'change' ) ) ;
button_create . on ( 'click' , event = > {
if ( button_create . prop ( "disabled" ) )
return ;
button_create . prop ( "disabled" , true ) ; /* disable double clicking */
modal . close ( ) ;
callback ( container_name . val ( ) as string , group_type ( ) ) ;
} ) ;
return tag ;
} ,
footer : null ,
width : 600
} ) ;
modal . htmlTag . find ( ".modal-body" ) . addClass ( "modal-group-add" ) ;
modal . open_listener . push ( ( ) = > {
modal . htmlTag . find ( ".group-name" ) . focus ( ) ;
} ) ;
modal . open ( ) ;
}
2018-09-30 21:50:59 +02:00
}