Added basic serveredit logic

canary
WolverinDEV 2018-08-11 15:02:11 +02:00
parent ed0e754d93
commit 63b55c0e25
10 changed files with 516 additions and 44 deletions

View File

@ -4,12 +4,6 @@
box-sizing: border-box;
}
.group_box {
border: lightgray solid 1px;
border-radius: 2px;
padding: 2px;
}
.contextMenu {
display: none;
z-index: 1000;

View File

@ -1,21 +1,68 @@
.channel_general_properties .value {
width: 100%;
}
.channel_general_properties .key {
width: 150px;
}
.channel_general_properties .property_entry {
margin: 2px;
}
.modal .properties {
display: grid;
grid-template-columns: minmax(min-content, max-content) auto;
grid-column-gap: 10px;
grid-row-gap: 3px;
box-sizing: border-box; }
.modal hr {
border-top: 3px double #8c8b8b;
width: 100%; }
.modal .general_properties, .modal .properties_general {
width: 100%;
/*
.slots {
width: 100%;
display: inline-flex;
flex-direction: row;
* {
display: inline-flex;
}
.maximum, .reserved {
a {
width: 140px;
}
input {
width: 100px;
margin-right: 20px;
}
}
}
*/ }
.modal .input_error {
border-radius: 1px;
border: solid red; }
.modal .server_properties .properties {
grid-template-columns: 135px auto; }
.modal .server_properties .properties:first-of-type {
margin-top: 5px; }
.modal .server_properties .virtualserver_welcomemessage {
height: 70px;
resize: none; }
.modal .container {
padding: 6px; }
.modal .group_box {
margin-top: 5px; }
.modal .group_box:first-of-type {
margin-top: 0px; }
.channel_perm_tbl .value {
width: 60px;
}
width: 60px; }
.input_error {
border-radius: 1px;
border-style: solid;
border-color: red;
}
.group_box {
display: grid; }
.group_box .header {
float: left;
margin-bottom: 2px; }
.group_box .content {
background: rgba(0, 0, 0, 0.035);
border: lightgray solid 1px;
border-radius: 0 2px;
padding: 6px; }
.container {
margin: 2px; }
/*# sourceMappingURL=modals.css.map */

100
css/modals.scss Normal file
View File

@ -0,0 +1,100 @@
.modal {
//General style
.properties {
display: grid;
grid-template-columns: minmax(min-content, max-content) auto;
grid-column-gap: 10px;
grid-row-gap: 3px;
box-sizing: border-box;
}
hr {
border-top: 3px double #8c8b8b;
width: 100%;
}
.general_properties, .properties_general {
width: 100%;
/*
.slots {
width: 100%;
display: inline-flex;
flex-direction: row;
* {
display: inline-flex;
}
.maximum, .reserved {
a {
width: 140px;
}
input {
width: 100px;
margin-right: 20px;
}
}
}
*/
}
.input_error {
border-radius: 1px;
border: solid red;
}
.server_properties {
.properties {
grid-template-columns: 135px auto;
&:first-of-type {
margin-top: 5px;
}
}
.virtualserver_welcomemessage {
height: 70px;
resize: none;
}
}
.container {
padding: 6px;
}
.group_box {
margin-top: 5px;
&:first-of-type {
margin-top: 0px;
}
}
}
.channel_perm_tbl .value {
width: 60px;
}
.group_box {
display: grid;
.header {
float: left;
margin-bottom: 2px;
}
.content {
background: rgba(0, 0, 0, .035);
border: lightgray solid 1px;
border-radius: 0 2px;
padding: 6px;
}
}
.container {
margin: 2px;
}

View File

