Skip to content

Commit

Permalink
refactor: start a rewrite with multiple components (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
fraxken authored Aug 1, 2024
1 parent 087661d commit 28c3643
Show file tree
Hide file tree
Showing 9 changed files with 353 additions and 235 deletions.
64 changes: 40 additions & 24 deletions public/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,50 @@ nav#orgs {
margin: 10px 20px;
}

nav#orgs > img {
width: 18px;
height: 18px;
margin-left: 10px;
position: relative;
top: 6px;
cursor: pointer;
}

nav .org {
height: 30px;
margin-right: 8px;
position: relative;
}

nav .org:hover>img {
border: 1px solid #FFF;
filter: grayscale(40%);
}

nav .org:hover>.close {
visibility: visible;
}

nav .org .close {
position: absolute;
right: -6px;
top: -6px;
width: 14px;
height: 14px;
background: rgb(246, 208, 206) url('/images/plus.png');
background-position: center center;
background-size: 12px 12px;
border-radius: 50%;
background-repeat: no-repeat;
padding: 4px;
transform: rotate(45deg);
box-shadow: 0px 0px 1px rgba(20, 20, 20, 0.3);
visibility: hidden;
cursor: pointer;
}

nav .org img {
nav .org > img {
transition: all .5s;
border-radius: 4px;
}

Expand Down Expand Up @@ -217,28 +255,6 @@ main>.table-container {
}
}

.close {
position: absolute;
right: -6px;
top: -6px;
width: 12px;
height: 12px;
background: white url('/images/plus.png');
background-position: center center;
background-size: 12px 12px;
border-radius: 50%;
background-repeat: no-repeat;
padding: 2px;
transform: rotate(45deg);
box-shadow: 0px 0px 1px rgba(20, 20, 20, 0.3);
visibility: hidden;
cursor: pointer;
}

nav .org div:hover>.close {
visibility: visible;
}

