2021-04-13 21:51:12 -07:00
|
|
|
import { Modal, Tooltip } from 'bootstrap';
|
2021-03-13 02:31:57 -07:00
|
|
|
import Masonry from 'masonry-layout';
|
|
|
|
import { initApiSelect, initStaticSelect, initColorSelect } from './select';
|
|
|
|
import { initDateSelector } from './dateSelector';
|
|
|
|
import { initMessageToasts } from './toast';
|
|
|
|
import { initSpeedSelector, initForms } from './forms';
|
2021-03-19 09:25:27 -07:00
|
|
|
import { initRackElevation } from './buttons';
|
2021-04-13 21:51:12 -07:00
|
|
|
import { initClipboard } from './clipboard';
|
2021-04-17 18:16:13 -07:00
|
|
|
import { initSearchBar, initInterfaceFilter } from './search';
|
2021-04-17 17:18:13 -07:00
|
|
|
import { initGenerateKeyPair, initLockUnlock, initGetSessionKey } from './secrets';
|
2021-04-19 16:59:56 -07:00
|
|
|
import { initTableConfig } from './tableConfig';
|
2021-03-13 13:51:51 -07:00
|
|
|
import { getElements } from './util';
|
2021-03-13 02:31:57 -07:00
|
|
|
|
|
|
|
const INITIALIZERS = [
|
|
|
|
initSearchBar,
|
|
|
|
initMasonry,
|
|
|
|
bindReslug,
|
|
|
|
initApiSelect,
|
|
|
|
initStaticSelect,
|
|
|
|
initDateSelector,
|
|
|
|
initSpeedSelector,
|
|
|
|
initColorSelect,
|
2021-03-19 09:25:27 -07:00
|
|
|
initRackElevation,
|
2021-04-13 21:51:12 -07:00
|
|
|
initClipboard,
|
2021-04-17 17:18:13 -07:00
|
|
|
initGenerateKeyPair,
|
|
|
|
initLockUnlock,
|
|
|
|
initGetSessionKey,
|
2021-04-17 18:16:13 -07:00
|
|
|
initInterfaceFilter,
|
2021-04-19 16:59:56 -07:00
|
|
|
initTableConfig,
|
2021-03-13 02:31:57 -07:00
|
|
|
] as (() => void)[];
|
|
|
|
|
|
|
|
/**
|
2021-03-13 13:51:51 -07:00
|
|
|
* Enable any defined Bootstrap Tooltips.
|
|
|
|
*
|
|
|
|
* @see https://getbootstrap.com/docs/5.0/components/tooltips
|
2021-03-13 02:31:57 -07:00
|
|
|
*/
|
|
|
|
function initBootstrap(): void {
|
|
|
|
if (document !== null) {
|
2021-03-13 13:51:51 -07:00
|
|
|
for (const tooltip of getElements('[data-bs-toggle="tooltip"]')) {
|
2021-03-13 02:31:57 -07:00
|
|
|
new Tooltip(tooltip, { container: 'body', boundary: 'window' });
|
|
|
|
}
|
2021-04-13 21:51:12 -07:00
|
|
|
for (const modal of getElements('[data-bs-toggle="modal"]')) {
|
|
|
|
new Modal(modal);
|
|
|
|
}
|
2021-03-13 02:31:57 -07:00
|
|
|
initMessageToasts();
|
|
|
|
initForms();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-13 13:51:51 -07:00
|
|
|
/**
|
|
|
|
* Initialize masonry-layout for homepage (or any other masonry layout cards).
|
|
|
|
*/
|
|
|
|
function initMasonry(): void {
|
2021-03-13 02:31:57 -07:00
|
|
|
if (document !== null) {
|
2021-03-13 13:51:51 -07:00
|
|
|
for (const grid of getElements('.masonry')) {
|
2021-03-13 02:31:57 -07:00
|
|
|
new Masonry(grid, {
|
|
|
|
itemSelector: '.masonry-item',
|
|
|
|
percentPosition: true,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a slug from any input string.
|
2021-03-13 13:51:51 -07:00
|
|
|
*
|
2021-03-13 02:31:57 -07:00
|
|
|
* @param slug Original string.
|
|
|
|
* @param chars Maximum number of characters.
|
|
|
|
* @returns Slugified string.
|
|
|
|
*/
|
|
|
|
function slugify(slug: string, chars: number): string {
|
|
|
|
return slug
|
|
|
|
.replace(/[^\-\.\w\s]/g, '') // Remove unneeded chars
|
|
|
|
.replace(/^[\s\.]+|[\s\.]+$/g, '') // Trim leading/trailing spaces
|
|
|
|
.replace(/[\-\.\s]+/g, '-') // Convert spaces and decimals to hyphens
|
|
|
|
.toLowerCase() // Convert to lowercase
|
|
|
|
.substring(0, chars); // Trim to first chars chars
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If a slug field exists, add event listeners to handle automatically generating its value.
|
|
|
|
*/
|
|
|
|
function bindReslug(): void {
|
|
|
|
const slugField = document.getElementById('id_slug') as HTMLInputElement;
|
|
|
|
const slugButton = document.getElementById('reslug') as HTMLButtonElement;
|
|
|
|
if (slugField === null || slugButton === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const sourceId = slugField.getAttribute('slug-source');
|
|
|
|
const sourceField = document.getElementById(`id_${sourceId}`) as HTMLInputElement;
|
|
|
|
|
|
|
|
if (sourceField === null) {
|
|
|
|
console.error('Unable to find field for slug field.');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const slugLengthAttr = slugField.getAttribute('maxlength');
|
|
|
|
let slugLength = 50;
|
|
|
|
|
|
|
|
if (slugLengthAttr) {
|
|
|
|
slugLength = Number(slugLengthAttr);
|
|
|
|
}
|
|
|
|
sourceField.addEventListener('blur', () => {
|
|
|
|
slugField.value = slugify(sourceField.value, slugLength);
|
|
|
|
});
|
|
|
|
slugButton.addEventListener('click', () => {
|
|
|
|
slugField.value = slugify(sourceField.value, slugLength);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (document.readyState !== 'loading') {
|
|
|
|
initBootstrap();
|
|
|
|
} else {
|
|
|
|
document.addEventListener('DOMContentLoaded', initBootstrap);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const init of INITIALIZERS) {
|
|
|
|
init();
|
|
|
|
}
|