@ -1,10 +1,6 @@
x-tab { display:none }
.tab {
font-family: Arial;
font-size: 12px;
/*white-space: pre;*/
line-height: 1;
padding: 2px;
height: 100%;
display: flex;
@ -34,6 +30,11 @@ x-tab { display:none }
*/
.tab .tab-header {
font-family: Arial;
font-size: 12px;
/*white-space: pre;*/
line-height: 1;
max-width: 100%;
overflow: auto;
/*height: 24px;*/

View File

@ -86,7 +86,7 @@
</div>
</div>
<script type="text/javascript" class="no-js">
let elements = document.getElementsByClassName("no-js");
var elements = document.getElementsByClassName("no-js");
while (elements.length > 0) //Removing these elements (even self)
elements.item(0).remove();
</script>

View File

@ -144,6 +144,7 @@ function loadDebug() {
"js/ui/modal/ModalConnect.js",
"js/ui/modal/ModalSettings.js",
"js/ui/modal/ModalCreateChannel.js",
"js/ui/modal/ModalServerEdit.js",
"js/ui/modal/ModalConnect.js",
"js/ui/modal/ModalChangeVolume.js",
"js/ui/modal/ModalBanClient.js",

View File

@ -30,7 +30,7 @@ namespace Modals {
});
applyGeneralListener(properties, modal.htmlTag.find(".channel_general_properties"), modal.htmlTag.find(".button_ok"), !channel);
applyGeneralListener(properties, modal.htmlTag.find(".general_properties"), modal.htmlTag.find(".button_ok"), !channel);
applyStandardListener(properties, modal.htmlTag.find(".settings_standard"), modal.htmlTag.find(".button_ok"), parent, !channel);
applyPermissionListener(properties, modal.htmlTag.find(".settings_permissions"), modal.htmlTag.find(".button_ok"), permissions, channel);

View File

@ -0,0 +1,175 @@
/// <reference path="../../utils/modal.ts" />
namespace Modals {
export function createServerModal(server: ServerEntry, callback: (properties?: ServerProperties) => any) {
let properties: ServerProperties = {} as ServerProperties; //The changes properties
const modal = createModal({
header: "Manager the Virtual Server",
body: () => {
let template = $("#tmpl_server_edit").renderTag(server.properties);
template = $.spawn("div").append(template);
return template.tabify();
},
footer: () => {
let footer = $.spawn("div");
footer.addClass("modal-button-group");
footer.css("margin", "5px");
let buttonCancel = $.spawn("button");
buttonCancel.text("Cancel").addClass("button_cancel");
let buttonOk = $.spawn("button");
buttonOk.text("Ok").addClass("button_ok");
footer.append(buttonCancel);
footer.append(buttonOk);
return footer;
},
width: 750
});
server_applyGeneralListener(properties, modal.htmlTag.find(".properties_general"), modal.htmlTag.find(".button_ok"));
server_applyHostListener(properties, server.properties, modal.htmlTag.find(".properties_host"), modal.htmlTag.find(".button_ok"));
modal.htmlTag.find(".button_ok").click(() => {
modal.close();
callback(properties); //First may create the channel
});
modal.htmlTag.find(".button_cancel").click(() => {
modal.close();
callback();
});
modal.open();
}
function server_applyGeneralListener(properties: ServerProperties, tag: JQuery, button: JQuery) {
let updateButton = () => {
if(tag.find(".input_error").length == 0)
button.removeAttr("disabled");
else button.attr("disabled", "true");
};
tag.find(".virtualserver_name").change(function (this: HTMLInputElement) {
properties.virtualserver_name = this.value;
$(this).removeClass("input_error");
if(this.value.length < 1 || this.value.length > 70)
$(this).addClass("input_error");
updateButton();
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_NAME).granted(1));
tag.find(".virtualserver_password").change(function (this: HTMLInputElement) {
properties.virtualserver_flag_password = this.value.length != 0;
if(properties.virtualserver_flag_password)
helpers.hashPassword(this.value).then(pass => properties.virtualserver_password = pass);
$(this).removeClass("input_error");
if(!properties.virtualserver_flag_password)
if(globalClient.permissions.neededPermission(PermissionType.B_CHANNEL_CREATE_MODIFY_WITH_FORCE_PASSWORD).granted(1))
$(this).addClass("input_error");
updateButton();
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_PASSWORD).granted(1));
tag.find(".virtualserver_maxclients").change(function (this: HTMLInputElement) {
properties.virtualserver_maxclients = this.valueAsNumber;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_MAXCLIENTS).granted(1));
tag.find(".virtualserver_reserved_slots").change(function (this: HTMLInputElement) {
properties.virtualserver_reserved_slots = this.valueAsNumber;
$(this).removeClass("input_error");
if(this.valueAsNumber > properties.virtualserver_maxclients)
$(this).addClass("input_error");
updateButton();
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_RESERVED_SLOTS).granted(1));
tag.find(".virtualserver_welcomemessage").change(function (this: HTMLInputElement) {
properties.virtualserver_welcomemessage = this.value;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_WELCOMEMESSAGE).granted(1));
}
/*
virtualserver_hostmessage
virtualserver_hostmessage_mode X
virtualserver_hostbanner_url
virtualserver_hostbanner_gfx_url
virtualserver_hostbanner_gfx_interval
virtualserver_hostbanner_mode X
virtualserver_hostbutton_tooltip
virtualserver_hostbutton_url
virtualserver_hostbutton_gfx_url
*/
function server_applyHostListener(properties: ServerProperties, original_properties: ServerProperties, tag: JQuery, button: JQuery) {
tag.find(".virtualserver_host").change(function (this: HTMLInputElement) {
properties.virtualserver_host = this.value;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOST).granted(1));
tag.find(".virtualserver_port").change(function (this: HTMLInputElement) {
properties.virtualserver_port = this.valueAsNumber;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_PORT).granted(1));
tag.find(".virtualserver_hostmessage").change(function (this: HTMLInputElement) {
properties.virtualserver_hostmessage = this.value;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTMESSAGE).granted(1));
tag.find(".virtualserver_hostmessage_mode").change(function (this: HTMLSelectElement) {
properties.virtualserver_hostmessage_mode = this.selectedIndex;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTMESSAGE).granted(1))
.find("option").eq(original_properties.virtualserver_hostmessage_mode).prop('selected', true);
tag.find(".virtualserver_hostbanner_url").change(function (this: HTMLInputElement) {
properties.virtualserver_hostbanner_url = this.value;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTBANNER).granted(1));
tag.find(".virtualserver_hostbanner_gfx_url").change(function (this: HTMLInputElement) {
properties.virtualserver_hostbanner_gfx_url = this.value;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTBANNER).granted(1));
tag.find(".virtualserver_hostbanner_gfx_interval").change(function (this: HTMLInputElement) {
properties.virtualserver_hostbanner_gfx_interval = this.valueAsNumber;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTBANNER).granted(1));
tag.find(".virtualserver_hostbanner_mode").change(function (this: HTMLSelectElement) {
properties.virtualserver_hostbanner_mode = this.selectedIndex;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTMESSAGE).granted(1))
.find("option").eq(original_properties.virtualserver_hostbanner_mode).prop('selected', true);
tag.find(".virtualserver_hostbutton_tooltip").change(function (this: HTMLInputElement) {
properties.virtualserver_hostbutton_tooltip = this.value;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTBUTTON).granted(1));
tag.find(".virtualserver_hostbutton_url").change(function (this: HTMLInputElement) {
properties.virtualserver_hostbutton_url = this.value;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTBUTTON).granted(1));
tag.find(".virtualserver_hostbutton_gfx_url").change(function (this: HTMLInputElement) {
properties.virtualserver_hostbutton_gfx_url = this.value;
}).prop("disabled", !globalClient.permissions.neededPermission(PermissionType.B_VIRTUALSERVER_MODIFY_HOSTBUTTON).granted(1));
}
/*
<!--
virtualserver_hostmessage: string = "";
virtualserver_hostmessage_mode: string = "";
virtualserver_hostbanner_url: string = "";
virtualserver_hostbanner_gfx_url: string = "";
virtualserver_hostbanner_gfx_interval: number = 0;
virtualserver_hostbutton_tooltip: string = "";
virtualserver_hostbutton_url: string = "";
virtualserver_hostbutton_gfx_url: string = "";
-->
*/
}

View File

@ -1,6 +1,10 @@
/// <reference path="channel.ts" />
/// <reference path="modal/ModalServerEdit.ts" />
class ServerProperties {
virtualserver_host: string = "";
virtualserver_port: number = 0;
virtualserver_name: string = "";
virtualserver_icon_id: number = 0;
virtualserver_version: string = "unknown";
@ -11,7 +15,25 @@ class ServerProperties {
virtualserver_queryclientsonline: number = 0;
virtualserver_channelsonline: number = 0;
virtualserver_uptime: number = 0;
virtualserver_maxclients: number = 0
virtualserver_maxclients: number = 0;
virtualserver_reserved_slots: number = 0;
virtualserver_password: string = "";
virtualserver_flag_password: boolean = false;
virtualserver_welcomemessage: string = "";
virtualserver_hostmessage: string = "";
virtualserver_hostmessage_mode: number = 0;
virtualserver_hostbanner_url: string = "";
virtualserver_hostbanner_gfx_url: string = "";
virtualserver_hostbanner_gfx_interval: number = 0;
virtualserver_hostbanner_mode: number = 0;
virtualserver_hostbutton_tooltip: string = "";
virtualserver_hostbutton_url: string = "";
virtualserver_hostbutton_gfx_url: string = "";
}
interface ServerAddress {
@ -72,9 +94,16 @@ class ServerEntry {
spawnContextMenu(x: number, y: number, on_close: () => void = () => {}) {
spawnMenu(x, y, {
type: MenuEntryType.ENTRY,
icon: "",
name: "test",
callback: () => {}
icon: "virtualserver_edit",
name: "Edit",
callback: () => {
Modals.createServerModal(this, properties => {
log.info(LogCategory.SERVER, "Changing server properties %o", properties);
console.log("Changed properties: %o", properties);
if (properties)
this.channelTree.client.serverConnection.sendCommand("serveredit", properties);
});
}
},
MenuEntry.CLOSE(on_close)
);

View File

@ -15,23 +15,20 @@
<body>
<!-- Template for chennel create & edit-->
<script id="tmpl_channel_edit" type="text/html">
<div class="align_column channel_general_properties">
<div class="align_row property_entry">
<div class="align_column general_properties">
<div class="properties">
<a class="key">Name:</a>
<input class="value channel_name" value="{{>channel_name}}"/>
</div>
<div class="align_row property_entry">
<a class="key">Password:</a>
<!-- Use a random id to trick the default browser password manager. (I think something like a default password is really useless and -->
<!-- Just display a random value here-->
<input class="value channel_password" type="password" id="field_channel_password_{{rnd '0~13377331'/}}" {{if channel_flag_password}} value="WolverinDEV"{{/if}}/>
</div>
<div class="align_row property_entry">
<a class="key">Topic:</a>
<input class="value channel_topic" value="{{>channel_topic}}"/>
</div>
<div class="align_row property_entry">
<a class="key">Description:</a>
<textarea class="value channel_description" style="height: 150px; resize: none">{{>channel_description}}</textarea>
</div>
@ -44,7 +41,7 @@
<div class="settings_standard" style="display: flex; flex-direction: row; width: 100%; justify-content: space-evenly">
<div style="vertical-align: center; margin: 20px;">
<a>Channel Type</a><br>
<fieldset style="border: gray solid; border-width: 2px; border-radius: 0px 6px 6px 6px;">
<fieldset style="border: 2px solid gray;border-radius: 0px 6px 6px 6px;">
<div><input type="radio" name="channel_type" value="temp" {{if !channel_flag_semi_permanent && !channel_flag_permanent}}checked{{/if}}> Temporary</div>
<div><input type="radio" name="channel_type" value="semi" {{if channel_flag_semi_permanent}}checked{{/if}}> Semi-Permanent</div>
<div><input type="radio" name="channel_type" value="perm" {{if channel_flag_permanent}}checked{{/if}}> Permanent</div>
@ -106,8 +103,136 @@
</x-tab>
</script>
<script id="tmpl_server_edit" type="text/html">
<div class="align_column properties_general server_properties">
<div class="properties">
<a class="key">Name:</a>
<input class="value virtualserver_name" value="{{>virtualserver_name}}"/>
<!-- Template for the connect modal -->
<a class="key">Password:</a>
<!-- Use a random id to trick the default browser password manager. (I think something like a default password is really useless and -->
<!-- Just display a random value here-->
<input class="value virtualserver_password" type="password" id="field_server_password_{{rnd '0~13377331'/}}" {{if virtualserver_flag_password}} value="WolverinDEV"{{/if}}/>
</div>
<hr>
<div class="properties">
<a>Maximum Clients:</a>
<div>
<input type="number" min="0" max="1024" value="{{:virtualserver_maxclients}}" class="value virtualserver_maxclients">
<a>Reserved slots:</a>
<input type="number" min="0" max="{{*: data.virtualserver_maxclients - 1 }}" value="{{:virtualserver_reserved_slots}}" class="value virtualserver_reserved_slots">
</div>
<div class="key">Welcome Message:</div>
<textarea class="value virtualserver_welcomemessage">{{>virtualserver_welcomemessage}}</textarea>
</div>
<hr>
</div>
<div style="margin-bottom: 5px"></div>
<x-tab>
<x-entry>
<x-tag>Host</x-tag>
<x-content>
<div class="container properties_host">
<div class="group_box">
<div class="header">Binding</div>
<div class="content">
<div class="properties">
<div class="key">Host:</div>
<input class="value virtualserver_host" value="{{>virtualserver_host}}"/>
<div class="key">Port:</div>
<input type="number" min="1" max="65536" value="{{:virtualserver_port}}" class="value virtualserver_port">
</div>
<a>Note: These settings require a virtual server restart to take effect!</a>
</div>
</div>
<div class="group_box">
<div class="header">Host message</div>
<div class="content properties">
<div class="key">Message:</div>
<input class="value virtualserver_hostmessage" value="{{>virtualserver_hostmessage}}"/>
<div class="key">Message Mode:</div>
<select class="value virtualserver_hostmessage_mode">
<option value="none">No message</option>
<option value="log">Show message in log</option>
<option value="modal">Show message as modal</option>
<option value="modal_exit">Show message as modal and disconnect the client</option>
</select>
</div>
</div>
<div class="group_box">
<div class="header">Host banner</div>
<div class="content properties">
<div class="key">URL:</div>
<input class="value virtualserver_hostbanner_url" value="{{>virtualserver_hostbanner_url}}"/>
<div class="key">Banner Gfx URL:</div>
<input class="value virtualserver_hostbanner_gfx_url" value="{{>virtualserver_hostbanner_gfx_url}}"/>
<div class="key">Gfx Interval:</div>
<div class="value">
<input type="number" min="60" value="{{:virtualserver_hostbanner_gfx_interval}}" class="value virtualserver_hostbanner_gfx_interval">
<a>Resize:</a>
<select class="value virtualserver_hostbanner_mode">
<option value="none">Do not adjust</option>
<option value="ignore_ratio">Adjust but ignore ratio aspect</option>
<option value="keep_ratio">Adjust and keep ratio aspect</option>
</select>
</div>
</div>
</div>
<div class="group_box">
<div class="header">Host Button</div>
<div class="content properties">
<div class="key">Tooltip:</div>
<input class="value virtualserver_hostbutton_tooltip" value="{{>virtualserver_hostbutton_tooltip}}"/>
<div class="key">URL:</div>
<input class="value virtualserver_hostbutton_url" value="{{>virtualserver_hostbutton_url}}"/>
<div class="key">Icon URL:</div>
<input class="value virtualserver_hostbutton_gfx_url" value="{{>virtualserver_hostbutton_gfx_url}}"/>
</div>
</div>
</div>
</x-content>
</x-entry>
<x-entry>
<x-tag>Transfers</x-tag>
<x-content>TeaSpeak does not yet support these variables</x-content>
</x-entry>
<x-entry>
<x-tag>Anti-Flood</x-tag>
<x-content>TODO!</x-content>
</x-entry>
<x-entry>
<x-tag>Security</x-tag>
<x-content>TODO!</x-content>
</x-entry>
<x-entry>
<x-tag>Misc</x-tag>
<x-content>TODO!</x-content>
</x-entry>
<x-entry>
<x-tag>Log</x-tag>
<x-content>TODO!</x-content>
</x-entry>
<x-entry>
<x-tag>Messages</x-tag>
<x-content>TODO!</x-content>
</x-entry>
</x-tab>
</script>
<!-- Template for the connect modal -->
<script id="tmpl_connect" type="text/html">
<div style="margin-top: 5px;">
<div style="display: flex; flex-direction: row; width: 100%; justify-content: space-between">