forked from hestiacp/hestiacp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhelpers.js
More file actions
113 lines (95 loc) · 3.22 KB
/
helpers.js
File metadata and controls
113 lines (95 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { customAlphabet } from 'nanoid';
// Generates a random password that always passes password requirements
export function randomPassword(length = 16) {
const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const lowercase = 'abcdefghijklmnopqrstuvwxyz';
const numbers = '0123456789';
const symbols = '!@#$%^&*()_+-=[]{}|;:,./<>?';
const allCharacters = uppercase + lowercase + numbers + symbols;
const generate = customAlphabet(allCharacters, length);
let password;
do {
password = generate();
// Must contain at least one uppercase letter, one lowercase letter, and one number
} while (!(/[a-z]/.test(password) && /[A-Z]/.test(password) && /\d/.test(password)));
return password;
}
// Debounces a function to avoid excessive calls
export function debounce(func, wait = 100) {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
// Returns the value of a CSS variable
export function getCssVariable(variableName) {
return getComputedStyle(document.documentElement).getPropertyValue(variableName).trim();
}
// Shows the loading spinner overlay
export function showSpinner() {
document.querySelector('.js-spinner').classList.add('active');
}
// Creates a confirmation <dialog> on the fly
export function createConfirmationDialog({
title,
message = 'Are you sure?',
targetUrl,
spinner = false,
}) {
// Create the dialog
const dialog = document.createElement('dialog');
dialog.classList.add('modal');
// Create and insert the title
if (title) {
const titleElement = document.createElement('h2');
titleElement.innerHTML = title;
titleElement.classList.add('modal-title');
dialog.append(titleElement);
}
// Create and insert the message
const messageElement = document.createElement('p');
messageElement.innerHTML = message;
messageElement.classList.add('modal-message');
dialog.append(messageElement);
// Create and insert the options
const optionsElement = document.createElement('div');
optionsElement.classList.add('modal-options');
const confirmButton = document.createElement('button');
confirmButton.type = 'submit';
confirmButton.classList.add('button');
confirmButton.textContent = 'OK';
optionsElement.append(confirmButton);
const cancelButton = document.createElement('button');
cancelButton.type = 'button';
cancelButton.classList.add('button', 'button-secondary', 'u-ml5');
cancelButton.textContent = 'Cancel';
if (targetUrl) {
optionsElement.append(cancelButton);
}
dialog.append(optionsElement);
// Define named functions to handle the event listeners
const handleConfirm = () => {
if (targetUrl) {
if (spinner) {
showSpinner();
}
window.location.href = targetUrl;
}
handleClose();
};
const handleCancel = () => handleClose();
const handleClose = () => {
confirmButton.removeEventListener('click', handleConfirm);
cancelButton.removeEventListener('click', handleCancel);
dialog.removeEventListener('close', handleClose);
dialog.remove();
};
// Add event listeners
confirmButton.addEventListener('click', handleConfirm);
cancelButton.addEventListener('click', handleCancel);
dialog.addEventListener('close', handleClose);
// Add to DOM and show
document.body.append(dialog);
dialog.showModal();
}