add a routing and page system
This commit is contained in:
parent
a620272dd9
commit
9b5f89ea39
@ -14,6 +14,7 @@
|
||||
<div id="containerId" class="container">
|
||||
<!-- 4NK Web5 Solution -->
|
||||
</div>
|
||||
<script type="module" src="/src/index.ts"></script>
|
||||
<!-- <script type="module" src="/src/index.ts"></script> -->
|
||||
<script type="module" src="/src/router.ts"></script>
|
||||
</body>
|
||||
</html>
|
102
src/html/home.js
102
src/html/home.js
@ -1,102 +0,0 @@
|
||||
import Routing from "/src/services/routing.service.ts";
|
||||
import Services from "/src/services/service.ts";
|
||||
|
||||
document.querySelectorAll('.tab').forEach(tab => {
|
||||
tab.addEventListener('click', () => {
|
||||
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
||||
tab.classList.add('active');
|
||||
|
||||
document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
|
||||
document.getElementById(tab.getAttribute('data-tab')).classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('notification-bell').addEventListener('click', openCloseNotifications);
|
||||
|
||||
|
||||
export function toggleMenu() {
|
||||
var menu = document.getElementById('menu');
|
||||
if (menu.style.display === 'block') {
|
||||
menu.style.display = 'none';
|
||||
} else {
|
||||
menu.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// Modal
|
||||
export async function openModal(myAddress, receiverAddress) {
|
||||
const router = await Routing.getInstance();
|
||||
router.openLoginModal(myAddress, receiverAddress)
|
||||
}
|
||||
|
||||
|
||||
function openCloseNotifications() {
|
||||
const notifications = document.querySelector('.notification-board')
|
||||
notifications.style.display = notifications?.style.display === 'none' ? 'block' : 'none'
|
||||
}
|
||||
|
||||
// const service = await Services.getInstance()
|
||||
// service.setNotification()
|
||||
|
||||
window.toggleMenu = toggleMenu;
|
||||
window.openModal = openModal;
|
||||
|
||||
/// Scan QR Code
|
||||
function docReady(fn) {
|
||||
// see if DOM is already available
|
||||
if (document.readyState === "complete"
|
||||
|| document.readyState === "interactive") {
|
||||
// call on next available tick
|
||||
setTimeout(fn, 1);
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", fn);
|
||||
}
|
||||
}
|
||||
|
||||
docReady(function () {
|
||||
scanDevice();
|
||||
var resultContainer = document.getElementById('qr-reader-results');
|
||||
var lastResult, countResults = 0;
|
||||
async function onScanSuccess(decodedText, decodedResult) {
|
||||
if (lastResult === decodedText) { return; }
|
||||
lastResult = decodedText;
|
||||
++countResults;
|
||||
// Handle on success condition with the decoded message.
|
||||
console.log(`Scan result ${decodedText}`, decodedResult);
|
||||
try {
|
||||
// Attempt to parse the decoded text as a URL
|
||||
const scannedUrl = new URL(decodedText);
|
||||
|
||||
// Extract the 'sp_address' parameter
|
||||
const spAddress = scannedUrl.searchParams.get('sp_address');
|
||||
|
||||
if (spAddress) {
|
||||
html5QrcodeScanner.clear();
|
||||
const service = await Services.getInstance()
|
||||
// Call the sendPairingTx function with the extracted sp_address
|
||||
await service.sendPairingTx(spAddress);
|
||||
} else {
|
||||
console.error('The scanned URL does not contain the sp_address parameter.');
|
||||
alert('Invalid QR code: sp_address parameter missing.');
|
||||
}
|
||||
} catch (error) {
|
||||
// Handle cases where decodedText is not a valid URL
|
||||
console.error('Scanned text is not a valid URL:', error);
|
||||
alert('Invalid QR code: Unable to parse URL.');
|
||||
}
|
||||
}
|
||||
|
||||
var html5QrcodeScanner = new Html5QrcodeScanner(
|
||||
"qr-reader", { fps: 10, qrbox: 250 });
|
||||
html5QrcodeScanner.render(onScanSuccess);
|
||||
});
|
||||
|
||||
function scanDevice() {
|
||||
const scannerImg = document.querySelector('#scanner')
|
||||
if(scannerImg) scannerImg.style.display = 'none'
|
||||
const scannerQrCode = document.querySelector('.qr-code-scanner')
|
||||
if(scannerQrCode) scannerQrCode.style.display = 'block'
|
||||
}
|
||||
|
||||
window.scanDevice = scanDevice
|
61
src/index.ts
61
src/index.ts
@ -1,33 +1,40 @@
|
||||
import Services from './services/service';
|
||||
// import Services from './services/service';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
try {
|
||||
// document.addEventListener('DOMContentLoaded', async () => {
|
||||
// try {
|
||||
|
||||
const services = await Services.getInstance();
|
||||
setTimeout( async () => {
|
||||
let device = await services.getDevice()
|
||||
// const services = await Services.getInstance();
|
||||
// setTimeout( async () => {
|
||||
// let device = await services.getDevice()
|
||||
// console.log("🚀 ~ setTimeout ~ device:", device)
|
||||
|
||||
if(!device) {
|
||||
device = await services.createNewDevice();
|
||||
} else {
|
||||
await services.restoreDevice(device)
|
||||
}
|
||||
await services.restoreProcesses();
|
||||
await services.restoreMessages();
|
||||
// if(!device) {
|
||||
// device = await services.createNewDevice();
|
||||
// } else {
|
||||
// await services.restoreDevice(device)
|
||||
// }
|
||||
// await services.restoreProcesses();
|
||||
// await services.restoreMessages();
|
||||
|
||||
if (services.isPaired()) { await services.injectProcessListPage() }
|
||||
else {
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString)
|
||||
const pairingAddress = urlParams.get('sp_address')
|
||||
// const amount = await services.getAmount();
|
||||
|
||||
if(pairingAddress) {
|
||||
setTimeout(async () => await services.sendPairingTx(pairingAddress), 1000)
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
// if (amount === 0n) {
|
||||
// const faucetMsg = await services.createFaucetMessage();
|
||||
// await services.sendFaucetMessage(faucetMsg);
|
||||
// }
|
||||
// if (services.isPaired()) { await services.injectProcessListPage() }
|
||||
// else {
|
||||
// const queryString = window.location.search;
|
||||
// const urlParams = new URLSearchParams(queryString)
|
||||
// const pairingAddress = urlParams.get('sp_address')
|
||||
|
||||
// if(pairingAddress) {
|
||||
// setTimeout(async () => await services.sendPairingTx(pairingAddress), 2000)
|
||||
// }
|
||||
// }
|
||||
// }, 500);
|
||||
// } catch (error) {
|
||||
// console.error(error);
|
||||
// }
|
||||
// });
|
||||
|
||||
|
114
src/pages/home/home.ts
Normal file
114
src/pages/home/home.ts
Normal file
@ -0,0 +1,114 @@
|
||||
import { Html5QrcodeScanner } from "html5-qrcode";
|
||||
import Routing from "../../services/routing.service";
|
||||
import Services from "../../services/service";
|
||||
|
||||
let resultContainer = document.getElementById('qr-reader-results');
|
||||
let lastResult: any, countResults = 0;
|
||||
|
||||
export function initHomePage(): void {
|
||||
console.log('INIT')
|
||||
document.querySelectorAll('.tab').forEach(tab => {
|
||||
|
||||
tab.addEventListener('click', () => {
|
||||
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
||||
tab.classList.add('active');
|
||||
|
||||
document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
|
||||
document.getElementById(tab.getAttribute('data-tab') as string)?.classList.add('active');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('notification-bell')?.addEventListener('click', openCloseNotifications);
|
||||
|
||||
var html5QrcodeScanner = new Html5QrcodeScanner(
|
||||
"qr-reader", { fps: 10, qrbox: 250 }, undefined);
|
||||
html5QrcodeScanner.render(onScanSuccess, undefined);
|
||||
|
||||
docReady(() => {
|
||||
scanDevice();
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function onScanSuccess(decodedText: any, decodedResult: any) {
|
||||
if (lastResult === decodedText) { return; }
|
||||
lastResult = decodedText;
|
||||
++countResults;
|
||||
// Handle on success condition with the decoded message.
|
||||
console.log(`Scan result ${decodedText}`, decodedResult);
|
||||
try {
|
||||
// Attempt to parse the decoded text as a URL
|
||||
const scannedUrl = new URL(decodedText);
|
||||
|
||||
// Extract the 'sp_address' parameter
|
||||
const spAddress = scannedUrl.searchParams.get('sp_address');
|
||||
|
||||
if (spAddress) {
|
||||
html5QrcodeScanner.clear();
|
||||
const service = await Services.getInstance()
|
||||
// Call the sendPairingTx function with the extracted sp_address
|
||||
await service.sendPairingTx(spAddress);
|
||||
} else {
|
||||
console.error('The scanned URL does not contain the sp_address parameter.');
|
||||
alert('Invalid QR code: sp_address parameter missing.');
|
||||
}
|
||||
} catch (error) {
|
||||
// Handle cases where decodedText is not a valid URL
|
||||
console.error('Scanned text is not a valid URL:', error);
|
||||
alert('Invalid QR code: Unable to parse URL.');
|
||||
}
|
||||
}
|
||||
export function toggleMenu() {
|
||||
let menu = document.getElementById('menu');
|
||||
if(menu) {
|
||||
if (menu.style.display === 'block') {
|
||||
menu.style.display = 'none';
|
||||
} else {
|
||||
menu.style.display = 'block';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//// Modal
|
||||
export async function openModal(myAddress: string, receiverAddress: string) {
|
||||
const router = await Routing.getInstance();
|
||||
router.openLoginModal(myAddress, receiverAddress)
|
||||
}
|
||||
|
||||
|
||||
function openCloseNotifications() {
|
||||
const notifications = document.querySelector('.notification-board') as HTMLDivElement
|
||||
notifications.style.display = notifications?.style.display === 'none' ? 'block' : 'none'
|
||||
}
|
||||
|
||||
// const service = await Services.getInstance()
|
||||
// service.setNotification()
|
||||
|
||||
(window as any).toggleMenu = toggleMenu;
|
||||
(window as any).openModal = openModal;
|
||||
|
||||
/// Scan QR Code
|
||||
function docReady(fn: any) {
|
||||
// see if DOM is already available
|
||||
if (document.readyState === "complete"
|
||||
|| document.readyState === "interactive") {
|
||||
// call on next available tick
|
||||
setTimeout(fn, 1);
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", fn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function scanDevice() {
|
||||
const scannerImg = document.querySelector('#scanner') as HTMLElement
|
||||
if(scannerImg) scannerImg.style.display = 'none'
|
||||
const scannerQrCode = document.querySelector('.qr-code-scanner') as HTMLElement
|
||||
if(scannerQrCode) scannerQrCode.style.display = 'block'
|
||||
}
|
||||
|
||||
(window as any).scanDevice = scanDevice
|
@ -1,7 +1,7 @@
|
||||
import Services from "/src/services/service.ts";
|
||||
|
||||
import Services from "../../services/service";
|
||||
import {IProcess } from "~/models/process.model";
|
||||
function toggleMenu() {
|
||||
const menu = document.getElementById("menu");
|
||||
const menu = document.getElementById("menu") as HTMLDivElement;
|
||||
if (menu.style.display === "block") {
|
||||
menu.style.display = "none";
|
||||
} else {
|
||||
@ -11,7 +11,7 @@ function toggleMenu() {
|
||||
|
||||
|
||||
// Initialize function, create initial tokens with itens that are already selected by the user
|
||||
function init(element) {
|
||||
function init(element: HTMLElement) {
|
||||
// Create div that wroaps all the elements inside (select, elements selected, search div) to put select inside
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.addEventListener("click", clickOnWrapper);
|
||||
@ -30,7 +30,6 @@ function init(element) {
|
||||
input.addEventListener("click", openOptions);
|
||||
|
||||
const dropdown_icon = document.createElement("a");
|
||||
dropdown_icon.setAttribute("href", "#");
|
||||
dropdown_icon.classList.add("dropdown-icon");
|
||||
|
||||
dropdown_icon.addEventListener("click", clickDropdown);
|
||||
@ -41,7 +40,7 @@ function init(element) {
|
||||
search_div.appendChild(dropdown_icon);
|
||||
|
||||
// set the wrapper as child (instead of the element)
|
||||
element.parentNode.replaceChild(wrapper, element);
|
||||
element.parentNode?.replaceChild(wrapper, element);
|
||||
// set element as child of wrapper
|
||||
wrapper.appendChild(element);
|
||||
wrapper.appendChild(search_div);
|
||||
@ -58,64 +57,65 @@ function init(element) {
|
||||
// }
|
||||
}
|
||||
|
||||
function removePlaceholder(wrapper) {
|
||||
function removePlaceholder(wrapper: HTMLElement) {
|
||||
const input_search = wrapper.querySelector(".selected-input");
|
||||
input_search.removeAttribute("placeholder");
|
||||
input_search?.removeAttribute("placeholder");
|
||||
}
|
||||
|
||||
function addPlaceholder(wrapper) {
|
||||
function addPlaceholder(wrapper: HTMLElement) {
|
||||
const input_search = wrapper.querySelector(".selected-input");
|
||||
const tokens = wrapper.querySelectorAll(".selected-wrapper");
|
||||
if (!tokens.length && !(document.activeElement === input_search))
|
||||
input_search.setAttribute("placeholder", "---------");
|
||||
input_search?.setAttribute("placeholder", "---------");
|
||||
}
|
||||
|
||||
// Listener of user search
|
||||
function inputChange(e) {
|
||||
const wrapper = e.target.parentNode.parentNode;
|
||||
const select = wrapper.querySelector("select");
|
||||
const dropdown = wrapper.querySelector(".dropdown-icon");
|
||||
function inputChange(e: Event) {
|
||||
const target = e.target as HTMLInputElement
|
||||
const wrapper = target?.parentNode?.parentNode;
|
||||
const select = wrapper?.querySelector("select") as HTMLSelectElement;
|
||||
const dropdown = wrapper?.querySelector(".dropdown-icon");
|
||||
|
||||
const input_val = e.target.value;
|
||||
const input_val = target?.value;
|
||||
|
||||
if (input_val) {
|
||||
dropdown.classList.add("active");
|
||||
dropdown?.classList.add("active");
|
||||
populateAutocompleteList(select, input_val.trim());
|
||||
} else {
|
||||
dropdown.classList.remove("active");
|
||||
dropdown?.classList.remove("active");
|
||||
const event = new Event("click");
|
||||
dropdown.dispatchEvent(event);
|
||||
dropdown?.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
// Listen for clicks on the wrapper, if click happens focus on the input
|
||||
function clickOnWrapper(e) {
|
||||
const wrapper = e.target;
|
||||
function clickOnWrapper(e: Event) {
|
||||
const wrapper = e.target as HTMLElement;
|
||||
if (wrapper.tagName == "DIV") {
|
||||
const input_search = wrapper.querySelector(".selected-input");
|
||||
const dropdown = wrapper.querySelector(".dropdown-icon");
|
||||
if (!dropdown.classList.contains("active")) {
|
||||
if (!dropdown?.classList.contains("active")) {
|
||||
const event = new Event("click");
|
||||
dropdown.dispatchEvent(event);
|
||||
dropdown?.dispatchEvent(event);
|
||||
}
|
||||
input_search.focus();
|
||||
(input_search as HTMLInputElement)?.focus();
|
||||
removePlaceholder(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
function openOptions(e) {
|
||||
const input_search = e.target;
|
||||
const wrapper = input_search.parentElement.parentElement;
|
||||
const dropdown = wrapper.querySelector(".dropdown-icon");
|
||||
if (!dropdown.classList.contains("active")) {
|
||||
function openOptions(e: Event) {
|
||||
const input_search = e.target as HTMLElement;
|
||||
const wrapper = input_search?.parentElement?.parentElement;
|
||||
const dropdown = wrapper?.querySelector(".dropdown-icon");
|
||||
if (!dropdown?.classList.contains("active")) {
|
||||
const event = new Event("click");
|
||||
dropdown.dispatchEvent(event);
|
||||
dropdown?.dispatchEvent(event);
|
||||
}
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
// Function that create a token inside of a wrapper with the given value
|
||||
function createToken(wrapper, value) {
|
||||
function createToken(wrapper: HTMLElement, value: any) {
|
||||
const search = wrapper.querySelector(".search-container");
|
||||
const inputInderline = document.querySelector(".selected-processes");
|
||||
// Create token wrapper
|
||||
@ -128,48 +128,48 @@ function createToken(wrapper, value) {
|
||||
close.classList.add("selected-close");
|
||||
close.setAttribute("tabindex", "-1");
|
||||
close.setAttribute("data-option", value);
|
||||
close.setAttribute("data-hits", 0);
|
||||
close.setAttribute("data-hits", '0');
|
||||
close.setAttribute("href", "#");
|
||||
close.innerText = "x";
|
||||
close.addEventListener("click", removeToken);
|
||||
token.appendChild(token_span);
|
||||
token.appendChild(close);
|
||||
inputInderline.appendChild(token);
|
||||
inputInderline?.appendChild(token);
|
||||
}
|
||||
|
||||
// Listen for clicks in the dropdown option
|
||||
function clickDropdown(e) {
|
||||
const dropdown = e.target;
|
||||
const wrapper = dropdown.parentNode.parentNode;
|
||||
const input_search = wrapper.querySelector(".selected-input");
|
||||
const select = wrapper.querySelector("select");
|
||||
function clickDropdown(e: Event) {
|
||||
const dropdown = e.target as HTMLElement;
|
||||
const wrapper = dropdown?.parentNode?.parentNode;
|
||||
const input_search = wrapper?.querySelector(".selected-input") as HTMLInputElement;
|
||||
const select = wrapper?.querySelector("select") as HTMLSelectElement;
|
||||
dropdown.classList.toggle("active");
|
||||
|
||||
if (dropdown.classList.contains("active")) {
|
||||
removePlaceholder(wrapper);
|
||||
input_search.focus();
|
||||
removePlaceholder(wrapper as HTMLElement);
|
||||
input_search?.focus();
|
||||
|
||||
if (!input_search.value) {
|
||||
if (!input_search?.value) {
|
||||
populateAutocompleteList(select, "", true);
|
||||
} else {
|
||||
populateAutocompleteList(select, input_search.value);
|
||||
}
|
||||
} else {
|
||||
clearAutocompleteList(select);
|
||||
addPlaceholder(wrapper);
|
||||
addPlaceholder(wrapper as HTMLElement);
|
||||
}
|
||||
}
|
||||
|
||||
// Clears the results of the autocomplete list
|
||||
function clearAutocompleteList(select) {
|
||||
function clearAutocompleteList(select: HTMLSelectElement) {
|
||||
const wrapper = select.parentNode;
|
||||
|
||||
const autocomplete_list = wrapper.querySelector(".autocomplete-list");
|
||||
autocomplete_list.innerHTML = "";
|
||||
const autocomplete_list = wrapper?.querySelector(".autocomplete-list");
|
||||
if(autocomplete_list) autocomplete_list.innerHTML = "";
|
||||
}
|
||||
|
||||
// Populate the autocomplete list following a given query from the user
|
||||
function populateAutocompleteList(select, query, dropdown = false) {
|
||||
function populateAutocompleteList(select: HTMLSelectElement, query: string, dropdown = false) {
|
||||
const { autocomplete_options } = getOptions(select);
|
||||
|
||||
let options_to_show;
|
||||
@ -178,9 +178,9 @@ function populateAutocompleteList(select, query, dropdown = false) {
|
||||
else options_to_show = autocomplete(query, autocomplete_options);
|
||||
|
||||
const wrapper = select.parentNode;
|
||||
const input_search = wrapper.querySelector(".search-container");
|
||||
const autocomplete_list = wrapper.querySelector(".autocomplete-list");
|
||||
autocomplete_list.innerHTML = "";
|
||||
const input_search = wrapper?.querySelector(".search-container");
|
||||
const autocomplete_list = wrapper?.querySelector(".autocomplete-list");
|
||||
if(autocomplete_list) autocomplete_list.innerHTML = "";
|
||||
const result_size = options_to_show.length;
|
||||
|
||||
if (result_size == 1) {
|
||||
@ -188,7 +188,7 @@ function populateAutocompleteList(select, query, dropdown = false) {
|
||||
li.innerText = options_to_show[0];
|
||||
li.setAttribute("data-value", options_to_show[0]);
|
||||
li.addEventListener("click", selectOption);
|
||||
autocomplete_list.appendChild(li);
|
||||
autocomplete_list?.appendChild(li);
|
||||
if (query.length == options_to_show[0].length) {
|
||||
const event = new Event("click");
|
||||
li.dispatchEvent(event);
|
||||
@ -199,18 +199,18 @@ function populateAutocompleteList(select, query, dropdown = false) {
|
||||
li.innerText = options_to_show[i];
|
||||
li.setAttribute("data-value", options_to_show[i]);
|
||||
li.addEventListener("click", selectOption);
|
||||
autocomplete_list.appendChild(li);
|
||||
autocomplete_list?.appendChild(li);
|
||||
}
|
||||
} else {
|
||||
const li = document.createElement("li");
|
||||
li.classList.add("not-cursor");
|
||||
li.innerText = "No options found";
|
||||
autocomplete_list.appendChild(li);
|
||||
autocomplete_list?.appendChild(li);
|
||||
}
|
||||
}
|
||||
|
||||
// Listener to autocomplete results when clicked set the selected property in the select option
|
||||
function selectOption(e) {
|
||||
function selectOption(e: any) {
|
||||
const wrapper = e.target.parentNode.parentNode.parentNode;
|
||||
const input_search = wrapper.querySelector(".selected-input");
|
||||
const option = wrapper.querySelector(
|
||||
@ -243,7 +243,7 @@ function selectOption(e) {
|
||||
}
|
||||
|
||||
// function that returns a list with the autcomplete list of matches
|
||||
function autocomplete(query, options) {
|
||||
function autocomplete(query: string, options: any) {
|
||||
// No query passed, just return entire list
|
||||
if (!query) {
|
||||
return options;
|
||||
@ -261,7 +261,7 @@ function autocomplete(query, options) {
|
||||
}
|
||||
|
||||
// Returns the options that are selected by the user and the ones that are not
|
||||
function getOptions(select) {
|
||||
function getOptions(select: HTMLSelectElement) {
|
||||
// Select all the options available
|
||||
const all_options = Array.from(select.querySelectorAll("option")).map(
|
||||
(el) => el.value
|
||||
@ -270,10 +270,10 @@ function getOptions(select) {
|
||||
// Get the options that are selected from the user
|
||||
const options_selected = Array.from(
|
||||
select.querySelectorAll("option:checked")
|
||||
).map((el) => el.value);
|
||||
).map((el: any) => el.value);
|
||||
|
||||
// Create an autocomplete options array with the options that are not selected by the user
|
||||
const autocomplete_options = [];
|
||||
const autocomplete_options: any[] = [];
|
||||
all_options.forEach((option) => {
|
||||
if (!options_selected.includes(option)) {
|
||||
autocomplete_options.push(option);
|
||||
@ -289,62 +289,63 @@ function getOptions(select) {
|
||||
}
|
||||
|
||||
// Listener for when the user wants to remove a given token.
|
||||
function removeToken(e) {
|
||||
function removeToken(e: Event) {
|
||||
// Get the value to remove
|
||||
const value_to_remove = e.target.dataset.option;
|
||||
const wrapper = e.target.parentNode.parentNode.parentNode;
|
||||
const input_search = wrapper.querySelector(".selected-input");
|
||||
const dropdown = wrapper.querySelector(".dropdown-icon");
|
||||
const target = e.target as HTMLSelectElement
|
||||
const value_to_remove = target.dataset.option;
|
||||
const wrapper = target.parentNode?.parentNode?.parentNode;
|
||||
const input_search = wrapper?.querySelector(".selected-input");
|
||||
const dropdown = wrapper?.querySelector(".dropdown-icon");
|
||||
// Get the options in the select to be unselected
|
||||
const option_to_unselect = wrapper.querySelector(
|
||||
const option_to_unselect = wrapper?.querySelector(
|
||||
`select option[value="${value_to_remove}"]`
|
||||
);
|
||||
option_to_unselect.removeAttribute("selected");
|
||||
option_to_unselect?.removeAttribute("selected");
|
||||
// Remove token attribute
|
||||
e.target.parentNode.remove();
|
||||
dropdown.classList.remove("active");
|
||||
const process = document.querySelector("#" + e.target.dataset.option);
|
||||
process.remove();
|
||||
(target.parentNode as any)?.remove();
|
||||
dropdown?.classList.remove("active");
|
||||
const process = document.querySelector("#" + target.dataset.option);
|
||||
process?.remove();
|
||||
}
|
||||
|
||||
// Listen for 2 sequence of hits on the delete key, if this happens delete the last token if exist
|
||||
function deletePressed(e) {
|
||||
const wrapper = e.target.parentNode.parentNode;
|
||||
const input_search = e.target;
|
||||
function deletePressed(e: KeyboardEvent) {
|
||||
const input_search = e.target as HTMLInputElement;
|
||||
const wrapper = input_search?.parentNode?.parentNode;
|
||||
const key = e.keyCode || e.charCode;
|
||||
const tokens = wrapper.querySelectorAll(".selected-wrapper");
|
||||
const tokens = wrapper?.querySelectorAll(".selected-wrapper");
|
||||
|
||||
if (tokens.length) {
|
||||
if (tokens?.length) {
|
||||
const last_token_x = tokens[tokens.length - 1].querySelector("a");
|
||||
let hits = +last_token_x.dataset.hits;
|
||||
let hits = +(last_token_x?.dataset?.hits || 0);
|
||||
|
||||
if (key == 8 || key == 46) {
|
||||
if (!input_search.value) {
|
||||
if (hits > 1) {
|
||||
// Trigger delete event
|
||||
const event = new Event("click");
|
||||
last_token_x.dispatchEvent(event);
|
||||
last_token_x?.dispatchEvent(event);
|
||||
} else {
|
||||
last_token_x.dataset.hits = 2;
|
||||
if(last_token_x?.dataset.hits) last_token_x.dataset.hits = '2';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
last_token_x.dataset.hits = 0;
|
||||
if(last_token_x?.dataset.hits) last_token_x.dataset.hits = '0';
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function addOption(target, val, text) {
|
||||
const select = document.querySelector(target);
|
||||
let opt = document.createElement("option");
|
||||
opt.value = val;
|
||||
opt.innerHTML = text;
|
||||
select.appendChild(opt);
|
||||
}
|
||||
// function addOption(target, val, text) {
|
||||
// const select = document.querySelector(target);
|
||||
// let opt = document.createElement("option");
|
||||
// opt.value = val;
|
||||
// opt.innerHTML = text;
|
||||
// select.appendChild(opt);
|
||||
// }
|
||||
|
||||
// get select that has the options available
|
||||
const select = document.querySelectorAll("[data-multi-select-plugin]");
|
||||
const select = document.querySelectorAll("[data-multi-select-plugin]") as NodeListOf<HTMLElement>;
|
||||
select.forEach((select) => {
|
||||
console.log(select);
|
||||
init(select);
|
||||
@ -356,18 +357,18 @@ document.addEventListener("click", () => {
|
||||
const select = document.querySelectorAll("[data-multi-select-plugin]");
|
||||
for (let i = 0; i < select.length; i++) {
|
||||
if (event) {
|
||||
var isClickInside = select[i].parentElement.parentElement.contains(
|
||||
event.target
|
||||
var isClickInside = select[i].parentElement?.parentElement?.contains(
|
||||
event.target as Node
|
||||
);
|
||||
|
||||
if (!isClickInside) {
|
||||
const wrapper = select[i].parentElement.parentElement;
|
||||
const dropdown = wrapper.querySelector(".dropdown-icon");
|
||||
const autocomplete_list = wrapper.querySelector(".autocomplete-list");
|
||||
const wrapper = select[i].parentElement?.parentElement;
|
||||
const dropdown = wrapper?.querySelector(".dropdown-icon");
|
||||
const autocomplete_list = wrapper?.querySelector(".autocomplete-list");
|
||||
//the click was outside the specifiedElement, do something
|
||||
dropdown.classList.remove("active");
|
||||
autocomplete_list.innerHTML = "";
|
||||
addPlaceholder(wrapper);
|
||||
dropdown?.classList.remove("active");
|
||||
if(autocomplete_list) autocomplete_list.innerHTML = "";
|
||||
addPlaceholder(wrapper as HTMLElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -379,4 +380,97 @@ export async function unpair() {
|
||||
await service.unpairDevice()
|
||||
}
|
||||
|
||||
window.unpair = unpair;
|
||||
(window as any).unpair = unpair;
|
||||
|
||||
|
||||
async function showSelectedProcess(event: MouseEvent) {
|
||||
const elem = event.target;
|
||||
if(elem) {
|
||||
|
||||
const cardContent = document.querySelector(".card-content");
|
||||
|
||||
const processes = await getProcesses();
|
||||
console.log("🚀 ~ Services ~ showSelectedProcess ~ processes:", processes)
|
||||
const process = processes.find((process: any) => process.name === (elem as any).dataset.value);
|
||||
if (process) {
|
||||
const processDiv = document.createElement("div");
|
||||
processDiv.className = "process";
|
||||
processDiv.id = process.name;
|
||||
const titleDiv = document.createElement("div");
|
||||
titleDiv.className = "process-title";
|
||||
titleDiv.innerHTML = `${process.name} : ${process.description}`;
|
||||
processDiv.appendChild(titleDiv);
|
||||
for (const zone of process.zoneList) {
|
||||
const zoneElement = document.createElement("div");
|
||||
zoneElement.className = "process-element";
|
||||
zoneElement.setAttribute('zone-id', zone.id.toString())
|
||||
zoneElement.innerHTML = `Zone ${zone.id} : ${zone.name}`;
|
||||
const service = await Services.getInstance()
|
||||
service.addSubscription(zoneElement, 'click', 'goToProcessPage')
|
||||
processDiv.appendChild(zoneElement);
|
||||
}
|
||||
if(cardContent) cardContent.appendChild(processDiv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function goToProcessPage(event: MouseEvent) {
|
||||
const target = event.target as HTMLDivElement;
|
||||
const zoneId = target?.getAttribute('zone-id');
|
||||
const processList = document.querySelectorAll('.process-element');
|
||||
if(processList) {
|
||||
for(const process of processList) {
|
||||
process.classList.remove('selected')
|
||||
}
|
||||
}
|
||||
target.classList.add('selected')
|
||||
|
||||
console.log('=======================> going to process page', zoneId)
|
||||
}
|
||||
|
||||
async function getProcesses(): Promise<IProcess[]> {
|
||||
const service = await Services.getInstance()
|
||||
// const processes = service.getProcesses()
|
||||
// console.log("🚀 ~ Services ~ getProcesses ~ processes:", processes)
|
||||
return [
|
||||
{
|
||||
id: 1,
|
||||
name: "Messaging",
|
||||
description: "Encrypted messages",
|
||||
zoneList: [
|
||||
{
|
||||
id: 1,
|
||||
name: "General",
|
||||
path: '/test'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Storage",
|
||||
description: "Distributed storage",
|
||||
zoneList: [
|
||||
{
|
||||
id: 1,
|
||||
name: "Paris",
|
||||
path: '/test'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Normandy",
|
||||
path: '/test'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "New York",
|
||||
path: '/test'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Moscow",
|
||||
path: '/test'
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
104
src/router.ts
Normal file
104
src/router.ts
Normal file
@ -0,0 +1,104 @@
|
||||
import '../public/style/4nk.css';
|
||||
import { initHomePage } from './pages/home/home';
|
||||
import Services from './services/service';
|
||||
|
||||
const routes: { [key: string]: string } = {
|
||||
'home': '/src/pages/home/home.html',
|
||||
'process': '/src/pages/process/process.html',
|
||||
};
|
||||
|
||||
export async function navigate(path: string) {
|
||||
path = path.replace(/^\//, '');
|
||||
if (!routes[path]) {
|
||||
path = 'home';
|
||||
} else {
|
||||
}
|
||||
|
||||
await handleLocation(path);
|
||||
}
|
||||
|
||||
async function handleLocation(path: string) {
|
||||
const isPaired = await init()
|
||||
console.log("🚀 ~ handleLocation ~ isPaired:", isPaired)
|
||||
// if(!isPaired) path = 'home'
|
||||
const routeHtml = routes[path] || routes['home'];
|
||||
|
||||
const content = document.getElementById('containerId');
|
||||
if (content) {
|
||||
const html = await fetch(routeHtml).then(data => data.text());
|
||||
content.innerHTML = html;
|
||||
|
||||
await new Promise(requestAnimationFrame);
|
||||
|
||||
if(path === "home") {
|
||||
const { initHomePage } = await import('./pages/home/home');
|
||||
initHomePage()
|
||||
}
|
||||
else if (path === "process") {
|
||||
await import('./pages/process/process');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.onpopstate = () => handleLocation('home');
|
||||
window.onclick = (event: MouseEvent) => {
|
||||
const target = event.target as HTMLElement;
|
||||
if (target.tagName === 'A') {
|
||||
event.preventDefault();
|
||||
const path = target.getAttribute('href');
|
||||
if (path) {
|
||||
navigate(path);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
async function init(): Promise<boolean> {
|
||||
let isPaired = false;
|
||||
try {
|
||||
|
||||
const services = await Services.getInstance();
|
||||
setTimeout( async () => {
|
||||
let device = await services.getDevice()
|
||||
console.log("🚀 ~ setTimeout ~ device:", device)
|
||||
|
||||
if(!device) {
|
||||
device = await services.createNewDevice();
|
||||
} else {
|
||||
await services.restoreDevice(device)
|
||||
}
|
||||
await services.restoreProcesses();
|
||||
await services.restoreMessages();
|
||||
|
||||
const amount = await services.getAmount();
|
||||
|
||||
if (amount === 0n) {
|
||||
const faucetMsg = await services.createFaucetMessage();
|
||||
await services.sendFaucetMessage(faucetMsg);
|
||||
}
|
||||
if (services.isPaired()) {
|
||||
isPaired = true;
|
||||
await navigate('process');
|
||||
}
|
||||
else {
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString)
|
||||
const pairingAddress = urlParams.get('sp_address')
|
||||
if(pairingAddress) {
|
||||
setTimeout(async () => await services.sendPairingTx(pairingAddress), 2000)
|
||||
}
|
||||
}
|
||||
return isPaired
|
||||
|
||||
}, 200);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return isPaired
|
||||
}
|
||||
return isPaired
|
||||
|
||||
}
|
||||
|
||||
(async () => {
|
||||
await navigate('home');
|
||||
})();
|
@ -4,6 +4,7 @@ import modalScript from '../html/login-modal.js?raw';
|
||||
import confirmationModalScript from '../html/confirmation-modal.js?raw';
|
||||
import Services from './service';
|
||||
import { U32_MAX } from './service';
|
||||
import { navigate } from '../router';
|
||||
|
||||
|
||||
export default class Routing {
|
||||
@ -83,7 +84,6 @@ export default class Routing {
|
||||
confirmLogin() {
|
||||
console.log('=============> Confirm Login')
|
||||
const loginTx = this.sdkClient.create_login_transaction(1)
|
||||
console.log("🚀 ~ Routing ~ confirmLogin ~ loginTx:", loginTx)
|
||||
this.sdkClient.login('LOGIN', loginTx)
|
||||
}
|
||||
async closeLoginModal() {
|
||||
@ -105,7 +105,7 @@ export default class Routing {
|
||||
this.paired_addresses = []
|
||||
const newDevice = await service.dumpDevice();
|
||||
await service.saveDevice(newDevice);
|
||||
service.injectProcessListPage();
|
||||
navigate('process');
|
||||
}
|
||||
|
||||
async closeConfirmationModal() {
|
||||
|
@ -1,15 +1,14 @@
|
||||
// import { WebSocketClient } from '../websockets';
|
||||
import { INotification } from '~/models/notification.model';
|
||||
import homePage from '../html/home.html?raw';
|
||||
import homeScript from '../html/home.js?raw';
|
||||
import processPage from '../html/process.html?raw';
|
||||
import processScript from '../html/process.js?raw';
|
||||
import homePage from '../pages/home/home.html?raw';
|
||||
import homeScript from '../pages/home/home.ts?raw';
|
||||
import processPage from '../pages/process/process.html?raw';
|
||||
import processScript from '../pages/process/process.js?raw';
|
||||
import { IProcess } from '~/models/process.model';
|
||||
// import Database from './database';
|
||||
import { WebSocketClient } from '../websockets';
|
||||
import QRCode from 'qrcode'
|
||||
import { servicesVersion } from 'typescript';
|
||||
import { ApiReturn, CachedMessage, Member } from '../../dist/pkg/sdk_client';
|
||||
import { ApiReturn } from '../../dist/pkg/sdk_client';
|
||||
import Routing from './routing.service';
|
||||
|
||||
type ProcessesCache = {
|
||||
@ -27,10 +26,10 @@ export default class Services {
|
||||
private websocketConnection: WebSocketClient | null = null;
|
||||
private processes: IProcess[] | null = null;
|
||||
private notifications: INotification[] | null = null;
|
||||
private subscriptions: { element: Element; event: string; eventHandler: string; }[] = [];
|
||||
private subscriptions: {element: Element; event: string; eventHandler: string;}[] = [] ;
|
||||
private database: any
|
||||
// Private constructor to prevent direct instantiation from outside
|
||||
private constructor() { }
|
||||
private constructor() {}
|
||||
|
||||
// Method to access the singleton instance of Services
|
||||
public static async getInstance(): Promise<Services> {
|
||||
@ -57,7 +56,6 @@ export default class Services {
|
||||
this.sdkClient = await import("../../dist/pkg/sdk_client");
|
||||
this.sdkClient.setup();
|
||||
await this.addWebsocketConnection(wsurl);
|
||||
await this.recoverInjectHtml();
|
||||
}
|
||||
|
||||
public async addWebsocketConnection(url: string): Promise<void> {
|
||||
@ -69,27 +67,10 @@ export default class Services {
|
||||
}
|
||||
}
|
||||
|
||||
public async recoverInjectHtml(): Promise<void> {
|
||||
const container = document.getElementById('containerId');
|
||||
|
||||
if (!container) {
|
||||
console.error("No html container");
|
||||
return;
|
||||
}
|
||||
|
||||
container.innerHTML = homePage;
|
||||
|
||||
const newScript = document.createElement('script')
|
||||
newScript.setAttribute('type', 'module')
|
||||
newScript.textContent = homeScript;
|
||||
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
||||
}
|
||||
|
||||
private generateQRCode = async (text: string) => {
|
||||
console.log("🚀 ~ Services ~ generateQRCode= ~ text:", text)
|
||||
try {
|
||||
const container = document.getElementById('containerId');
|
||||
const currentUrl = window.location.href;
|
||||
const currentUrl = 'https://' + window.location.host;
|
||||
const url = await QRCode.toDataURL(currentUrl + "?sp_address=" + text);
|
||||
const qrCode = container?.querySelector('.qr-code img');
|
||||
qrCode?.setAttribute('src', url)
|
||||
@ -158,7 +139,7 @@ export default class Services {
|
||||
}
|
||||
|
||||
//Get emojis from other device
|
||||
public async emojisPairingRequest() {
|
||||
public async emojisPairingRequest () {
|
||||
try {
|
||||
const container = document.getElementById('containerId');
|
||||
|
||||
@ -174,7 +155,7 @@ export default class Services {
|
||||
const emojiDisplay = container?.querySelector('.pairing-request');
|
||||
|
||||
if (emojiDisplay) {
|
||||
emojiDisplay.textContent = "(Request from: " + emojis + ")";
|
||||
emojiDisplay.textContent = "(Request from: " +emojis+")";
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
@ -226,7 +207,6 @@ export default class Services {
|
||||
// Si ce n'est pas une URL valide, on garde l'adresse originale
|
||||
console.log("Ce n'est pas une URL valide, on garde l'adresse originale.");
|
||||
}
|
||||
|
||||
if (address) {
|
||||
const emojis = await this.addressToEmoji(address);
|
||||
if (emojiDisplay) {
|
||||
@ -250,14 +230,13 @@ export default class Services {
|
||||
this.onOkButtonClick();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async onOkButtonClick() {
|
||||
const addressInput = (document.getElementById('addressInput') as HTMLInputElement).value;
|
||||
await this.sendPairingTx(addressInput);
|
||||
}
|
||||
|
||||
|
||||
public isPaired(): boolean | undefined {
|
||||
try {
|
||||
return this.sdkClient.is_linking();
|
||||
@ -281,7 +260,7 @@ export default class Services {
|
||||
"roles": {
|
||||
"owner": {
|
||||
"members":
|
||||
[{ sp_addresses: [myAddress, recipientAddress] }],
|
||||
[{sp_addresses: [myAddress, recipientAddress]}],
|
||||
"validation_rules":
|
||||
[
|
||||
{
|
||||
@ -309,12 +288,6 @@ export default class Services {
|
||||
}
|
||||
|
||||
public async sendPairingTx(spAddress: string): Promise<void> {
|
||||
const amount = this.sdkClient.get_available_amount();
|
||||
|
||||
if (amount === 0n) {
|
||||
const faucetMsg = this.sdkClient.create_faucet_msg();
|
||||
await this.sendFaucetMessage(faucetMsg);
|
||||
}
|
||||
|
||||
const localAddress = this.sdkClient.get_address();
|
||||
const emptyTxid = '0'.repeat(64)
|
||||
@ -327,10 +300,10 @@ export default class Services {
|
||||
return
|
||||
}
|
||||
|
||||
setTimeout(async () => {
|
||||
setTimeout( async () => {
|
||||
const apiReturn = this.prepareProcessTx(localAddress, spAddress)
|
||||
await this.handleApiReturn(apiReturn);
|
||||
}, 100)
|
||||
}, 1500)
|
||||
|
||||
return
|
||||
}
|
||||
@ -363,7 +336,6 @@ export default class Services {
|
||||
// console.log("🚀 ~ WebSocketClient ~ this.ws.onopen= ~ faucetMessage:", message)
|
||||
await this.websocketConnection?.sendMessage('Faucet', message);
|
||||
}
|
||||
|
||||
async parseCipher(message: string) {
|
||||
// try {
|
||||
// JSON.parse(message)
|
||||
@ -388,7 +360,7 @@ export default class Services {
|
||||
try {
|
||||
// console.log('==============> sending txxxxxxx parser', tx)
|
||||
const parsedTx = await this.sdkClient.parse_new_tx(tx, 0, 0.0001)
|
||||
if (parsedTx) {
|
||||
if(parsedTx) {
|
||||
console.log("🚀 ~ Services ~ parseNewTx ~ parsedTx:", parsedTx)
|
||||
try {
|
||||
await this.handleApiReturn(parsedTx);
|
||||
@ -398,7 +370,7 @@ export default class Services {
|
||||
console.error("Failed to update device with new tx");
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
} catch(e) {
|
||||
console.trace(e);
|
||||
}
|
||||
}
|
||||
@ -430,7 +402,7 @@ export default class Services {
|
||||
}
|
||||
}
|
||||
|
||||
if (apiReturn.updated_cached_msg && apiReturn.updated_cached_msg.length) {
|
||||
if(apiReturn.updated_cached_msg && apiReturn.updated_cached_msg.length) {
|
||||
apiReturn.updated_cached_msg.forEach((msg, index) => {
|
||||
// console.debug(`CachedMessage ${index}:`, msg);
|
||||
// Save the message to local storage
|
||||
@ -510,9 +482,8 @@ export default class Services {
|
||||
// }
|
||||
// }
|
||||
|
||||
async getAmount() {
|
||||
async getAmount(): Promise<BigInt> {
|
||||
const amount = await this.sdkClient.get_available_amount()
|
||||
console.log("🚀 ~ Services ~ getAmount ~ amount:", amount)
|
||||
return amount
|
||||
}
|
||||
|
||||
@ -547,7 +518,7 @@ export default class Services {
|
||||
return message;
|
||||
}
|
||||
|
||||
private addSubscription(element: Element, event: string, eventHandler: string): void {
|
||||
addSubscription(element: Element, event: string, eventHandler: string): void {
|
||||
this.subscriptions.push({ element, event, eventHandler });
|
||||
element.addEventListener(event, (this as any)[eventHandler].bind(this));
|
||||
}
|
||||
@ -567,8 +538,6 @@ export default class Services {
|
||||
//Adress to Emoji integration
|
||||
this.displayEmojis(spAddress)
|
||||
//Adress to Emoji integration
|
||||
|
||||
|
||||
return spAddress;
|
||||
}
|
||||
|
||||
@ -683,37 +652,9 @@ export default class Services {
|
||||
this.subscriptions = [];
|
||||
}
|
||||
|
||||
async injectProcessListPage(): Promise<void> {
|
||||
const container = document.getElementById('containerId');
|
||||
|
||||
if (!container) {
|
||||
console.error("No html container");
|
||||
return;
|
||||
}
|
||||
|
||||
this.cleanSubscriptions()
|
||||
|
||||
// const user = services.sdkClient.create_user('Test', 'test', 10, 1, 'Messaging')
|
||||
// console.log("🚀 ~ Services ~ injectProcessListPage ~ user:", user)
|
||||
|
||||
// const database = await Database.getInstance();
|
||||
// const indexedDb = await database.getDb();
|
||||
// await database.writeObject(indexedDb, database.getStoreList().AnkUser, user.user, null);
|
||||
container.innerHTML = processPage;
|
||||
const newScript = document.createElement('script');
|
||||
newScript.setAttribute('type', 'module')
|
||||
newScript.textContent = processScript;
|
||||
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
||||
|
||||
this.processes = await this.getProcesses();
|
||||
if (this.processes) {
|
||||
this.setProcessesInSelectElement(this.processes)
|
||||
}
|
||||
}
|
||||
|
||||
public async setProcessesInSelectElement(processList: any[]) {
|
||||
const select = document.querySelector(".select-field");
|
||||
if (select) {
|
||||
if(select) {
|
||||
for (const process of processList) {
|
||||
const option = document.createElement("option");
|
||||
option.setAttribute("value", process.name);
|
||||
@ -722,11 +663,11 @@ export default class Services {
|
||||
}
|
||||
}
|
||||
const optionList = document.querySelector('.autocomplete-list');
|
||||
if (optionList) {
|
||||
if(optionList) {
|
||||
const observer = new MutationObserver((mutations, observer) => {
|
||||
const options = optionList.querySelectorAll('li')
|
||||
if (options) {
|
||||
for (const option of options) {
|
||||
if(options) {
|
||||
for(const option of options) {
|
||||
this.addSubscription(option, 'click', 'showSelectedProcess')
|
||||
}
|
||||
}
|
||||
@ -743,95 +684,7 @@ export default class Services {
|
||||
const options = target?.querySelectorAll('li')
|
||||
}
|
||||
|
||||
public async showSelectedProcess(event: MouseEvent) {
|
||||
const elem = event.target;
|
||||
if (elem) {
|
||||
|
||||
const cardContent = document.querySelector(".card-content");
|
||||
|
||||
const processes = await this.getProcesses();
|
||||
console.log("🚀 ~ Services ~ showSelectedProcess ~ processes:", processes)
|
||||
const process = processes.find((process: any) => process.name === (elem as any).dataset.value);
|
||||
if (process) {
|
||||
const processDiv = document.createElement("div");
|
||||
processDiv.className = "process";
|
||||
processDiv.id = process.name;
|
||||
const titleDiv = document.createElement("div");
|
||||
titleDiv.className = "process-title";
|
||||
titleDiv.innerHTML = `${process.name} : ${process.description}`;
|
||||
processDiv.appendChild(titleDiv);
|
||||
for (const zone of process.zoneList) {
|
||||
const zoneElement = document.createElement("div");
|
||||
zoneElement.className = "process-element";
|
||||
zoneElement.setAttribute('zone-id', zone.id.toString())
|
||||
zoneElement.innerHTML = `Zone ${zone.id} : ${zone.name}`;
|
||||
this.addSubscription(zoneElement, 'click', 'goToProcessPage')
|
||||
processDiv.appendChild(zoneElement);
|
||||
}
|
||||
if (cardContent) cardContent.appendChild(processDiv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goToProcessPage(event: MouseEvent) {
|
||||
const target = event.target as HTMLDivElement;
|
||||
const zoneId = target?.getAttribute('zone-id');
|
||||
const processList = document.querySelectorAll('.process-element');
|
||||
if (processList) {
|
||||
for (const process of processList) {
|
||||
process.classList.remove('selected')
|
||||
}
|
||||
}
|
||||
target.classList.add('selected')
|
||||
|
||||
console.log('=======================> going to process page', zoneId)
|
||||
}
|
||||
|
||||
async getProcesses(): Promise<IProcess[]> {
|
||||
const processes = this.sdkClient.get_processes()
|
||||
console.log("🚀 ~ Services ~ getProcesses ~ processes:", processes)
|
||||
return [
|
||||
{
|
||||
id: 1,
|
||||
name: "Messaging",
|
||||
description: "Encrypted messages",
|
||||
zoneList: [
|
||||
{
|
||||
id: 1,
|
||||
name: "General",
|
||||
path: '/test'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Storage",
|
||||
description: "Distributed storage",
|
||||
zoneList: [
|
||||
{
|
||||
id: 1,
|
||||
name: "Paris",
|
||||
path: '/test'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Normandy",
|
||||
path: '/test'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "New York",
|
||||
path: '/test'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Moscow",
|
||||
path: '/test'
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
getNotifications(): INotification[] {
|
||||
return [
|
||||
@ -863,11 +716,11 @@ export default class Services {
|
||||
const badge = document.querySelector('.notification-badge') as HTMLDivElement
|
||||
const notifications = this.notifications
|
||||
const noNotifications = document.querySelector('.no-notification') as HTMLDivElement
|
||||
if (notifications?.length) {
|
||||
if(notifications?.length) {
|
||||
badge.innerText = notifications.length.toString()
|
||||
const notificationBoard = document.querySelector('.notification-board') as HTMLDivElement
|
||||
noNotifications.style.display = 'none'
|
||||
for (const notif of notifications) {
|
||||
for(const notif of notifications) {
|
||||
const notifElement = document.createElement("div");
|
||||
notifElement.className = "notification-element";
|
||||
notifElement.setAttribute('notif-id', notif.id.toString())
|
||||
|
@ -22,6 +22,6 @@
|
||||
"~/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src", "src/**/*", "./vite.config.ts", "src/index.d.ts"],
|
||||
"include": ["src", "src/**/*", "./vite.config.ts", "src/index.d.ts", "src/router.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user