Improved the performance of the permission editor. (Spliting tasks in smaller pices)
This commit is contained in:
parent
bbdae986b8
commit
86eb36b1e4
4 changed files with 388 additions and 300 deletions
|
@ -73,7 +73,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
border: grey solid;
|
border: grey solid;
|
||||||
border-width: 0px 0px 1px 0px;
|
border-width: 0 0 1px 0;
|
||||||
|
|
||||||
background-color: lightgreen;
|
background-color: lightgreen;
|
||||||
}
|
}
|
||||||
|
@ -287,9 +287,12 @@ footer .container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: stretch;
|
justify-content: stretch;
|
||||||
|
|
||||||
|
/*
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
overflow-x: visible;
|
overflow-x: visible;
|
||||||
|
*/
|
||||||
|
overflow: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
background: white;
|
background: white;
|
||||||
border: 2px solid lightgray;
|
border: 2px solid lightgray;
|
||||||
|
|
|
@ -820,7 +820,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="entry group">
|
<div class="entry group tab-show-partitional">
|
||||||
<div class="title"><div class="arrow down"></div><a>{{>name}}</a></div>
|
<div class="title"><div class="arrow down"></div><a>{{>name}}</a></div>
|
||||||
<div class="group-entries">
|
<div class="group-entries">
|
||||||
{{for entries tmpl="tmpl_permission_entry"/}}
|
{{for entries tmpl="tmpl_permission_entry"/}}
|
||||||
|
|
|
@ -3,6 +3,59 @@
|
||||||
/// <reference path="../../client.ts" />
|
/// <reference path="../../client.ts" />
|
||||||
|
|
||||||
namespace Modals {
|
namespace Modals {
|
||||||
|
async function build_permission_editor() : Promise<JQuery[]> {
|
||||||
|
let root_entry: any = {};
|
||||||
|
root_entry.entries = [];
|
||||||
|
|
||||||
|
{ /* lets build the stuff (~5ms) */
|
||||||
|
let groups = globalClient.permissions.groupedPermissions();
|
||||||
|
let entry_stack: any[] = [root_entry];
|
||||||
|
|
||||||
|
let insert_group = (group: GroupedPermissions) => {
|
||||||
|
let group_entry: any = {};
|
||||||
|
group_entry.type = "group";
|
||||||
|
group_entry.name = group.group.name;
|
||||||
|
group_entry.entries = [];
|
||||||
|
entry_stack.last().entries.push(group_entry);
|
||||||
|
|
||||||
|
entry_stack.push(group_entry);
|
||||||
|
for(let child of group.children)
|
||||||
|
insert_group(child);
|
||||||
|
entry_stack.pop();
|
||||||
|
|
||||||
|
for(let perm of group.permissions) {
|
||||||
|
let entry: any = {};
|
||||||
|
entry.type = "entry";
|
||||||
|
entry.permission_name = perm.name;
|
||||||
|
entry.unset = true;
|
||||||
|
group_entry.entries.push(entry);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
groups.forEach(entry => insert_group(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
root_entry.permissions = root_entry.entries;
|
||||||
|
const start = Date.now();
|
||||||
|
console.log("begin render");
|
||||||
|
const rendered = $("#tmpl_permission_explorer").renderTag(root_entry);
|
||||||
|
console.log("end (%o)", Date.now() - start);
|
||||||
|
|
||||||
|
const result: JQuery[] = [];
|
||||||
|
|
||||||
|
for(let i = 0; i < 4; i++)
|
||||||
|
await new Promise(resolve => setTimeout(() => {
|
||||||
|
const start = Date.now();
|
||||||
|
console.log("begin");
|
||||||
|
result.push(rendered.clone());
|
||||||
|
console.log("end (%o)", Date.now() - start);
|
||||||
|
resolve();
|
||||||
|
}, 5));
|
||||||
|
result.push(rendered);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export function spawnPermissionEdit() : Modal {
|
export function spawnPermissionEdit() : Modal {
|
||||||
const connectModal = createModal({
|
const connectModal = createModal({
|
||||||
header: function() {
|
header: function() {
|
||||||
|
@ -11,60 +64,42 @@ namespace Modals {
|
||||||
body: function () {
|
body: function () {
|
||||||
let properties: any = {};
|
let properties: any = {};
|
||||||
|
|
||||||
let start, end;
|
const tags: JQuery[] = [$.spawn("div"), $.spawn("div"), $.spawn("div"), $.spawn("div"), $.spawn("div")];
|
||||||
start = Date.now();
|
|
||||||
{
|
|
||||||
let groups = globalClient.permissions.groupedPermissions();
|
|
||||||
let root_entry: any = {};
|
|
||||||
root_entry.entries = [];
|
|
||||||
let entry_stack: any[] = [root_entry];
|
|
||||||
|
|
||||||
let insert_group = (group: GroupedPermissions) => {
|
properties["permissions_group_server"] = tags[0];
|
||||||
let group_entry: any = {};
|
properties["permissions_group_channel"] = tags[1];
|
||||||
group_entry.type = "group";
|
properties["permissions_channel"] = tags[2];
|
||||||
group_entry.name = group.group.name;
|
properties["permissions_client"] = tags[3];
|
||||||
group_entry.entries = [];
|
properties["permissions_client_channel"] = tags[4];
|
||||||
entry_stack.last().entries.push(group_entry);
|
|
||||||
|
|
||||||
entry_stack.push(group_entry);
|
|
||||||
for(let child of group.children)
|
|
||||||
insert_group(child);
|
|
||||||
entry_stack.pop();
|
|
||||||
|
|
||||||
for(let perm of group.permissions) {
|
|
||||||
let entry: any = {};
|
|
||||||
entry.type = "entry";
|
|
||||||
entry.permission_name = perm.name;
|
|
||||||
entry.unset = true;
|
|
||||||
group_entry.entries.push(entry);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
groups.forEach(entry => insert_group(entry));
|
|
||||||
|
|
||||||
root_entry.permissions = root_entry.entries;
|
|
||||||
properties["permissions_group_server"] = $("#tmpl_permission_explorer").renderTag(root_entry);
|
|
||||||
properties["permissions_group_channel"] = properties["permissions_group_server"].clone();
|
|
||||||
properties["permissions_channel"] = properties["permissions_group_server"].clone();
|
|
||||||
properties["permissions_client"] = properties["permissions_group_server"].clone();
|
|
||||||
properties["permissions_client_channel"] = properties["permissions_group_server"].clone();
|
|
||||||
}
|
|
||||||
end = Date.now();
|
|
||||||
console.log("Generate: %s", end - start);
|
|
||||||
start = end;
|
|
||||||
|
|
||||||
let tag = $.spawn("div").append($("#tmpl_server_permissions").renderTag(properties)).tabify(false);
|
let tag = $.spawn("div").append($("#tmpl_server_permissions").renderTag(properties)).tabify(false);
|
||||||
end = Date.now();
|
setTimeout(() => {
|
||||||
console.log("Tab: %s", end - start);
|
console.log("HEAVY 1");
|
||||||
start = end;
|
build_permission_editor().then(result => {
|
||||||
|
console.log("Result!");
|
||||||
|
for(let i = 0; i < 5; i++)
|
||||||
|
tags[i].replaceWith(result[i]);
|
||||||
|
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log("HEAVY 2");
|
||||||
|
const task_queue: (() => Promise<any>)[] = [];
|
||||||
|
|
||||||
|
task_queue.push(apply_server_groups.bind(undefined, tag.find(".layout-group-server")));
|
||||||
|
task_queue.push(apply_channel_groups.bind(undefined, tag.find(".layout-group-channel")));
|
||||||
|
task_queue.push(apply_channel_permission.bind(undefined, tag.find(".layout-channel")));
|
||||||
|
task_queue.push(apply_client_permission.bind(undefined, tag.find(".layout-client")));
|
||||||
|
task_queue.push(apply_client_channel_permission.bind(undefined, tag.find(".layout-client-channel")));
|
||||||
|
|
||||||
|
const task_invokder = () => {
|
||||||
|
if(task_queue.length == 0) return;
|
||||||
|
task_queue.pop_front()().then(() => setTimeout(task_invokder, 0));
|
||||||
|
};
|
||||||
|
setTimeout(task_invokder, 5);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
apply_server_groups(tag.find(".layout-group-server"));
|
|
||||||
apply_channel_groups(tag.find(".layout-group-channel"));
|
|
||||||
apply_channel_permission(tag.find(".layout-channel"));
|
|
||||||
apply_client_permission(tag.find(".layout-client"));
|
|
||||||
apply_client_channel_permission(tag.find(".layout-client-channel"));
|
|
||||||
end = Date.now();
|
|
||||||
console.log("Listeners: %s", end - start);
|
|
||||||
start = end;
|
|
||||||
return tag;
|
return tag;
|
||||||
},
|
},
|
||||||
footer: function () {
|
footer: function () {
|
||||||
|
@ -91,76 +126,103 @@ namespace Modals {
|
||||||
return connectModal;
|
return connectModal;
|
||||||
}
|
}
|
||||||
|
|
||||||
function display_permissions(permission_tag: JQuery, permissions: PermissionValue[]) {
|
async function display_permissions(permission_tag: JQuery, permissions: PermissionValue[]) {
|
||||||
permission_tag.find(".permission").addClass("unset").find(".permission-grant input").val("");
|
permission_tag.find(".permission").addClass("unset").find(".permission-grant input").val("");
|
||||||
|
|
||||||
for(let perm of permissions) {
|
const permission_chunks: PermissionValue[][] = [];
|
||||||
let tag = permission_tag.find("." + perm.type.name);
|
while(permissions.length > 0) {
|
||||||
if(perm.value != undefined) {
|
permission_chunks.push(permissions.slice(0, 20));
|
||||||
tag.removeClass("unset");
|
permissions = permissions.slice(20);
|
||||||
{
|
|
||||||
let value = tag.find(".permission-value input");
|
|
||||||
if(value.attr("type") == "checkbox")
|
|
||||||
value.prop("checked", perm.value == 1);
|
|
||||||
else
|
|
||||||
value.val(perm.value);
|
|
||||||
}
|
|
||||||
tag.find(".permission-skip input").prop("checked", perm.flag_skip);
|
|
||||||
tag.find(".permission-negate input").prop("checked", perm.flag_negate);
|
|
||||||
}
|
|
||||||
if(perm.granted_value != undefined) {
|
|
||||||
tag.find(".permission-grant input").val(perm.granted_value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await new Promise(resolve => {
|
||||||
|
const process_chunk = () => {
|
||||||
|
if(permission_chunks.length == 0) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(let perm of permission_chunks.pop_front()) {
|
||||||
|
let tag = permission_tag.find("." + perm.type.name);
|
||||||
|
if(perm.value != undefined) {
|
||||||
|
tag.removeClass("unset");
|
||||||
|
{
|
||||||
|
let value = tag.find(".permission-value input");
|
||||||
|
if(value.attr("type") == "checkbox")
|
||||||
|
value.prop("checked", perm.value == 1);
|
||||||
|
else
|
||||||
|
value.val(perm.value);
|
||||||
|
}
|
||||||
|
tag.find(".permission-skip input").prop("checked", perm.flag_skip);
|
||||||
|
tag.find(".permission-negate input").prop("checked", perm.flag_negate);
|
||||||
|
}
|
||||||
|
if(perm.granted_value != undefined) {
|
||||||
|
tag.find(".permission-grant input").val(perm.granted_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(process_chunk, 0);
|
||||||
|
};
|
||||||
|
setTimeout(process_chunk, 0);
|
||||||
|
});
|
||||||
|
|
||||||
permission_tag.find(".filter-input").trigger('change');
|
permission_tag.find(".filter-input").trigger('change');
|
||||||
}
|
}
|
||||||
|
|
||||||
function make_permission_editor(tag: JQuery, default_number: number, cb_edit: (type: PermissionInfo, value?: number, skip?: boolean, negate?: boolean) => Promise<boolean>, cb_grant_edit: (type: PermissionInfo, value?: number) => Promise<boolean>) {
|
async function make_permission_editor(tag: JQuery, default_number: number, cb_edit: (type: PermissionInfo, value?: number, skip?: boolean, negate?: boolean) => Promise<boolean>, cb_grant_edit: (type: PermissionInfo, value?: number) => Promise<boolean>) {
|
||||||
tag = tag.hasClass("permission-explorer") ? tag : tag.find(".permission-explorer");
|
tag = tag.hasClass("permission-explorer") ? tag : tag.find(".permission-explorer");
|
||||||
const list = tag.find(".list");
|
const list = tag.find(".list");
|
||||||
//list.css("max-height", document.body.clientHeight * .7)
|
//list.css("max-height", document.body.clientHeight * .7)
|
||||||
|
|
||||||
list.find(".arrow").each((idx, _entry) => {
|
await new Promise(resolve => setTimeout(() => {
|
||||||
let entry = $(_entry);
|
list.find(".arrow").each((idx, _entry) => {
|
||||||
let entries = entry.parentsUntil(".group").first().parent().find("> .group-entries");
|
|
||||||
entry.on('click', () => {
|
|
||||||
if(entry.hasClass("right")) {
|
|
||||||
entries.show();
|
|
||||||
} else {
|
|
||||||
entries.hide();
|
|
||||||
}
|
|
||||||
entry.toggleClass("right down");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
tag.find(".filter-input, .filter-granted").on('keyup change', event => {
|
|
||||||
let filter_mask = tag.find(".filter-input").val() as string;
|
|
||||||
let req_granted = tag.find('.filter-granted').prop("checked");
|
|
||||||
|
|
||||||
tag.find(".permission").each((idx, _entry) => {
|
|
||||||
let entry = $(_entry);
|
let entry = $(_entry);
|
||||||
let key = entry.find("> .filter-key");
|
let entries = entry.parentsUntil(".group").first().parent().find("> .group-entries");
|
||||||
|
entry.on('click', () => {
|
||||||
|
if(entry.hasClass("right")) {
|
||||||
|
entries.show();
|
||||||
|
} else {
|
||||||
|
entries.hide();
|
||||||
|
}
|
||||||
|
entry.toggleClass("right down");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
let should_hide = filter_mask.length != 0 && key.text().indexOf(filter_mask) == -1;
|
resolve();
|
||||||
if(req_granted) {
|
}, 0));
|
||||||
if(entry.hasClass("unset") && entry.find(".permission-grant input").val() == "")
|
|
||||||
should_hide = true;
|
await new Promise(resolve => setTimeout(() => {
|
||||||
}
|
tag.find(".filter-input, .filter-granted").on('keyup change', event => {
|
||||||
entry.attr("match", should_hide ? 0 : 1);
|
let filter_mask = tag.find(".filter-input").val() as string;
|
||||||
if(should_hide)
|
let req_granted = tag.find('.filter-granted').prop("checked");
|
||||||
entry.hide();
|
|
||||||
else
|
tag.find(".permission").each((idx, _entry) => {
|
||||||
entry.show();
|
let entry = $(_entry);
|
||||||
|
let key = entry.find("> .filter-key");
|
||||||
|
|
||||||
|
let should_hide = filter_mask.length != 0 && key.text().indexOf(filter_mask) == -1;
|
||||||
|
if(req_granted) {
|
||||||
|
if(entry.hasClass("unset") && entry.find(".permission-grant input").val() == "")
|
||||||
|
should_hide = true;
|
||||||
|
}
|
||||||
|
entry.attr("match", should_hide ? 0 : 1);
|
||||||
|
if(should_hide)
|
||||||
|
entry.hide();
|
||||||
|
else
|
||||||
|
entry.show();
|
||||||
|
});
|
||||||
|
tag.find(".group").each((idx, _entry) => {
|
||||||
|
let entry = $(_entry);
|
||||||
|
let target = entry.find(".entry:not(.group)[match=\"1\"]").length > 0;
|
||||||
|
if(target)
|
||||||
|
entry.show();
|
||||||
|
else
|
||||||
|
entry.hide();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
tag.find(".group").each((idx, _entry) => {
|
|
||||||
let entry = $(_entry);
|
resolve();
|
||||||
let target = entry.find(".entry:not(.group)[match=\"1\"]").length > 0;
|
}, 0));
|
||||||
if(target)
|
|
||||||
entry.show();
|
|
||||||
else
|
|
||||||
entry.hide();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const expend_all = (parent) => {
|
const expend_all = (parent) => {
|
||||||
(parent || list).find(".arrow").addClass("right").removeClass("down").trigger('click');
|
(parent || list).find(".arrow").addClass("right").removeClass("down").trigger('click');
|
||||||
|
@ -169,196 +231,209 @@ namespace Modals {
|
||||||
(parent || list).find(".arrow").removeClass("right").addClass("down").trigger('click');
|
(parent || list).find(".arrow").removeClass("right").addClass("down").trigger('click');
|
||||||
};
|
};
|
||||||
|
|
||||||
list.on('contextmenu', event => {
|
|
||||||
if (event.isDefaultPrevented()) return;
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
spawn_context_menu(event.pageX, event.pageY, {
|
await new Promise(resolve => setTimeout(() => {
|
||||||
type: MenuEntryType.ENTRY,
|
list.on('contextmenu', event => {
|
||||||
icon: "",
|
|
||||||
name: "Expend all",
|
|
||||||
callback: () => expend_all.bind(this, [undefined])
|
|
||||||
},{
|
|
||||||
type: MenuEntryType.ENTRY,
|
|
||||||
icon: "",
|
|
||||||
name: "Collapse all",
|
|
||||||
callback: collapse_all.bind(this, [undefined])
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
tag.find(".title").each((idx, _entry) => {
|
|
||||||
let entry = $(_entry);
|
|
||||||
entry.on('click', () => {
|
|
||||||
tag.find(".selected").removeClass("selected");
|
|
||||||
$(_entry).addClass("selected");
|
|
||||||
});
|
|
||||||
|
|
||||||
entry.on('contextmenu', event => {
|
|
||||||
if (event.isDefaultPrevented()) return;
|
if (event.isDefaultPrevented()) return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
spawn_context_menu(event.pageX, event.pageY, {
|
spawn_context_menu(event.pageX, event.pageY, {
|
||||||
type: MenuEntryType.ENTRY,
|
type: MenuEntryType.ENTRY,
|
||||||
icon: "",
|
icon: "",
|
||||||
name: "Expend group",
|
name: "Expend all",
|
||||||
callback: () => expend_all.bind(this, entry)
|
callback: () => expend_all.bind(this, [undefined])
|
||||||
}, {
|
},{
|
||||||
type: MenuEntryType.ENTRY,
|
type: MenuEntryType.ENTRY,
|
||||||
|
icon: "",
|
||||||
|
name: "Collapse all",
|
||||||
|
callback: collapse_all.bind(this, [undefined])
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
}, 0));
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(() => {
|
||||||
|
tag.find(".title").each((idx, _entry) => {
|
||||||
|
let entry = $(_entry);
|
||||||
|
entry.on('click', () => {
|
||||||
|
tag.find(".selected").removeClass("selected");
|
||||||
|
$(_entry).addClass("selected");
|
||||||
|
});
|
||||||
|
|
||||||
|
entry.on('contextmenu', event => {
|
||||||
|
if (event.isDefaultPrevented()) return;
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
spawn_context_menu(event.pageX, event.pageY, {
|
||||||
|
type: MenuEntryType.ENTRY,
|
||||||
|
icon: "",
|
||||||
|
name: "Expend group",
|
||||||
|
callback: () => expend_all.bind(this, entry)
|
||||||
|
}, {
|
||||||
|
type: MenuEntryType.ENTRY,
|
||||||
icon: "",
|
icon: "",
|
||||||
name: "Expend all",
|
name: "Expend all",
|
||||||
callback: () => expend_all.bind(this, undefined)
|
callback: () => expend_all.bind(this, undefined)
|
||||||
}, {
|
}, {
|
||||||
type: MenuEntryType.ENTRY,
|
type: MenuEntryType.ENTRY,
|
||||||
icon: "",
|
icon: "",
|
||||||
name: "Collapse group",
|
name: "Collapse group",
|
||||||
callback: collapse_all.bind(this, entry)
|
callback: collapse_all.bind(this, entry)
|
||||||
}, {
|
}, {
|
||||||
type: MenuEntryType.ENTRY,
|
type: MenuEntryType.ENTRY,
|
||||||
icon: "",
|
icon: "",
|
||||||
name: "Collapse all",
|
name: "Collapse all",
|
||||||
callback: () => expend_all.bind(this, undefined)
|
callback: () => expend_all.bind(this, undefined)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
tag.find(".permission").each((idx, _entry) => {
|
resolve();
|
||||||
let entry = $(_entry);
|
}, 0));
|
||||||
|
|
||||||
entry.on('click', () => {
|
await new Promise(resolve => setTimeout(() => {
|
||||||
tag.find(".selected").removeClass("selected");
|
tag.find(".permission").each((idx, _entry) => {
|
||||||
$(_entry).addClass("selected");
|
let entry = $(_entry);
|
||||||
});
|
|
||||||
|
|
||||||
entry.on('dblclick', event => {
|
entry.on('click', () => {
|
||||||
entry.removeClass("unset");
|
tag.find(".selected").removeClass("selected");
|
||||||
|
$(_entry).addClass("selected");
|
||||||
let value = entry.find("> .permission-value input");
|
|
||||||
if(value.attr("type") == "number")
|
|
||||||
value.focus().val(default_number).trigger('change');
|
|
||||||
else
|
|
||||||
value.prop("checked", true).trigger('change');
|
|
||||||
});
|
|
||||||
|
|
||||||
entry.on('contextmenu', event => {
|
|
||||||
if(event.isDefaultPrevented()) return;
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
let entries: ContextMenuEntry[] = [];
|
|
||||||
|
|
||||||
if(entry.hasClass("unset")) {
|
|
||||||
entries.push({
|
|
||||||
type: MenuEntryType.ENTRY,
|
|
||||||
icon: "",
|
|
||||||
name: "Add permission",
|
|
||||||
callback: () => entry.trigger('dblclick')
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
entries.push({
|
|
||||||
type: MenuEntryType.ENTRY,
|
|
||||||
icon: "",
|
|
||||||
name: "Remove permission",
|
|
||||||
callback: () => {
|
|
||||||
entry.addClass("unset");
|
|
||||||
entry.find(".permission-value input").val("").trigger('change');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if(entry.find("> .permission-grant input").val() == "") {
|
|
||||||
entries.push({
|
|
||||||
type: MenuEntryType.ENTRY,
|
|
||||||
icon: "",
|
|
||||||
name: "Add grant permission",
|
|
||||||
callback: () => {
|
|
||||||
let value = entry.find("> .permission-grant input");
|
|
||||||
value.focus().val(default_number).trigger('change');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
entries.push({
|
|
||||||
type: MenuEntryType.ENTRY,
|
|
||||||
icon: "",
|
|
||||||
name: "Remove permission",
|
|
||||||
callback: () => {
|
|
||||||
entry.find("> .permission-grant input").val("").trigger('change');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
entries.push(MenuEntry.HR());
|
|
||||||
entries.push({
|
|
||||||
type: MenuEntryType.ENTRY,
|
|
||||||
icon: "",
|
|
||||||
name: "Expend all",
|
|
||||||
callback: () => expend_all.bind(this, undefined)
|
|
||||||
});
|
});
|
||||||
entries.push({
|
|
||||||
type: MenuEntryType.ENTRY,
|
entry.on('dblclick', event => {
|
||||||
icon: "",
|
entry.removeClass("unset");
|
||||||
name: "Collapse all",
|
|
||||||
callback: collapse_all.bind(this, undefined)
|
let value = entry.find("> .permission-value input");
|
||||||
|
if(value.attr("type") == "number")
|
||||||
|
value.focus().val(default_number).trigger('change');
|
||||||
|
else
|
||||||
|
value.prop("checked", true).trigger('change');
|
||||||
});
|
});
|
||||||
entries.push(MenuEntry.HR());
|
|
||||||
entries.push({
|
entry.on('contextmenu', event => {
|
||||||
type: MenuEntryType.ENTRY,
|
if(event.isDefaultPrevented()) return;
|
||||||
icon: "",
|
event.preventDefault();
|
||||||
name: "Show permission description",
|
|
||||||
callback: () => {
|
let entries: ContextMenuEntry[] = [];
|
||||||
createErrorModal("Not implemented!", "This function isnt implemented yet!").open();
|
|
||||||
|
if(entry.hasClass("unset")) {
|
||||||
|
entries.push({
|
||||||
|
type: MenuEntryType.ENTRY,
|
||||||
|
icon: "",
|
||||||
|
name: "Add permission",
|
||||||
|
callback: () => entry.trigger('dblclick')
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
entries.push({
|
||||||
|
type: MenuEntryType.ENTRY,
|
||||||
|
icon: "",
|
||||||
|
name: "Remove permission",
|
||||||
|
callback: () => {
|
||||||
|
entry.addClass("unset");
|
||||||
|
entry.find(".permission-value input").val("").trigger('change');
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
if(entry.find("> .permission-grant input").val() == "") {
|
||||||
|
entries.push({
|
||||||
|
type: MenuEntryType.ENTRY,
|
||||||
|
icon: "",
|
||||||
|
name: "Add grant permission",
|
||||||
|
callback: () => {
|
||||||
|
let value = entry.find("> .permission-grant input");
|
||||||
|
value.focus().val(default_number).trigger('change');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
entries.push({
|
||||||
|
type: MenuEntryType.ENTRY,
|
||||||
|
icon: "",
|
||||||
|
name: "Remove permission",
|
||||||
|
callback: () => {
|
||||||
|
entry.find("> .permission-grant input").val("").trigger('change');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
entries.push(MenuEntry.HR());
|
||||||
|
entries.push({
|
||||||
|
type: MenuEntryType.ENTRY,
|
||||||
|
icon: "",
|
||||||
|
name: "Expend all",
|
||||||
|
callback: () => expend_all.bind(this, undefined)
|
||||||
|
});
|
||||||
|
entries.push({
|
||||||
|
type: MenuEntryType.ENTRY,
|
||||||
|
icon: "",
|
||||||
|
name: "Collapse all",
|
||||||
|
callback: collapse_all.bind(this, undefined)
|
||||||
|
});
|
||||||
|
entries.push(MenuEntry.HR());
|
||||||
|
entries.push({
|
||||||
|
type: MenuEntryType.ENTRY,
|
||||||
|
icon: "",
|
||||||
|
name: "Show permission description",
|
||||||
|
callback: () => {
|
||||||
|
createErrorModal("Not implemented!", "This function isnt implemented yet!").open();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
entries.push({
|
||||||
|
type: MenuEntryType.ENTRY,
|
||||||
|
icon: "",
|
||||||
|
name: "Copy permission name",
|
||||||
|
callback: () => {
|
||||||
|
copy_to_clipboard(entry.find(".permission-name").text() as string);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
spawn_context_menu(event.pageX, event.pageY, ...entries);
|
||||||
});
|
});
|
||||||
entries.push({
|
|
||||||
type: MenuEntryType.ENTRY,
|
entry.find(".permission-value input, .permission-negate input, .permission-skip input").on('change', event => {
|
||||||
icon: "",
|
let permission = globalClient.permissions.resolveInfo(entry.find(".permission-name").text());
|
||||||
name: "Copy permission name",
|
if(!permission) {
|
||||||
callback: () => {
|
console.error("Attempted to edit a not known permission! (%s)", entry.find(".permission-name").text());
|
||||||
copy_to_clipboard(entry.find(".permission-name").text() as string);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entry.hasClass("unset")) {
|
||||||
|
cb_edit(permission, undefined, undefined, undefined).catch(error => {
|
||||||
|
tag.find(".button-update").trigger('click');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
let input = entry.find(".permission-value input");
|
||||||
|
let value = input.attr("type") == "number" ? input.val() : (input.prop("checked") ? "1" : "0");
|
||||||
|
if(value == "" || isNaN(value as number)) value = 0;
|
||||||
|
else value = parseInt(value as string);
|
||||||
|
let negate = entry.find(".permission-negate input").prop("checked");
|
||||||
|
let skip = entry.find(".permission-skip input").prop("checked");
|
||||||
|
|
||||||
|
cb_edit(permission, value, skip, negate).catch(error => {
|
||||||
|
tag.find(".button-update").trigger('click');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
spawn_context_menu(event.pageX, event.pageY, ...entries);
|
entry.find(".permission-grant input").on('change', event => {
|
||||||
});
|
let permission = globalClient.permissions.resolveInfo(entry.find(".permission-name").text());
|
||||||
|
if(!permission) {
|
||||||
|
console.error("Attempted to edit a not known permission! (%s)", entry.find(".permission-name").text());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
entry.find(".permission-value input, .permission-negate input, .permission-skip input").on('change', event => {
|
let value = entry.find(".permission-grant input").val();
|
||||||
let permission = globalClient.permissions.resolveInfo(entry.find(".permission-name").text());
|
if(value && value != "" && !isNaN(value as number)) {
|
||||||
if(!permission) {
|
cb_grant_edit(permission, parseInt(value as string)).catch(error => {
|
||||||
console.error("Attempted to edit a not known permission! (%s)", entry.find(".permission-name").text());
|
tag.find(".button-update").trigger('click');
|
||||||
return;
|
});
|
||||||
}
|
} else cb_grant_edit(permission, undefined).catch(error => {
|
||||||
|
|
||||||
if(entry.hasClass("unset")) {
|
|
||||||
cb_edit(permission, undefined, undefined, undefined).catch(error => {
|
|
||||||
tag.find(".button-update").trigger('click');
|
tag.find(".button-update").trigger('click');
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
let input = entry.find(".permission-value input");
|
|
||||||
let value = input.attr("type") == "number" ? input.val() : (input.prop("checked") ? "1" : "0");
|
|
||||||
if(value == "" || isNaN(value as number)) value = 0;
|
|
||||||
else value = parseInt(value as string);
|
|
||||||
let negate = entry.find(".permission-negate input").prop("checked");
|
|
||||||
let skip = entry.find(".permission-skip input").prop("checked");
|
|
||||||
|
|
||||||
cb_edit(permission, value, skip, negate).catch(error => {
|
|
||||||
tag.find(".button-update").trigger('click');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
entry.find(".permission-grant input").on('change', event => {
|
|
||||||
let permission = globalClient.permissions.resolveInfo(entry.find(".permission-name").text());
|
|
||||||
if(!permission) {
|
|
||||||
console.error("Attempted to edit a not known permission! (%s)", entry.find(".permission-name").text());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let value = entry.find(".permission-grant input").val();
|
|
||||||
if(value && value != "" && !isNaN(value as number)) {
|
|
||||||
cb_grant_edit(permission, parseInt(value as string)).catch(error => {
|
|
||||||
tag.find(".button-update").trigger('click');
|
|
||||||
});
|
|
||||||
} else cb_grant_edit(permission, undefined).catch(error => {
|
|
||||||
tag.find(".button-update").trigger('click');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
resolve();
|
||||||
|
}, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
function build_channel_tree(channel_list: JQuery, update_button: JQuery) {
|
function build_channel_tree(channel_list: JQuery, update_button: JQuery) {
|
||||||
|
@ -382,12 +457,12 @@ namespace Modals {
|
||||||
setTimeout(() => channel_list.find('.channel').first().trigger('click'), 0);
|
setTimeout(() => channel_list.find('.channel').first().trigger('click'), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function apply_client_channel_permission(tag: JQuery) {
|
async function apply_client_channel_permission(tag: JQuery) {
|
||||||
let permission_tag = tag.find(".permission-explorer");
|
let permission_tag = tag.find(".permission-explorer");
|
||||||
let channel_list = tag.find(".list-channel .entries");
|
let channel_list = tag.find(".list-channel .entries");
|
||||||
permission_tag.addClass("disabled");
|
permission_tag.addClass("disabled");
|
||||||
|
|
||||||
make_permission_editor(permission_tag, 75, (type, value, skip, negate) => {
|
await make_permission_editor(permission_tag, 75, (type, value, skip, negate) => {
|
||||||
let cldbid = parseInt(tag.find(".client-dbid").val() as string);
|
let cldbid = parseInt(tag.find(".client-dbid").val() as string);
|
||||||
if(isNaN(cldbid)) return Promise.reject("invalid cldbid");
|
if(isNaN(cldbid)) return Promise.reject("invalid cldbid");
|
||||||
|
|
||||||
|
@ -484,11 +559,11 @@ namespace Modals {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function apply_client_permission(tag: JQuery) {
|
async function apply_client_permission(tag: JQuery) {
|
||||||
let permission_tag = tag.find(".permission-explorer");
|
let permission_tag = tag.find(".permission-explorer");
|
||||||
permission_tag.addClass("disabled");
|
permission_tag.addClass("disabled");
|
||||||
|
|
||||||
make_permission_editor(permission_tag, 75, (type, value, skip, negate) => {
|
await make_permission_editor(permission_tag, 75, (type, value, skip, negate) => {
|
||||||
let cldbid = parseInt(tag.find(".client-dbid").val() as string);
|
let cldbid = parseInt(tag.find(".client-dbid").val() as string);
|
||||||
if(isNaN(cldbid)) return Promise.reject("invalid cldbid");
|
if(isNaN(cldbid)) return Promise.reject("invalid cldbid");
|
||||||
if(value != undefined) {
|
if(value != undefined) {
|
||||||
|
@ -559,11 +634,11 @@ namespace Modals {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function apply_channel_permission(tag: JQuery) {
|
async function apply_channel_permission(tag: JQuery) {
|
||||||
let channel_list = tag.find(".list-channel .entries");
|
let channel_list = tag.find(".list-channel .entries");
|
||||||
let permission_tag = tag.find(".permission-explorer");
|
let permission_tag = tag.find(".permission-explorer");
|
||||||
|
|
||||||
make_permission_editor(tag, 75, (type, value, skip, negate) => {
|
await make_permission_editor(tag, 75, (type, value, skip, negate) => {
|
||||||
let channel_id: number = parseInt(channel_list.find(".selected").attr("channel-id"));
|
let channel_id: number = parseInt(channel_list.find(".selected").attr("channel-id"));
|
||||||
let channel = globalClient.channelTree.findChannel(channel_id);
|
let channel = globalClient.channelTree.findChannel(channel_id);
|
||||||
if(!channel) {
|
if(!channel) {
|
||||||
|
@ -636,11 +711,11 @@ namespace Modals {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function apply_channel_groups(tag: JQuery) {
|
async function apply_channel_groups(tag: JQuery) {
|
||||||
let group_list = tag.find(".list-group-channel .entries");
|
let group_list = tag.find(".list-group-channel .entries");
|
||||||
let permission_tag = tag.find(".permission-explorer");
|
let permission_tag = tag.find(".permission-explorer");
|
||||||
|
|
||||||
make_permission_editor(tag, 75, (type, value, skip, negate) => {
|
await make_permission_editor(tag, 75, (type, value, skip, negate) => {
|
||||||
let group_id: number = parseInt(group_list.find(".selected").attr("group-id"));
|
let group_id: number = parseInt(group_list.find(".selected").attr("group-id"));
|
||||||
let group = globalClient.groups.channelGroup(group_id);
|
let group = globalClient.groups.channelGroup(group_id);
|
||||||
if(!group) {
|
if(!group) {
|
||||||
|
@ -737,11 +812,11 @@ namespace Modals {
|
||||||
setTimeout(() => group_list.find('.group').first().trigger('click'), 0);
|
setTimeout(() => group_list.find('.group').first().trigger('click'), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function apply_server_groups(tag: JQuery) {
|
async function apply_server_groups(tag: JQuery) {
|
||||||
let group_list = tag.find(".list-group-server .entries");
|
let group_list = tag.find(".list-group-server .entries");
|
||||||
let permission_tag = tag.find(".permission-explorer");
|
let permission_tag = tag.find(".permission-explorer");
|
||||||
|
|
||||||
make_permission_editor(tag, 75, (type, value, skip, negate) => {
|
await make_permission_editor(tag, 75, (type, value, skip, negate) => {
|
||||||
let group_id: number = parseInt(group_list.find(".selected").attr("group-id"));
|
let group_id: number = parseInt(group_list.find(".selected").attr("group-id"));
|
||||||
let group = globalClient.groups.serverGroup(group_id);
|
let group = globalClient.groups.serverGroup(group_id);
|
||||||
if(!group) {
|
if(!group) {
|
||||||
|
|
|
@ -37,32 +37,42 @@ var TabFunctions = {
|
||||||
let silentContent = $.spawn("div");
|
let silentContent = $.spawn("div");
|
||||||
silentContent.addClass("tab-content-invisible");
|
silentContent.addClass("tab-content-invisible");
|
||||||
|
|
||||||
template.find("x-entry").each(function () {
|
template.find("x-entry").each( (_, _entry) => {
|
||||||
let hentry = $.spawn("div");
|
const entry = $(_entry);
|
||||||
hentry.addClass("entry");
|
|
||||||
|
let tag_header = $.spawn("div").addClass("entry");
|
||||||
if(copy)
|
if(copy)
|
||||||
hentry.append($(this).find("x-tag").clone(true, true));
|
tag_header.append(entry.find("x-tag").clone(true, true));
|
||||||
else
|
else
|
||||||
hentry.append($(this).find("x-tag"));
|
tag_header.append(entry.find("x-tag"));
|
||||||
|
|
||||||
|
const tag_content = copy ? entry.find("x-content").clone(true, true) : entry.find("x-content");
|
||||||
|
content.append(tag_content.hide());
|
||||||
|
|
||||||
|
tag_header.on("click", () => {
|
||||||
|
if(tag_header.hasClass("selected")) return;
|
||||||
|
|
||||||
const _this = $(this);
|
|
||||||
const _entryContent = copy ? _this.find("x-content").clone(true, true) : _this.find("x-content");
|
|
||||||
silentContent.append(_entryContent);
|
|
||||||
hentry.on("click", function () {
|
|
||||||
if(hentry.hasClass("selected")) return;
|
|
||||||
tag.find(".tab-header .selected").removeClass("selected");
|
tag.find(".tab-header .selected").removeClass("selected");
|
||||||
hentry.addClass("selected");
|
tag_header.addClass("selected");
|
||||||
|
|
||||||
content.children().appendTo(silentContent);
|
content.find("> x-content").hide();
|
||||||
console.log(silentContent);
|
/* don't show many nodes at once */
|
||||||
content.empty();
|
let entries = tag_content.find(".tab-show-partitional");
|
||||||
content.append(_entryContent);
|
entries.hide();
|
||||||
//console.log(_this.find("x-content"));
|
const show_next = index => {
|
||||||
//content.append(_this.find("x-content"));
|
console.log("Show " + index);
|
||||||
|
if(index >= entries.length) return;
|
||||||
|
entries.eq(index).show();
|
||||||
|
|
||||||
|
setTimeout(show_next.bind(undefined, index + 1), 0);
|
||||||
|
};
|
||||||
|
show_next(0);
|
||||||
|
|
||||||
|
tag_content.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(this);
|
console.log(this);
|
||||||
header.append(hentry);
|
header.append(tag_header);
|
||||||
});
|
});
|
||||||
|
|
||||||
header.find(".entry").first().trigger("click");
|
header.find(".entry").first().trigger("click");
|
||||||
|
|
Loading…
Add table
Reference in a new issue