footer {
text-align: center;
display: inline-block;
Expand All @@ -251,7 +267,7 @@ footer .footer-text {
color: #546E7A;
}

footer .footer-text strong{
footer .footer-text strong {
color: #3F51B5;
font-weight: bold;
}
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<link rel="stylesheet" href="css/filter.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/2.3.1/list.min.js"></script>
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
<script src="/js/main.js"></script>
<script src="/js/main.js" type="module"></script>
</head>

<body>
Expand Down
83 changes: 83 additions & 0 deletions public/js/components/Board.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// CONSTANTS
const kStatusBoardColumns = [
"name",
"license",
"test",
"type",
"public",
"pkg-name",
"version",
"node",
"esm",
"fork",
"fork-count",
"size",
"stars",
{ name: "last-commit", attr: "data-timestamp" },
{ name: "last-release", attr: "data-timestamp" },
"unreleased-commit",
"pr",
"issues",
"nyc",
"state",
"dep",
"devDep",
"branch"
];

export class Board {
static render() {
console.log("[Board] render");

new List("data", {
valueNames: [...kStatusBoardColumns]
});

const tags = document.getElementById("tags");
tags.style.display = "none";
for (const tagElement of document.querySelectorAll(".tag")) {
tagElement.addEventListener("click", tagElementClick);
}

const dropdown = document.getElementById("filter");
if (dropdown) {
dropdown.addEventListener("click", () => {
dropdown.classList.toggle("button-selected");
dropdown.setAttribute(
"aria-expanded", dropdown.getAttribute("aria-expanded") === "true" ? "false" : "true"
);
tags.style.display = tags.style.display === "block" ?
"none" : "block";
});
}

document.addEventListener("click", (event) => {
if (!tags.contains(event.target) && !dropdown.contains(event.target)) {
tags.style.display = "none";
dropdown.setAttribute("aria-expanded", "false");
}
});
}
}

function tagElementClick() {
this.classList.toggle("selected");

let hiddenTags = JSON.parse(localStorage.getItem("hidden-tags")) ?? [];
const dataValue = this.getAttribute("data-value");

if (hiddenTags.includes(dataValue)) {
hiddenTags = hiddenTags.filter((item) => item !== dataValue);
}
else {
hiddenTags.push(dataValue);
}

localStorage.setItem("hidden-tags", JSON.stringify(hiddenTags));

const th = document.querySelector(`[data-sort="${dataValue}"]`);
th.classList.toggle("hidden");

document.querySelectorAll(`.${dataValue}`)
.forEach((element) => element.classList.toggle("hidden"));
}
164 changes: 164 additions & 0 deletions public/js/components/Org.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Import Internal Dependencies
import { createDOMElement } from "../utils.js";

export class Organization {
// When adding org, we need to make sure that the added org become the active one
static nextActiveOrg = null;

static get orgs() {
return JSON.parse(localStorage.getItem("orgs") ?? "[]");
}

static set orgs(orgs) {
localStorage.setItem("orgs", JSON.stringify(orgs));
}

/**
* @param {!string} orgName
* @returns {void}
*/
static setActive(orgName) {
const updatedOrgs = this.orgs.map((org) => {
org.active = org.orgName === orgName;

return org;
});

localStorage.setItem("orgs", JSON.stringify(updatedOrgs));
}

static render(
callback = () => void 0,
socket
) {
console.log("[Org] render");

const orgs = this.orgs;
const popupEl = document.getElementById("add-org-popup");
const loaderEl = document.querySelector("#popup-loader");
const inputEl = document.getElementById("add-org-input");
const submitBtnEl = document.getElementById("add-org-btn");

const fragment = document.createDocumentFragment();

for (const org of orgs) {
const orgHTMLElement = createDOMElement("div", {
classList: ["org"],
childs: [
createDOMElement("img", {
attributes: {
src: org.logo,
title: org.orgName,
height: 30,
width: 30
}
})
]
});

if (orgs.length > 1) {
const closeDiv = createDOMElement("div", {
classList: ["close"]
});
closeDiv.addEventListener("click", (e) => {
e.stopPropagation();
const token = JSON.parse(localStorage.getItem("token") ?? "null");
const message = { removeOrg: org.orgName };

if (token && !isTokenExpired(token)) {
message.token = token;
}
else {
// eslint-disable-next-line no-alert
const password = prompt("Password ?", "");
message.password = password;
}

socket.send(JSON.stringify(message));
});

orgHTMLElement.appendChild(closeDiv);
}

orgHTMLElement.addEventListener("click", () => {
this.setActive(org.orgName);

document.querySelector("header").innerHTML = org.header;
document.querySelector("main").innerHTML = org.main;

if (new Date(org.lastUpdate).getTime() < Date.now() - (10 * 60 * 60 * 1000)) {
socket.send(JSON.stringify({
orgName: org.orgName,
token: JSON.parse(localStorage.getItem("token"))
}));
document.querySelector("h1").innerHTML += " (updating...)";

return;
}

this.render(callback);
callback();
});

fragment.appendChild(orgHTMLElement);
}

const addOrgEl = createDOMElement("img", {
attributes: {
src: "/images/plus.png"
}
});

addOrgEl.addEventListener("click", () => {
const formEl = document.querySelector("#add-org-form");
const closePopupEl = document.querySelector("#close-popup");

closePopupEl.addEventListener("click", () => {
popupEl.classList.remove("opened");
});

popupEl.classList.add("opened");
const controller = new AbortController();

function onSubmit(e) {
e.preventDefault();
const token = JSON.parse(localStorage.getItem("token") ?? "null");
const message = { orgName: inputEl.value };

if (token && !isTokenExpired(token)) {
message.token = token;
}
else {
// eslint-disable-next-line no-alert
const password = prompt("Password ?", "");
message.password = password;
}

socket.send(JSON.stringify(message));
loaderEl.classList.remove("hidden");
inputEl.disabled = true;
submitBtnEl.disabled = true;
controller.abort();

Organization.nextActiveOrg = inputEl.value;
}

formEl.addEventListener("submit", onSubmit, { signal: controller.signal });
});
fragment.appendChild(addOrgEl);

return fragment;
}
}

/**
* @param {!string} token
* @returns {boolean}
*/
function isTokenExpired(
token
) {
const expiry = (JSON.parse(atob(token.split(".")[1]))).exp;

return (Math.floor((new Date()).getTime() / 1000)) >= expiry;
}
Loading

0 comments on commit 28c3643

Please sign in to comment.