mirror of
https://github.com/gusaul/grpcox.git
synced 2024-12-26 10:50:11 +00:00
166 lines
5.6 KiB
JavaScript
166 lines
5.6 KiB
JavaScript
let protoMap;
|
|
let showCollection;
|
|
|
|
// IIFE to setup event listener
|
|
(function () {
|
|
// add event listener on proto checkbox
|
|
// if checked the uploader and proto collection view will be displayed
|
|
// also the grpc reflection will use given proto instead of server reflection
|
|
const protoSwitch = document.getElementById("local-proto");
|
|
protoSwitch.addEventListener("change", function(event) {
|
|
const { checked } = event.target;
|
|
toggleDisplayProtoInput(checked);
|
|
});
|
|
|
|
// add event listener on upload proto file
|
|
// uploaded file extension will be checked, only those with *.proto will be processed
|
|
// add successful file to protoMap to be displayed
|
|
const protoUploader = document.getElementById("proto-file");
|
|
protoUploader.addEventListener("change", handleProtoUpload, false);
|
|
|
|
// add event listener on toggle proto collection display
|
|
// it will show / hide the proto collection
|
|
const protoCollectionToggle = document.getElementById("proto-collection-toggle");
|
|
protoCollectionToggle.addEventListener("click", toggleDisplayProtoCollection);
|
|
|
|
// init map to handle proto files
|
|
// every proto files will be unique to their name
|
|
protoMap = new Map();
|
|
|
|
// set proto collection display status to true
|
|
// by default the collection will be shown
|
|
showCollection = true;
|
|
}());
|
|
|
|
// toggle proto files display
|
|
// displaying upload button
|
|
function toggleDisplayProtoInput(show) {
|
|
const style = show ? "display: block" : "display: none";
|
|
|
|
const protoInput = document.getElementById("proto-input");
|
|
protoInput.removeAttribute("style");
|
|
protoInput.style.cssText = style;
|
|
}
|
|
|
|
// toggle proto files collection
|
|
// displaying uploaded protos collection
|
|
function toggleDisplayProtoCollection() {
|
|
const protoCollection = document.getElementsByClassName("proto-collection")[0];
|
|
protoCollection.removeAttribute("style");
|
|
const protoToggle = document.getElementById("proto-collection-toggle");
|
|
|
|
let collectionStyle = "";
|
|
let toggleText = protoToggle.innerHTML;
|
|
|
|
if (showCollection) {
|
|
collectionStyle = "display: none";
|
|
toggleText = toggleText.replace("Hide", "Show");
|
|
} else {
|
|
collectionStyle = "display: block";
|
|
toggleText = toggleText.replace("Show", "Hide");
|
|
}
|
|
|
|
protoCollection.style.cssText = collectionStyle;
|
|
protoToggle.innerHTML = toggleText;
|
|
showCollection = !showCollection;
|
|
}
|
|
|
|
// handling file upload event
|
|
// add uploaded files to protoMap to avoid duplication, on file with same name the older
|
|
// file will be replaced with the latest
|
|
// if the file isn't available before, add DOM element for UI representation
|
|
// file without *.proto won't be processed
|
|
function handleProtoUpload() {
|
|
const files = this.files;
|
|
|
|
for (const file of files) {
|
|
if (!file.name.endsWith(".proto") && !file.name.endsWith(".protoset")) {
|
|
continue;
|
|
}
|
|
if (!protoMap.has(file.name)) {
|
|
addProtoItem(file.name, file.size);
|
|
}
|
|
protoMap.set(file.name, file);
|
|
}
|
|
}
|
|
|
|
// adding proto item to proto collection view
|
|
// give visual representation to user and access to remove unwanted uploaded files
|
|
function addProtoItem(name, size) {
|
|
const protoItem = createProtoItem(name, size);
|
|
const collection = document.getElementsByClassName("proto-collection")[0];
|
|
collection.appendChild(protoItem);
|
|
}
|
|
|
|
// create dom element for proto item
|
|
// every item will be given id corresponding to it's name for easier access
|
|
function createProtoItem(name, size) {
|
|
const item = document.createElement("div");
|
|
item.classList.add("proto-item");
|
|
item.id = name;
|
|
|
|
const icon = document.createElement("img");
|
|
icon.src = "img/file.png";
|
|
icon.alt = "file icon";
|
|
icon.classList.add("proto-icon");
|
|
item.appendChild(icon);
|
|
|
|
const desc = createProtoItemDesc(name, size);
|
|
item.appendChild(desc);
|
|
|
|
return item;
|
|
}
|
|
|
|
// create dom element for proto item description
|
|
function createProtoItemDesc(name, size) {
|
|
const desc = document.createElement("div");
|
|
desc.classList.add("proto-desc");
|
|
|
|
const caption = document.createElement("span");
|
|
caption.classList.add("proto-caption");
|
|
const captionText = document.createTextNode(name.length > 15 ?
|
|
name.substring(0, 12) + "..." :
|
|
name);
|
|
caption.appendChild(captionText);
|
|
desc.appendChild(caption);
|
|
|
|
const sizeDOM = document.createElement("span");
|
|
sizeDOM.classList.add("proto-size");
|
|
const sizeText = document.createTextNode(size > 1000 ?
|
|
`${size/1000}kb` :
|
|
`${size}b`);
|
|
sizeDOM.appendChild(sizeText);
|
|
desc.appendChild(sizeDOM);
|
|
|
|
const remove = document.createElement("button");
|
|
remove.classList.add("btn", "btn-sm", "proto-remove");
|
|
remove.addEventListener("click", function() {removeProtoItem(name);});
|
|
const removeIcon = document.createElement("i");
|
|
removeIcon.classList.add("fa", "fa-trash");
|
|
remove.appendChild(removeIcon);
|
|
const removeText = document.createTextNode(" remove");
|
|
remove.appendChild(removeText);
|
|
desc.appendChild(remove);
|
|
|
|
return desc;
|
|
}
|
|
|
|
// remove proto item based on it's ID
|
|
function removeProtoItem(name) {
|
|
const item = document.getElementById(name);
|
|
item.parentNode.removeChild(item);
|
|
protoMap.delete(name);
|
|
}
|
|
|
|
// fetch all proto from protoMap
|
|
// compose it into formData to make it easier to send via ajax
|
|
function getProtos() {
|
|
const formData = new FormData();
|
|
|
|
for (const proto of protoMap.values()) {
|
|
formData.append("protos", proto, proto.name);
|
|
}
|
|
|
|
return formData;
|
|
}
|