This repository has been archived on 2024-10-16. You can view files and clone it, but cannot push or open issues or pull requests.
ebala/mirzaev/ebala/system/views/pages/entry/administrator.html

321 lines
13 KiB
HTML
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% block css %}
<link type="text/css" rel="stylesheet" href="/css/account.css">
<link type="text/css" rel="stylesheet" href="/css/icons/arrow_right.css">
<link type="text/css" rel="stylesheet" href="/css/icons/nametag.css">
<link type="text/css" rel="stylesheet" href="/css/icons/keyhole.css">
<link type="text/css" rel="stylesheet" href="/css/icons/user_add.css">
{% endblock %}
{% block body %}
<section id="entry" class="panel medium snow">
<section class="header unselectable">
<h1>Идентификация</h1>
</section>
<section class="body">
<iframe name="void" style="display:none"></iframe>
<form id="identification" method="POST" action="/entry" target="void" autocomplete="on" novalidate="true">
<label id="administrator" form="identification" for="_administrator">
<i class="icon nametag"></i>
<input id="_administrator" class="stretched merged right snow borderless" name="administrator" type="text"
placeholder="Идентификатор администратора" list="administrators"
value="{{ session.buffer.entry.administrator._key ?? cookie.buffer_entry_administrator__key }}"
onkeypress="if (event.keyCode === 13) this.nextElementSibling.click()" autocomplete="username"
autofocus="true">
<button type="submit" class="clay merged left" onclick="__administrator(); return false"><i
class="icon arrow right"></i></button>
<datalist id="administrators">
{% for account in accounts %}
<option value="{{ account.getKey() }}">{{ account.getKey() }} {{ account.name.first }} {{ account.name.second
}}</option>
{% endfor %}
</datalist>
</label>
<label id="password" class="hidden" form="identification" for="_password">
<i class="icon keyhole"></i>
<input id="_password" class="stretched merged right snow borderless" name="password" type="password"
placeholder="Пароль" onkeypress="if (event.keyCode === 13) this.nextElementSibling.click()"
autocomplete="current-password">
<button type="submit" class="clay merged left" onclick="__password()"><i class="icon arrow right"></i></button>
</label>
</form>
</section>
</section>
<section id="errors" class="panel medium animation window hidden snow" style="--height: 300px">
<section class="body">
<dl></dl>
</section>
</section>
<script>
// Инициализация функций в глобальной области видимости
let _administrator, __administrator, _password, __password, _errors, balls, trash;
document.addEventListener('damper.initialized', function (e) {
// Инициализирован демпфер
// Защита от вызова на других страницах
if (trash) return;
// Инициализация HTML-элемента с блоком входа в аккаунт
const entry = {wrap: document.getElementById('entry')};
entry.title = entry.wrap.getElementsByTagName('h1')[0];
// Инициализация HTML-элемента с блоком ошибок
const errors = {wrap: document.getElementById('errors')};
errors.list = errors.wrap.getElementsByTagName('dl')[0];
// Инициализация HTML-элементов-оболочек полей ввода
const fields = {
administrator: {label: document.getElementById('administrator')},
password: {label: document.getElementById('password')},
};
fields.administrator.input = fields.administrator.label.getElementsByTagName('input')[0];
fields.password.input = fields.password.label.getElementsByTagName('input')[0];
fields.administrator.button = fields.administrator.label.getElementsByTagName('button')[0];
fields.password.button = fields.password.label.getElementsByTagName('button')[0];
// Инициализация маски идентификатора администратора
fields.administrator.input.mask = IMask(fields.administrator.input, {mask: '000000000000'});
/**
* Отправить входной псевдоним на сервер
*
* @return {void}
*/
_administrator = async () => {
// Деинициализация индикатора и анимации об ошибке
fields.administrator.input.classList.remove('error');
fields.administrator.input.previousElementSibling.classList.remove('error');
// Инициализация функции разблокировки
function unblock() {
// Разблокировка поля ввода
fields.administrator.input.removeAttribute('readonly');
fields.administrator.button.removeAttribute('disabled');
// Инициализация отображения ошибки
fields.administrator.input.classList.add('error');
fields.administrator.input.previousElementSibling.classList.add('error');
// Фокусировка на поле ввода
fields.administrator.input.focus();
}
// Запуск отсрочки разблокировки на случай, если сервер не отвечает
const timeout = setTimeout(() => {_errors(['Сервер не отвечает']); unblock()}, 5000);
// Запрос к серверу
const response = await session.administrator(fields.administrator.input.value);
// Удаление отсрочки разблокировки
clearTimeout(timeout);
if (_errors(response.errors)) {
// Сгенерированы ошибки
// Разблокировка
unblock();
} else {
// Не сгенерированы ошибки (подразумевается их отсутствие)
// Деинициализация интерфейса идентификации
fields.administrator.label.classList.add('hidden');
// Инициализация интерфейса аутентификации
entry.title.innerText = 'Аутентификация';
fields.password.label.classList.remove('hidden');
fields.password.input.focus();
}
};
/**
* Отправить входной псевдоним на сервер с дополнительной подготовкой
*
* @return {void}
*/
__administrator = e.detail.damper(async () => {
// Блокировка поля ввода
fields.administrator.input.setAttribute('readonly', true);
fields.administrator.button.setAttribute('disabled', true);
// Реинициализация блока ошибок
_errors();
// Запуск процесса отправки входного псевдонима
_administrator();
}, 1000);
/**
* Отправить пароль на сервер
*
* @return {void}
*/
_password = async () => {
// Деинициализация индикатора и анимации об ошибке
fields.password.input.classList.remove('error');
fields.password.input.previousElementSibling.classList.remove('error');
// Инициализация функции разблокировки
function unblock() {
// Разблокировка поля ввода
fields.password.input.removeAttribute('readonly');
fields.password.button.removeAttribute('disabled');
// Инициализация отображения ошибки
fields.password.input.classList.add('error');
fields.password.input.previousElementSibling.classList.add('error');
// Фокусировка на поле ввода
fields.password.input.focus();
}
// Запуск отсрочки разблокировки на случай, если сервер не отвечает
const timeout = setTimeout(() => {_errors(['Сервер не отвечает']); unblock()}, 5000);
// Запрос к серверу
const response = await session.password(fields.password.input.value);
// Удаление отсрочки разблокировки
clearTimeout(timeout);
if (_errors(response.errors) || response.verify !== true) {
// Сгенерированы ошибки
// Разблокировка
unblock();
} else {
// Не сгенерированы ошибки (подразумевается их отсутствие)
if (response.account) {
// Инициализирован аккаунт
if (typeof loader === 'function') {
// Initialized the loader class
// Отметить данный HTML-элемент с JS-кодом в очередь на очистку?
trash = true;
// Деинициализация неактуального CSS-документа
document.head.querySelector('link[href="/css/account.css"]').remove();
// Инициализация главной страницы
loader.index();
loader.menu();
}
}
}
};
/**
* Отправить пароль на сервер с дополнительной подготовкой
*
* @return {void}
*/
__password = e.detail.damper(async () => {
// Блокировка поля ввода
fields.password.input.setAttribute('readonly', true);
fields.password.button.setAttribute('disabled', true);
// Реинициализация блока ошибок
_errors();
// Запуск процесса отправки входного псевдонима
_password();
}, 100)
/**
* Сгенерировать HTML-элемент с блоком ошибок
*
* @param {object} registry Реестр ошибок
* @param {bool} reinitialization Реинициализировать?
*
* @return {bool} Сгенерированы ошибки?
*/
_errors = (registry, reinitialization = true) => {
function height() {
// Скрытие HTML-элемента
errors.wrap.style.zIndex = '-99999';
errors.wrap.style.left = '-99999px';
errors.wrap.style.top = '-99999px';
errors.wrap.style.position = 'absolute';
errors.wrap.style.display = 'var(--display, unset)';
errors.wrap.style.opacity = '0';
errors.wrap.style.animationName = 'unset';
// Реинициализация переменной с данными о высоте HTML-элемента
errors.wrap.style.setProperty('--height', errors.wrap.offsetHeight + 'px');
// Отмена скрытия HTML-элемента
errors.wrap.style.zIndex =
errors.wrap.style.left =
errors.wrap.style.top =
errors.wrap.style.position =
errors.wrap.style.display =
errors.wrap.style.opacity =
errors.wrap.style.animationName = null;
}
// Удаление ошибок из прошлой генерации
if (reinitialization) errors.list.innerHTML = null;
for (error in registry) {
// Генерация HTML-элементов с текстами ошибок
// Инициализация HTML-элемента текста ошибки
const samp = document.createElement('samp');
if (typeof registry[error] === 'object') {
// Категория ошибок
// Проверка наличия ошибок
if (registry[error].length === 0) continue;
// Инициализация HTML-элемента-оболочки
const wrap = document.createElement('dt');
// Запись текста категории
samp.innerText = error;
// Запись HTML-элементов в список
wrap.appendChild(samp);
errors.list.appendChild(wrap);
// Реинициализация высоты
height();
// Обработка вложенных ошибок (вход в рекурсию)
_errors(registry[error], false);
} else {
// Текст ошибки (подразумевается)
// Инициализация HTML-элемента
const wrap = document.createElement('dd');
// Запись текста ошибки
samp.innerText = registry[error];
// Запись HTML-элемента в список
wrap.appendChild(samp);
errors.list.appendChild(wrap);
// Реинициализация высоты
height();
}
}
// Реинициализация HTML-элемента с текстом ошибок
if (reinitialization && errors.list.childElementCount === 0) errors.wrap.classList.add('hidden');
else errors.wrap.classList.remove('hidden');
return errors.list.childElementCount === 0 ? false : true;
};
});
</script>
{% endblock %}
{% block js %}
<script type="text/javascript" src="/js/session.js"></script>
<script type="text/javascript" src="/js/loader.js"></script>
<script type="text/javascript" src="/js/imask-7.1.0-alpha.js"></script>
{% endblock %}