Finished up with channel rank/perms frontend.
This commit is contained in:
parent
edb4215929
commit
796bb033a7
22 changed files with 472 additions and 57 deletions
|
|
@ -14,32 +14,207 @@ GNU Affero General Public License for more details.
|
|||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||
|
||||
class channelSettingsPrompt{
|
||||
class channelSettingsPage{
|
||||
constructor(){
|
||||
//Get channel name off of the URL
|
||||
this.channel = window.location.pathname.slice(3).replace('/settings','');
|
||||
this.hidden = document.querySelector("#channel-hidden");
|
||||
this.delete = document.querySelector("#channel-delete");
|
||||
//Instantiate UX handling objects, making sure to pass the channel name.
|
||||
this.deleteBtn = new deleteBtn(this.channel);
|
||||
this.rankList = new rankList(this.channel);
|
||||
this.prefrenceList = new prefrenceList(this.channel);
|
||||
this.permList = new permList(this.channel);
|
||||
}
|
||||
}
|
||||
|
||||
this.hidden.addEventListener('change', this.submitUpdate.bind(this));
|
||||
this.delete.addEventListener('click', this.promptDelete.bind(this));
|
||||
class rankList{
|
||||
constructor(channel){
|
||||
this.channel = channel
|
||||
this.table = document.querySelector(".admin-list-table");
|
||||
this.userPrompt = document.querySelector("#new-rank-input");
|
||||
this.rankSelect = document.querySelector("#new-rank-select");
|
||||
|
||||
//Load the userlist and setup input
|
||||
this.loadList();
|
||||
this.setupInput();
|
||||
}
|
||||
|
||||
setupInput(){
|
||||
this.userPrompt.addEventListener("keydown", this.submitNewRank.bind(this));
|
||||
}
|
||||
|
||||
resetInput(){
|
||||
//These change every time the table is refreshed, so we should reset the property as well.
|
||||
this.inputs = document.querySelectorAll(".channel-rank-select");
|
||||
|
||||
this.inputs.forEach((input) => {
|
||||
input.addEventListener("change", this.submitUpdate.bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
async loadList(){
|
||||
const list = await utils.ajax.getChannelRank(this.channel);
|
||||
|
||||
this.updateList(list);
|
||||
}
|
||||
|
||||
async submitNewRank(event){
|
||||
if(event.key != "Enter" && event.key != null){
|
||||
//Bail out if we didn't hit enter
|
||||
return;
|
||||
}
|
||||
|
||||
//Send new rank
|
||||
this.submitUserRank(this.userPrompt.value, this.rankSelect.value);
|
||||
|
||||
//Clear out prompt
|
||||
this.userPrompt.value = "";
|
||||
}
|
||||
|
||||
async submitUpdate(event){
|
||||
//probably not the cleanest way to get the chan name :P
|
||||
const key = event.target.id.split("-").pop();
|
||||
const value = event.target.type == "checkbox" ? event.target.checked : event.target.value;
|
||||
const user = event.target.id.replace("channel-rank-select-","");
|
||||
const rank = event.target.value;
|
||||
|
||||
await this.submitUserRank(user, rank);
|
||||
}
|
||||
|
||||
async submitUserRank(user, rank){
|
||||
await this.updateList(await utils.ajax.setChannelRank(this.channel, user, rank));
|
||||
}
|
||||
|
||||
async updateList(data){
|
||||
//If no data
|
||||
if(!data){
|
||||
//Do not pass go, do not collect $200
|
||||
return;
|
||||
}
|
||||
//Get rank of logged in user
|
||||
const curName = document.querySelector("#username").textContent
|
||||
const curUser = data[curName];
|
||||
const rankEnum = await utils.ajax.getRankEnum();
|
||||
|
||||
//clear the table
|
||||
this.clearTable();
|
||||
|
||||
Object.entries(data).forEach((userAr) => {
|
||||
//pull user object from entry array
|
||||
const user = userAr[1];
|
||||
|
||||
//Create entry row
|
||||
const entryRow = document.createElement('tr');
|
||||
entryRow.classList.add("admin-list-entry");
|
||||
|
||||
//Create IMG cell
|
||||
const imgCell = document.createElement('td')
|
||||
imgCell.classList.add("admin-list-entry","admin-list-entry-item");
|
||||
|
||||
//Create IMG node inside of IMG cell
|
||||
const imgNode = document.createElement('img');
|
||||
imgNode.classList.add("admin-list-entry","admin-list-entry-item");
|
||||
imgNode.src = user.img;
|
||||
|
||||
//append Img Node to Img Cell
|
||||
imgCell.appendChild(imgNode);
|
||||
|
||||
//Create ID cell
|
||||
const idCell = document.createElement('td');
|
||||
idCell.classList.add("admin-list-entry","admin-list-entry-item","admin-list-entry-not-first-col");
|
||||
idCell.innerHTML = user.id;
|
||||
|
||||
//Create Name cell
|
||||
const nameCell = document.createElement('td');
|
||||
nameCell.classList.add("admin-list-entry","admin-list-entry-item","admin-list-entry-not-first-col");
|
||||
nameCell.innerHTML = user.user;
|
||||
|
||||
//Create Rank cell
|
||||
const rankCell = document.createElement('td');
|
||||
rankCell.classList.add("admin-list-entry","admin-list-entry-item","admin-list-entry-not-first-col");
|
||||
//If the listed user rank is equal or higher than the signed-in user
|
||||
if(rankEnum.indexOf(user.rank) >= rankEnum.indexOf(curUser.rank)){
|
||||
rankCell.innerHTML = user.rank;
|
||||
}else{
|
||||
//Create rank select
|
||||
const rankSelect = document.createElement('select');
|
||||
rankSelect.id = `channel-rank-select-${user.user}`
|
||||
rankSelect.classList.add("channel-rank-select")
|
||||
|
||||
//for each rank in the enum
|
||||
rankEnum.slice().reverse().forEach((rank) => {
|
||||
//Create an option for the given rank
|
||||
const rankOption = document.createElement('option');
|
||||
rankOption.value = rank;
|
||||
rankOption.innerHTML = rank;
|
||||
rankOption.selected = user.rank == rank;
|
||||
rankSelect.appendChild(rankOption);
|
||||
});
|
||||
|
||||
//Set value to current user rank and append it to Rank Cell
|
||||
rankCell.appendChild(rankSelect);
|
||||
}
|
||||
|
||||
//Append cells to row
|
||||
entryRow.appendChild(imgCell);
|
||||
entryRow.appendChild(idCell);
|
||||
entryRow.appendChild(nameCell);
|
||||
entryRow.appendChild(rankCell);
|
||||
|
||||
//Append row to table
|
||||
this.table.appendChild(entryRow);
|
||||
|
||||
//reset input events
|
||||
this.resetInput();
|
||||
});
|
||||
}
|
||||
|
||||
clearTable(){
|
||||
//get all non-title table rows
|
||||
const rows = this.table.querySelectorAll("tr.admin-list-entry");
|
||||
|
||||
//for each row
|
||||
rows.forEach((row) => {
|
||||
//The Lord Yeeteth, and The Lord Yoinketh away...
|
||||
row.remove();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class prefrenceList{
|
||||
constructor(channel){
|
||||
this.channel = channel;
|
||||
this.inputs = document.querySelectorAll(".channel-preference-list-item");
|
||||
}
|
||||
|
||||
setupInput(){
|
||||
this.inputs.forEach((input) => {
|
||||
input.addEventListener("change", this.submitUpdate.bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
async submitUpdate(event){
|
||||
const key = event.target.id.replace("channel-preference-","");
|
||||
const value = event.target.checked;
|
||||
const settingsMap = new Map([
|
||||
[key, value]
|
||||
]);
|
||||
|
||||
this.handleUpdate(await utils.ajax.setChannelSetting(this.channel, settingsMap));
|
||||
this.handleUpdate(await utils.ajax.setChannelSetting(this.channel, settingsMap), event.target, key);
|
||||
}
|
||||
|
||||
handleUpdate(updateObj){
|
||||
this.hidden.checked = updateObj.hidden;
|
||||
handleUpdate(data, target, key){
|
||||
if(data){
|
||||
target = data[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class deleteBtn{
|
||||
constructor(channel){
|
||||
this.channel = channel;
|
||||
this.delete = document.querySelector("#channel-delete");
|
||||
|
||||
this.delete.addEventListener('click', this.promptDelete.bind(this));
|
||||
}
|
||||
|
||||
promptDelete(){
|
||||
promptDelete(){
|
||||
var confirm = window.prompt(`Warning: You are about to nuke ${this.channel} off of the face of the fucking planet, no taksie-backsies. \n \n Type in ${this.channel} to confirm.`);
|
||||
this.deleteChannel(confirm);
|
||||
}
|
||||
|
|
@ -51,4 +226,32 @@ class channelSettingsPrompt{
|
|||
}
|
||||
}
|
||||
|
||||
new channelSettingsPrompt();
|
||||
class permList{
|
||||
constructor(channel){
|
||||
this.channel = channel
|
||||
this.inputs = document.querySelectorAll(".channel-perm-select");
|
||||
this.setupInput();
|
||||
}
|
||||
|
||||
setupInput(){
|
||||
this.inputs.forEach((input) => {
|
||||
input.addEventListener("change", this.submitUpdate.bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
async submitUpdate(event){
|
||||
const key = event.target.id.replace("admin-perm-list-rank-select-","");
|
||||
const value = event.target.value;
|
||||
const permMap = new Map([
|
||||
[key, value]
|
||||
]);
|
||||
|
||||
this.handleUpdate(await utils.ajax.setChannelPermissions(this.channel, permMap), event.target, key);
|
||||
}
|
||||
|
||||
handleUpdate(data, target, key){
|
||||
target.value = data[key];
|
||||
}
|
||||
}
|
||||
|
||||
new channelSettingsPage();
|
||||
|
|
@ -47,7 +47,11 @@ class profileEditPrompt{
|
|||
//Setup properties
|
||||
this.prompt.id = `profile-${this.field}-prompt`;
|
||||
this.prompt.classList.add("profile-edit-prompt");
|
||||
this.prompt.placeholder = this.content.innerHTML;
|
||||
if(this.field == "img"){
|
||||
this.prompt.placeholder = this.content.src;
|
||||
}else{
|
||||
this.prompt.placeholder = this.content.innerHTML;
|
||||
}
|
||||
|
||||
//Setup event listener
|
||||
this.prompt.addEventListener("keydown", this.update.bind(this));
|
||||
|
|
|
|||
|
|
@ -187,6 +187,18 @@ class canopyAjaxUtils{
|
|||
}
|
||||
}
|
||||
|
||||
async getRankEnum(){
|
||||
var response = await fetch(`/api/account/rankEnum`,{
|
||||
method: "GET"
|
||||
});
|
||||
|
||||
if(response.status == 200){
|
||||
return (await response.json())
|
||||
}else{
|
||||
utils.ux.displayResponseError(await response.json());
|
||||
}
|
||||
}
|
||||
|
||||
async deleteAccount(pass){
|
||||
const response = await fetch(`/api/account/delete`,{
|
||||
method: "POST",
|
||||
|
|
@ -253,6 +265,18 @@ class canopyAjaxUtils{
|
|||
}
|
||||
}
|
||||
|
||||
async getChannelRank(channel){
|
||||
var response = await fetch(`/api/channel/rank?chanName=${channel}`,{
|
||||
method: "GET"
|
||||
});
|
||||
|
||||
if(response.status == 200){
|
||||
return (await response.json())
|
||||
}else{
|
||||
utils.ux.displayResponseError(await response.json());
|
||||
}
|
||||
}
|
||||
|
||||
async setChannelRank(chanName, user, rank){
|
||||
var response = await fetch(`/api/channel/rank`,{
|
||||
method: "POST",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue