Removed old frontend code

This commit is contained in:
Jan Böhmer 2022-08-03 22:54:46 +02:00
parent efb38173e6
commit 750bdc45d1
3 changed files with 1 additions and 1017 deletions

View file

@ -17,15 +17,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*
* Welcome to your app's main JavaScript file!
*
* We recommend including the built version of this JavaScript file
* (and its CSS file) in your base layout (base.html.twig).
*/
// any CSS you require will output into a single css file (app.css in this case)
// Main CSS files
import '../css/app.css';
@ -46,57 +37,4 @@ import "./register_events";
import "./tristate_checkboxes";
//Define jquery globally
window.$ = window.jQuery = require("jquery")
/**
require('bootstrap-select');
require('jquery-form');
require('corejs-typeahead/dist/typeahead.bundle.min');
window.Bloodhound = require('corejs-typeahead/dist/bloodhound.js');
;
require('bootstrap-fileinput');
require('./datatables.js');
window.bootbox = require('bootbox');
require("marked");
window.DOMPurify = require("dompurify");
// Includes required for tag input
require('./tagsinput.js');
require('../css/tagsinput.css');
//Tristate checkbox support
require('./jquery.tristate.js');
require('darkmode-js');
//Equation rendering
require('katex');
window.renderMathInElement = require('katex/contrib/auto-render/auto-render').default;
import 'katex/dist/katex.css';
window.ClipboardJS = require('clipboard');
require('../ts_src/ajax_ui');
//import {ajaxUI} from "../ts_src/ajax_ui";
//window.ajaxUI = ajaxUI;
//Require all events;
require('../ts_src/event_listeners');
//Start AjaxUI AFTER all event has been registered
//$(document).ready(ajaxUI.start());
*/
//console.log('Hello Webpack Encore! Edit me in assets/js/app.js');
window.$ = window.jQuery = require("jquery")

View file

@ -1,605 +0,0 @@
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Extract the title (The name between the <title> tags) of a HTML snippet.
* @param {string} html The HTML code which should be searched.
* @returns {string} The title extracted from the html.
*/
function extractTitle(html : string) : string {
let title : string = "";
let regex = /<title>(.*?)<\/title>/gi;
if (regex.test(html)) {
let matches = html.match(regex);
for(let match in matches) {
title = $(matches[match]).text();
}
}
return title;
}
class AjaxUI {
protected BASE = "/";
private trees_filled : boolean = false;
private statePopped : boolean = false;
public xhr : XMLHttpRequest;
public constructor()
{
//Make back in the browser go back in history
window.onpopstate = this.onPopState;
$(document).ajaxError(this.onAjaxError.bind(this));
//$(document).ajaxComplete(this.onAjaxComplete.bind(this));
}
/**
* Starts the ajax ui und execute handlers registered in addStartAction().
* Should be called in a document.ready, after handlers are set.
*/
public start(disabled : boolean = false)
{
if(disabled) {
return;
}
console.info("AjaxUI started!");
this.BASE = $("body").data("base-url");
//If path doesn't end with slash, add it.
if(this.BASE[this.BASE.length - 1] !== '/') {
this.BASE = this.BASE + '/';
}
console.info("Base path is " + this.BASE);
//Show flash messages
$(".toast").toast('show');
/**
* Save the XMLHttpRequest that jQuery used, to the class, so we can acess the responseURL property.
* This is a work-around as long jQuery does not implement this property in its jQXHR objects.
*/
//@ts-ignore
jQuery.ajaxSettings.xhr = function () {
//@ts-ignore
let xhr = new window.XMLHttpRequest();
//Save the XMLHttpRequest to the class.
ajaxUI.xhr = xhr;
return xhr;
};
this.registerLinks();
this.registerForm();
this.fillTrees();
this.initDataTables();
//Trigger start event
$(document).trigger("ajaxUI:start");
}
/**
* Fill the trees with the given data.
*/
public fillTrees()
{
let categories = localStorage.getItem("tree_datasource_tree-categories");
let devices = localStorage.getItem("tree_datasource_tree-devices");
let tools = localStorage.getItem("tree_datasource_tree-tools");
if(categories == null) {
categories = "categories";
}
if(devices == null) {
devices = "devices";
}
if(tools == null) {
tools = "tools";
}
this.treeLoadDataSource("tree-categories", categories);
this.treeLoadDataSource("tree-devices", devices);
this.treeLoadDataSource("tree-tools", tools);
this.trees_filled = true;
//Register tree btns to expand all, or to switch datasource.
$(".tree-btns").click(function (event) {
event.preventDefault();
$(this).parents("div.dropdown").removeClass('show');
//$(this).closest(".dropdown-menu").removeClass('show');
$(".dropdown-menu.show").removeClass("show");
let mode = $(this).data("mode");
let target = $(this).data("target");
let text = $(this).text() + " \n<span class='caret'></span>"; //Add caret or it will be removed, when written into title
if (mode==="collapse") {
// @ts-ignore
$('#' + target).treeview('collapseAll', { silent: true });
}
else if(mode==="expand") {
// @ts-ignore
$('#' + target).treeview('expandAll', { silent: true });
} else {
localStorage.setItem("tree_datasource_" + target, mode);
ajaxUI.treeLoadDataSource(target, mode);
}
return false;
});
}
/**
* Load the given url into the tree with the given id.
* @param target_id
* @param datasource
*/
protected treeLoadDataSource(target_id, datasource) {
let text : string = $(".tree-btns[data-mode='" + datasource + "']").html();
text = text + " \n<span class='caret'></span>"; //Add caret or it will be removed, when written into title
switch(datasource) {
case "categories":
ajaxUI.initTree("#" + target_id, 'tree/categories');
break;
case "locations":
ajaxUI.initTree("#" + target_id, 'tree/locations');
break;
case "footprints":
ajaxUI.initTree("#" + target_id, 'tree/footprints');
break;
case "manufacturers":
ajaxUI.initTree("#" + target_id, 'tree/manufacturers');
break;
case "suppliers":
ajaxUI.initTree("#" + target_id, 'tree/suppliers');
break;
case "tools":
ajaxUI.initTree("#" + target_id, 'tree/tools');
break;
case "devices":
ajaxUI.initTree("#" + target_id, 'tree/devices');
ajaxUI.initTree("#" + target_id, 'tree/devices');
break;
}
$( "#" + target_id + "-title").html(text);
}
/**
* Fill a treeview with data from the given url.
* @param tree The Jquery selector for the tree (e.g. "#tree-tools")
* @param url The url from where the data should be loaded
*/
public initTree(tree, url) {
//let contextmenu_handler = this.onNodeContextmenu;
$.getJSON(ajaxUI.BASE + url, function (data) {
// @ts-ignore
$(tree).treeview({
data: data,
enableLinks: false,
showIcon: false,
showBorder: true,
searchResultBackColor: '#ffc107',
searchResultColor: '#000',
onNodeSelected: function(event, data) {
if(data.href) {
ajaxUI.navigateTo(data.href);
}
},
//onNodeContextmenu: contextmenu_handler,
expandIcon: "fas fa-plus fa-fw fa-treeview", collapseIcon: "fas fa-minus fa-fw fa-treeview"})
.on('initialized', function() {
$(this).treeview('collapseAll', { silent: true });
//Implement searching if needed.
if($(this).data('treeSearch')) {
let _this = this;
let $search = $($(this).data('treeSearch'));
$search.on( 'input', function() {
$(_this).treeview('collapseAll', { silent: true });
$(_this).treeview('search', [$search.val()]);
});
}
});
});
}
/**
* Register all links, for loading via ajax.
*/
public registerLinks()
{
// Unbind all old handlers, so the things are not executed multiple times.
$('a').not(".link-external, [data-no-ajax], .page-link, [href^='javascript'], [href^='#']").unbind('click').click(function (event) {
let a = $(this);
let href = $.trim(a.attr("href"));
//Ignore links without href attr and nav links ('they only have a #)
if(href != null && href != "" && href.charAt(0) !== '#') {
event.preventDefault();
ajaxUI.navigateTo(href);
}
}
);
console.debug('Links registered!');
}
protected getFormOptions() : JQueryFormOptions
{
return {
success: this.onAjaxComplete,
beforeSerialize: function($form, options) : boolean {
//Update the content of textarea fields using CKEDITOR before submitting.
//@ts-ignore
if(typeof CKEDITOR !== 'undefined') {
//@ts-ignore
for (let name in CKEDITOR.instances) {
//@ts-ignore
CKEDITOR.instances[name].updateElement();
}
}
//Check every checkbox field, so that it will be submitted (only valid fields are submitted)
$form.find("input[type=checkbox].tristate").prop('checked', true);
return true;
},
beforeSubmit: function (arr, $form, options) : boolean {
//When data-with-progbar is specified, then show progressbar.
if($form.data("with-progbar") != undefined) {
ajaxUI.showProgressBar();
}
return true;
}
};
}
/**
* Register all forms for loading via ajax.
*/
public registerForm()
{
let options = this.getFormOptions();
$('form').not('[data-no-ajax]').ajaxForm(options);
console.debug('Forms registered!');
}
/**
* Submits the given form via ajax.
* @param form The form that will be submmitted.
* @param btn The btn via which the form is submitted
*/
public submitForm(form, btn = null)
{
let options = ajaxUI.getFormOptions();
if(btn) {
options.data = {};
options.data[$(btn).attr('name')] = $(btn).attr('value');
}
$(form).ajaxSubmit(options);
}
/**
* Show the progressbar
*/
public showProgressBar()
{
//Blur content background
$('#content').addClass('loading-content');
// @ts-ignore
$('#progressModal').modal({
keyboard: false,
backdrop: false,
show: true
});
}
/**
* Hides the progressbar.
*/
public hideProgressBar()
{
// @ts-ignore
$('#progressModal').modal('hide');
//Remove the remaining things of the modal
$('.modal-backdrop').remove();
$('body').removeClass('modal-open');
$('body, .navbar').css('padding-right', "");
}
/**
* Navigates to the given URL
* @param url The url which should be opened.
* @param show_loading Show the loading bar during loading.
*/
public navigateTo(url : string, show_loading : boolean = true)
{
if(show_loading) {
this.showProgressBar();
}
$.ajax(url, {
success: this.onAjaxComplete
});
//$.ajax(url).promise().done(this.onAjaxComplete);
}
/**
* Called when an error occurs on loading ajax. Outputs the message to the console.
*/
private onAjaxError (event, request, settings) {
'use strict';
//Ignore aborted requests.
if (request.statusText =='abort' || request.status == 0) {
return;
}
//Ignore ajax errors with 200 code (like the ones during 2FA authentication)
if(request.status == 200) {
return;
}
console.error("Error getting the ajax data from server!");
console.log(event);
console.log(request);
console.log(settings);
ajaxUI.hideProgressBar();
//Create error text
let title = request.statusText;
switch(request.status) {
case 500:
title = 'Internal Server Error!';
break;
case 404:
title = "Site not found!";
break;
case 403:
title = "Permission denied!";
break;
}
var alert = bootbox.alert(
{
size: 'large',
message: function() {
let msg = "Error getting data from Server! <b>Status Code: " + request.status + "</b>";
msg += '<br><br><a class=\"btn btn-link\" data-toggle=\"collapse\" href=\"#iframe_div\" >' + 'Show response' + "</a>";
msg += "<div class=\" collapse\" id='iframe_div'><iframe height='512' width='100%' id='iframe'></iframe></div>";
return msg;
},
title: title,
callback: function () {
//Remove blur
$('#content').removeClass('loading-content');
}
});
//@ts-ignore
alert.init(function (){
var dstFrame = document.getElementById('iframe');
//@ts-ignore
var dstDoc = dstFrame.contentDocument || dstFrame.contentWindow.document;
dstDoc.write(request.responseText);
dstDoc.close();
});
//If it was a server error and response is not empty, show it to user.
if(request.status == 500 && request.responseText !== "")
{
console.log("Response:" + request.responseText);
}
}
/**
* This function gets called every time, the "back" button in the browser is pressed.
* We use it to load the content from history stack via ajax and to rewrite url, so we only have
* to load #content-data
* @param event
*/
private onPopState(event)
{
let page : string = location.href;
ajaxUI.statePopped = true;
ajaxUI.navigateTo(page);
}
/**
* This function takes the response of an ajax requests, and does the things we need to do for our AjaxUI.
* This includes inserting the content and pushing history.
* @param responseText
* @param textStatus
* @param jqXHR
*/
private onAjaxComplete(responseText: string, textStatus: string, jqXHR: any)
{
console.debug("Ajax load completed!");
ajaxUI.hideProgressBar();
/* We need to do the url checking before the parseHTML, so that we dont get wrong url name, caused by scripts
in the new content */
// @ts-ignore
let url = this.url;
//Check if we were redirect to a new url, then we should use that as new url.
if(ajaxUI.xhr.responseURL) {
url = ajaxUI.xhr.responseURL;
}
//Parse response to DOM structure
//We need to preserve javascript, so the table ca
let dom = $.parseHTML(responseText, document, true);
//And replace the content container
$("#content").replaceWith($("#content", dom));
//Replace login menu too (so everything is up to date)
$("#login-content").replaceWith($('#login-content', dom));
//Replace flash messages and show them
$("#message-container").replaceWith($('#message-container', dom));
$(".toast").toast('show');
//Set new title
let title = extractTitle(responseText);
document.title = title;
//Push to history, if we currently arent poping an old value.
if(!ajaxUI.statePopped) {
history.pushState(null, title, url);
} else {
//Clear pop state
ajaxUI.statePopped = false;
}
//Do things on the new dom
ajaxUI.registerLinks();
ajaxUI.registerForm();
ajaxUI.initDataTables();
//Trigger reload event
$(document).trigger("ajaxUI:reload");
}
/**
* Init all datatables marked with data-datatable based on their data-settings attribute.
*/
protected initDataTables()
{
//@ts-ignore
$($.fn.DataTable.tables()).DataTable().fixedHeader.disable();
//@ts-ignore
$($.fn.DataTable.tables()).DataTable().destroy();
//Find all datatables and init it.
let $tables = $('[data-datatable]');
$.each($tables, function(index, table) {
let $table = $(table);
let settings = $table.data('settings');
//@ts-ignore
var promise = $('#part_list').initDataTables(settings,
{
colReorder: true,
responsive: true,
"fixedHeader": { header: $(window).width() >= 768, //Only enable fixedHeaders on devices with big screen. Fixes scrolling issues on smartphones.
headerOffset: $("#navbar").height()},
"buttons": [ {
"extend": 'colvis',
'className': 'mr-2 btn-light',
"text": "<i class='fa fa-cog'></i>"
}],
"select": $table.data('select') ?? false,
"rowCallback": function( row, data, index ) {
//Check if we have a level, then change color of this row
if (data.level) {
let style = "";
switch(data.level) {
case "emergency":
case "alert":
case "critical":
case "error":
style = "table-danger";
break;
case "warning":
style = "table-warning";
break;
case "notice":
style = "table-info";
break;
}
if (style){
$(row).addClass(style);
}
}
}
});
//Register links.
promise.then(function() {
ajaxUI.registerLinks();
//Set the correct title in the table.
let title = $('#part-card-header-src');
$('#part-card-header').html(title.html());
$(document).trigger('ajaxUI:dt_loaded');
if($table.data('part_table')) {
//@ts-ignore
$('#dt').on( 'select.dt deselect.dt', function ( e, dt, items ) {
let selected_elements = dt.rows({selected: true});
let count = selected_elements.count();
if(count > 0) {
$('#select_panel').removeClass('d-none');
} else {
$('#select_panel').addClass('d-none');
}
$('#select_count').text(count);
let selected_ids_string = selected_elements.data().map(function(value, index) {
return value['id']; }
).join(",");
$('#select_ids').val(selected_ids_string);
} );
}
//Attach event listener to update links after new page selection:
$('#dt').on('draw.dt column-visibility.dt', function() {
ajaxUI.registerLinks();
$(document).trigger('ajaxUI:dt_loaded');
});
});
});
console.debug('Datatables inited.');
}
}
export let ajaxUI = new AjaxUI();

View file

@ -1,349 +0,0 @@
/*
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {ajaxUI} from "./ajax_ui";
import "bootbox";
import "marked";
import * as marked from "marked";
import {parse} from "marked";
import * as ZXing from "@zxing/library";
/************************************
*
* In this file all the functions that has to be called using AjaxUIoperation are registered.
* You can use AjaxUI:start and AjaxUI:reload events.
*
***********************************/
// Add bootstrap treeview on divs with data-tree-data attribute
$(document).on("ajaxUI:start ajaxUI:reload", function() {
$("[data-tree-data]").each(function(index, element) {
let data = $(element).data('treeData');
//@ts-ignore
$(element).treeview({
data: data,
enableLinks: false,
showIcon: false,
showBorder: true,
searchResultBackColor: '#ffc107',
searchResultColor: '#000',
showTags: true,
//@ts-ignore
wrapNode: true,
//@ts-ignore
tagsClass: 'badge badge-secondary badge-pill pull-right',
expandIcon: "fas fa-plus fa-fw fa-treeview", collapseIcon: "fas fa-minus fa-fw fa-treeview",
onNodeSelected: function(event, data) {
if(data.href) {
ajaxUI.navigateTo(data.href);
}
}
}).on('initialized', function() {
$(this).treeview('collapseAll', { silent: true });
let selected = $(this).treeview('getSelected');
$(this).treeview('revealNode', [ selected, {silent: true } ]);
//Implement searching if needed.
if($(this).data('treeSearch')) {
let _this = this;
let $search = $($(this).data('treeSearch'));
$search.on( 'input', function() {
$(_this).treeview('collapseAll', { silent: true });
$(_this).treeview('search', [$search.val()]);
});
}
//Add tree expand and reduce buttons if needed.
if($(this).data('treeReduce')) {
let _this = this;
let $btn = $($(this).data('treeReduce'));
$btn.click(function () {
$(_this).treeview('collapseAll');
});
}
if($(this).data('treeExpand')) {
let _this = this;
let $btn = $($(this).data('treeExpand'));
$btn.click(function () {
$(_this).treeview('expandAll');
});
}
});
});
});
$(document).on("ajaxUI:start ajaxUI:reload", function() {
$("[data-delete-form]").unbind('submit').submit(function (event) {
event.preventDefault();
let form = this;
//Get the submit button
let btn = document.activeElement;
let title = $(this).data("title");
let message = $(this).data("message");
bootbox.confirm({
message: message, title: title, callback: function (result) {
//If the dialog was confirmed, then submit the form.
if (result) {
ajaxUI.submitForm(form, btn);
}
}
});
return false;
});
//Register for forms with delete-buttons
$("[data-delete-btn]").parents('form').unbind('submit').submit(function (event) {
event.preventDefault();
let form = this;
//Get the submit button
let btn = document.activeElement;
let title = $(btn).data("title");
let message = $(btn).data("message");
//If not the button with the message was pressed, then simply submit the form.
if(!btn.hasAttribute('data-delete-btn')) {
ajaxUI.submitForm(form, btn);
}
bootbox.confirm({
message: message, title: title, callback: function (result) {
//If the dialog was confirmed, then submit the form.
if (result) {
ajaxUI.submitForm(form, btn);
}
}
});
});
});
$(document).on("ajaxUI:start ajaxUI:reload", function() {
//@ts-ignore
$(".tristate").tristate( {
checked: "true",
unchecked: "false",
indeterminate: "indeterminate",
});
$('.permission_multicheckbox:checkbox').change(function() {
//Find the other checkboxes in this row, and change their value
var $row = $(this).parents('tr');
//@ts-ignore
var new_state = $(this).tristate('state');
//@ts-ignore
$('.tristate:checkbox', $row).tristate('state', new_state);
});
});
//Re initialize fileinputs on reload
$(document).on("ajaxUI:reload", function () {
//@ts-ignore
$(".file").fileinput();
});
/**
* This listener keeps track of which tab is currently selected (using hash and localstorage) and will try to open
* that tab on reload. That means that if the user changes something, he does not have to switch back to the tab
* where he was before submit.
*/
$(document).on("ajaxUI:reload ajaxUI:start", function () {
//Determine which tab should be shown (use hash if specified, otherwise use localstorage)
var $activeTab = null;
if (location.hash) {
$activeTab = $('a[href=\'' + location.hash + '\']');
} else if(localStorage.getItem('activeTab')) {
$activeTab = $('a[href="' + localStorage.getItem('activeTab') + '"]');
}
if($activeTab) {
//Findout if the tab has any parent tab we have to show before
var parents = $($activeTab).parents('.tab-pane');
parents.each(function(n) {
$('a[href="#' + $(this).attr('id') + '"]').tab('show');
});
//Finally show the active tab itself
$activeTab.tab('show');
}
$('body').on('click', 'a[data-toggle=\'tab\']', function (e) {
e.preventDefault()
var tab_name = this.getAttribute('href')
if (history.replaceState) {
history.replaceState(null, null, tab_name)
}
else {
location.hash = tab_name
}
localStorage.setItem('activeTab', tab_name)
$(this).tab('show');
return false;
});
});
/**
* Load the higher resolution version of hover pictures.
*/
$(document).on("ajaxUI:reload ajaxUI:start ajaxUI:dt_loaded", function () {
$('.hoverpic[data-thumbnail]').popover({
html: true,
trigger: 'hover',
placement: 'right',
container: 'body',
content: function () {
return '<img class="img-fluid" src="' + $(this).data('thumbnail') + '" />';
}
});
});
//Register typeaheads
$(document).on("ajaxUI:reload ajaxUI:start attachment:create", function () {
$('input[data-autocomplete]').each(function() {
//@ts-ignore
var engine = new Bloodhound({
//@ts-ignore
datumTokenizer: Bloodhound.tokenizers.obj.whitespace(''),
//@ts-ignore
queryTokenizer: Bloodhound.tokenizers.obj.whitespace(''),
remote: {
url: $(this).data('autocomplete'),
wildcard: 'QUERY'
}
});
//@ts-ignore
$(this).typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'states',
source: engine,
limit: 250,
templates: {
suggestion: function(data) {
if (typeof data === "string") {
return "<div>" + data + "</div>";
} else if(typeof data === "object" && typeof data.image === "string") {
return "<div class='row m-0'><div class='col-2 pl-0 pr-1'><img class='typeahead-image' src='" + data.image + "'/></div><div class='col-10'>" + data.name + "</div></div>"
}
},
},
display: 'name',
});
//Make the typeahead input fill the container (remove block-inline attr)
$(this).parent(".twitter-typeahead").css('display', 'block');
})
});
$(document).on("ajaxUI:start ajaxUI:reload attachment:create", function() {
let updater = function() {
//@ts-ignore
let selected_option = $(this)[0].selectedOptions[0];
let filter_string = $(selected_option).data('filetype_filter');
//Find associated file input
let $row = $(this).parents('tr');
//Set accept filter
$('input[type="file"]', $row).prop('accept', filter_string);
};
//Register a change handler on all change listeners, and update it when the events are triggered
$('select.attachment_type_selector').change(updater).each(updater);
});
$(document).on("ajaxUI:start ajaxUI:reload", function() {
function setTooltip(btn, message) {
$(btn).tooltip('hide')
.attr('data-original-title', message)
.tooltip('show');
}
function hideTooltip(btn) {
setTimeout(function() {
$(btn).tooltip('hide');
}, 1000);
}
//@ts-ignore
var clipboard = new ClipboardJS('.btn[data-clipboard-target], .btn[data-clipboard-text], .btn[data-clipboard-action]');
clipboard.on('success', function(e) {
setTooltip(e.trigger, 'Copied!');
hideTooltip(e.trigger);
});
clipboard.on('error', function(e) {
setTooltip(e.trigger, 'Failed!');
hideTooltip(e.trigger);
});
});
//Register U2F on page reload too...
$(document).on("ajaxUI:reload", function() {
//@ts-ignore
window.u2fauth.ready(function () {
const form = document.getElementById('u2fForm')
if (!form) {
return
}
const type = form.dataset.action
if (type === 'auth') {
//@ts-ignore
u2fauth.authenticate()
} else if (type === 'reg' && form.addEventListener) {
form.addEventListener('submit', function (event) {
event.preventDefault()
//@ts-ignore
u2fauth.register()
}, false)
}
})
});
//Need for proper body padding, with every navbar height
$(window).resize(function () {
let height : number = $('#navbar').height() + 10;
$('body').css('padding-top', height);
$('#fixed-sidebar').css('top', height);
});
$(window).on('load', function () {
let height : number = $('#navbar').height() + 10;
$('body').css('padding-top', height);
$('#fixed-sidebar').css('top', height);
});