страницы список да вообще дохера всего в общем
This commit is contained in:
parent
fd27d88b6c
commit
525d71dfe4
|
@ -0,0 +1,153 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace mirzaev\ebala\controllers;
|
||||||
|
|
||||||
|
// Файлы проекта
|
||||||
|
use mirzaev\ebala\controllers\core,
|
||||||
|
mirzaev\ebala\controllers\traits\errors,
|
||||||
|
mirzaev\ebala\models\registry;
|
||||||
|
|
||||||
|
// Библиотека для ArangoDB
|
||||||
|
use ArangoDBClient\Document as _document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Контроллер администратора
|
||||||
|
*
|
||||||
|
* @package mirzaev\ebala\controllers
|
||||||
|
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||||
|
*/
|
||||||
|
final class administrator extends core
|
||||||
|
{
|
||||||
|
use errors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Главная страница
|
||||||
|
*
|
||||||
|
* @param array $parameters Параметры запроса
|
||||||
|
*/
|
||||||
|
public function index(array $parameters = []): ?string
|
||||||
|
{
|
||||||
|
// Авторизация
|
||||||
|
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'administrator')) {
|
||||||
|
// Авторизован аккаунт оператора или администратора
|
||||||
|
|
||||||
|
foreach (['confirmed', 'waiting', 'published', 'unpublished', 'problematic', 'hided', 'completed'] as $name) {
|
||||||
|
// Перебор фильтров статусов
|
||||||
|
|
||||||
|
// Инициализация значения (приоритет у cookie)
|
||||||
|
$value = $_COOKIE["administrators_filter_$name"] ?? $this->session->buffer[$_SERVER['INTERFACE']]['administrators']['filters'][$name] ?? 0;
|
||||||
|
|
||||||
|
// Инициализировано значение?
|
||||||
|
if ($value === null || $value === 0) continue;
|
||||||
|
|
||||||
|
// Генерация класса для HTML-элемента по его состоянию (0 - ОТСУТСТВУЕТ, 1 - И, 2 - ИЛИ)
|
||||||
|
$this->view->{$name} = match ($value) {
|
||||||
|
'0', 0 => 'earth',
|
||||||
|
'1', 1 => 'sand',
|
||||||
|
'2', 2 => 'river',
|
||||||
|
default => 'earth'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Генерация представлениямя
|
||||||
|
$main = $this->view->render(DIRECTORY_SEPARATOR . 'pages' . DIRECTORY_SEPARATOR . 'administrators.html');
|
||||||
|
} else $main = $this->authorization();
|
||||||
|
|
||||||
|
// Возврат (успех)
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') return $this->view->render(DIRECTORY_SEPARATOR . 'index.html', ['main' => $main]);
|
||||||
|
else if ($_SERVER['REQUEST_METHOD'] === 'POST') return $main;
|
||||||
|
|
||||||
|
// Возврат (провал)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Прочитать
|
||||||
|
*
|
||||||
|
* @param array $parameters Параметры запроса
|
||||||
|
*/
|
||||||
|
public function read(array $parameters = []): ?string
|
||||||
|
{
|
||||||
|
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'administrator')) {
|
||||||
|
// Авторизован аккаунт оператора или администратора
|
||||||
|
|
||||||
|
// Реинициализация актуальной страницы
|
||||||
|
if (isset($parameters['page'])) $this->session->write(['administrators' => ['page' => $parameters['page']]]);
|
||||||
|
else if (empty($this->session->buffer[$_SERVER['INTERFACE']]['administrators']['page'])) $this->session->write(['administrators' => ['page' => 1]]);
|
||||||
|
|
||||||
|
// Инициализация буфера AQL-выражения для инъекции фильтра по интервалу
|
||||||
|
$polysemantic = '';
|
||||||
|
|
||||||
|
// Инициализация допустимых статусов
|
||||||
|
$statuses = ['active', 'inactive', 'fined', 'decent', 'hided', 'fired'];
|
||||||
|
|
||||||
|
// Инициализация буфера AQL-выражения для инъекции фильтра по статусам (И)
|
||||||
|
$statuses_and = '';
|
||||||
|
|
||||||
|
foreach ($statuses as $name) {
|
||||||
|
// Перебор фильтров статусов (И)
|
||||||
|
|
||||||
|
// Инициализация значения (приоритет у cookie) (отсутствие значения или значение 0 вызывают continue)
|
||||||
|
if (empty($value = $_COOKIE["administrators_filter_$name"] ?? $this->session->buffer[$_SERVER['INTERFACE']]['administrators']['filters'][$name] ?? 0)) continue;
|
||||||
|
|
||||||
|
// Генерация AQL-выражения для инъекции в строку запроса
|
||||||
|
if ($value === '1') $statuses_and .= " && administrator.$name == true";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Очистка от бинарных операторов сравнения с только одним операндом (крайние)
|
||||||
|
$statuses_and = trim(trim(trim($statuses_and), '&&'));
|
||||||
|
|
||||||
|
// Инициализация буфера AQL-выражения для инъекции фильтра по статусам (ИЛИ)
|
||||||
|
$statuses_or = '';
|
||||||
|
|
||||||
|
foreach ($statuses as $name) {
|
||||||
|
// Перебор фильтров статусов (ИЛИ)
|
||||||
|
|
||||||
|
// Инициализация значения (приоритет у cookie) (отсутствие значения или значение 0 вызывают continue)
|
||||||
|
if (empty($value = $_COOKIE["administrators_filter_$name"] ?? $this->session->buffer[$_SERVER['INTERFACE']]['administrators']['filters'][$name] ?? 0)) continue;
|
||||||
|
|
||||||
|
// Генерация AQL-выражения для инъекции в строку запроса
|
||||||
|
if ($value === '2') $statuses_or .= " || administrator.$name == true";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Очистка от бинарных операторов сравнения с только одним операндом (крайние)
|
||||||
|
$statuses_or = trim(trim(trim($statuses_or), '||'));
|
||||||
|
|
||||||
|
// Инициализация буфера с объёдинёнными буферами c AQL-выражениям "И" и "ИЛИ"
|
||||||
|
$statuses_merged = (empty($statuses_and) ? '' : "($statuses_and)") . (empty($statuses_or) ? '' : (empty($statuses_and) ? '' : ' || ') . "($statuses_or)");
|
||||||
|
|
||||||
|
// Инициализация общего буфера с AQL-выражениями
|
||||||
|
$filters = '';
|
||||||
|
|
||||||
|
// Объединение фильров в единую строку с AQL-выражениями для инъекции
|
||||||
|
if (!empty($statuses_merged)) $filters .= empty($filters) ? $statuses_merged : " && ($statuses_merged)";
|
||||||
|
|
||||||
|
// Инициализация данных для генерации HTML-документа с таблицей
|
||||||
|
$this->view->rows = registry::administrators(before: empty($filters) ? null : "FILTER ($filters)", page: (int) $this->session->buffer[$_SERVER['INTERFACE']]['administrators']['page']);
|
||||||
|
|
||||||
|
// Запись в cookie (только таким методом можно записать "hostonly: true")
|
||||||
|
setcookie(
|
||||||
|
'administrators_page',
|
||||||
|
(string) $this->session->buffer[$_SERVER['INTERFACE']]['administrators']['page'],
|
||||||
|
[
|
||||||
|
'expires' => strtotime('+1 hour'),
|
||||||
|
'path' => '/',
|
||||||
|
'secure' => true,
|
||||||
|
'httponly' => false,
|
||||||
|
'samesite' => 'strict'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Запись в глобальную переменную шаблонизатора обрабатываемой страницы
|
||||||
|
$this->view->page = $parameters['page'];
|
||||||
|
|
||||||
|
// Инициализация блока
|
||||||
|
return $this->view->render(DIRECTORY_SEPARATOR . 'elements' . DIRECTORY_SEPARATOR . 'administrators.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Возврат (провал)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ namespace mirzaev\ebala\controllers;
|
||||||
// Файлы проекта
|
// Файлы проекта
|
||||||
use mirzaev\ebala\controllers\core,
|
use mirzaev\ebala\controllers\core,
|
||||||
mirzaev\ebala\controllers\traits\errors,
|
mirzaev\ebala\controllers\traits\errors,
|
||||||
mirzaev\ebala\models\operator as model;
|
mirzaev\ebala\models\registry;
|
||||||
|
|
||||||
// Библиотека для ArangoDB
|
// Библиотека для ArangoDB
|
||||||
use ArangoDBClient\Document as _document;
|
use ArangoDBClient\Document as _document;
|
||||||
|
@ -125,7 +125,7 @@ final class operator extends core
|
||||||
if (!empty($statuses_merged)) $filters .= empty($filters) ? $statuses_merged : " && ($statuses_merged)";
|
if (!empty($statuses_merged)) $filters .= empty($filters) ? $statuses_merged : " && ($statuses_merged)";
|
||||||
|
|
||||||
// Инициализация данных для генерации HTML-документа с таблицей
|
// Инициализация данных для генерации HTML-документа с таблицей
|
||||||
$this->view->rows = model::list(before: empty($filters) ? null : "FILTER ($filters)", page: (int) $this->session->buffer[$_SERVER['INTERFACE']]['operators']['page']);
|
$this->view->rows = registry::operators(before: empty($filters) ? null : "FILTER ($filters)", page: (int) $this->session->buffer[$_SERVER['INTERFACE']]['operators']['page']);
|
||||||
|
|
||||||
// Запись в cookie (только таким методом можно записать "hostonly: true")
|
// Запись в cookie (только таким методом можно записать "hostonly: true")
|
||||||
setcookie(
|
setcookie(
|
||||||
|
@ -150,28 +150,4 @@ final class operator extends core
|
||||||
// Возврат (провал)
|
// Возврат (провал)
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Прочитать данные магазинов для <datalist>
|
|
||||||
*
|
|
||||||
* @param array $parameters Параметры запроса
|
|
||||||
*/
|
|
||||||
public function datalist(array $parameters = []): ?string
|
|
||||||
{
|
|
||||||
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator' || $this->account->type === 'operator')) {
|
|
||||||
// Авторизован аккаунт оператора или магазина
|
|
||||||
|
|
||||||
// Инициализация данных магазинов
|
|
||||||
$this->view->operators = model::read(filter: 'd.status == "active"', amount: 10000, return: '{ id: d.id, director: d.director }');
|
|
||||||
|
|
||||||
// Универсализация
|
|
||||||
if ($this->view->operators instanceof _document) $this->view->operators = [$this->view->operators];
|
|
||||||
|
|
||||||
// Возврат (успех)
|
|
||||||
return $this->view->render(DIRECTORY_SEPARATOR . 'lists' . DIRECTORY_SEPARATOR . 'operators.html');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Возврат (провал)
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,10 +85,6 @@ final class task extends core
|
||||||
if ($this->account->status()) {
|
if ($this->account->status()) {
|
||||||
// Авторизован аккаунт
|
// Авторизован аккаунт
|
||||||
|
|
||||||
// Реинициализация актуальной страницы
|
|
||||||
if (isset($parameters['page'])) $this->session->write(['tasks' => ['page' => $parameters['page']]]);
|
|
||||||
else if (empty($this->session->buffer[$_SERVER['INTERFACE']]['tasks']['page'])) $this->session->write(['tasks' => ['page' => 1]]);
|
|
||||||
|
|
||||||
// Инициализация буфера AQL-выражения для инъекции фильтра по интервалу
|
// Инициализация буфера AQL-выражения для инъекции фильтра по интервалу
|
||||||
$interval = '';
|
$interval = '';
|
||||||
|
|
||||||
|
@ -125,12 +121,13 @@ final class task extends core
|
||||||
// Очистка от бинарных операторов сравнения с только одним операндом (крайние)
|
// Очистка от бинарных операторов сравнения с только одним операндом (крайние)
|
||||||
$polysemantic = trim(trim(trim($polysemantic), '&&'));
|
$polysemantic = trim(trim(trim($polysemantic), '&&'));
|
||||||
|
|
||||||
|
|
||||||
// Инициализация допустимых статусов
|
// Инициализация допустимых статусов
|
||||||
// @TODO Добавить инвертирование для waiting и unpublished
|
|
||||||
$statuses = ['confirmed', 'waiting', 'published', 'unpublished', 'problematic', 'hided', 'completed'];
|
$statuses = ['confirmed', 'waiting', 'published', 'unpublished', 'problematic', 'hided', 'completed'];
|
||||||
|
|
||||||
// Инициализация буфера AQL-выражения для инъекции фильтра по статусам (И)
|
// Инициализация буферов AQL-выражений для инъекции фильтра по статусам
|
||||||
$statuses_and = '';
|
$statuses_and = '';
|
||||||
|
$statuses_or = '';
|
||||||
|
|
||||||
foreach ($statuses as $name) {
|
foreach ($statuses as $name) {
|
||||||
// Перебор фильтров статусов (И)
|
// Перебор фильтров статусов (И)
|
||||||
|
@ -138,27 +135,23 @@ final class task extends core
|
||||||
// Инициализация значения (приоритет у cookie) (отсутствие значения или значение 0 вызывают continue)
|
// Инициализация значения (приоритет у cookie) (отсутствие значения или значение 0 вызывают continue)
|
||||||
if (empty($value = $_COOKIE["tasks_filter_$name"] ?? $this->session->buffer[$_SERVER['INTERFACE']]['tasks']['filters'][$name] ?? 0)) continue;
|
if (empty($value = $_COOKIE["tasks_filter_$name"] ?? $this->session->buffer[$_SERVER['INTERFACE']]['tasks']['filters'][$name] ?? 0)) continue;
|
||||||
|
|
||||||
|
// Конвертация ярлыков
|
||||||
|
$converted = match ($name) {
|
||||||
|
'waiting' => 'confirmed',
|
||||||
|
'unpublished' => 'published',
|
||||||
|
default => $name
|
||||||
|
};
|
||||||
|
|
||||||
|
// Генерация выражения
|
||||||
|
$expression = "task.$converted == " . ($name === 'unpublished' || $name === 'waiting' ? 'false' : 'true');
|
||||||
|
|
||||||
// Генерация AQL-выражения для инъекции в строку запроса
|
// Генерация AQL-выражения для инъекции в строку запроса
|
||||||
if ($value === '1') $statuses_and .= " && task.$name == true";
|
if ($value === '1') $statuses_and .= " && " . $expression;
|
||||||
|
else if ($value === '2') $statuses_or .= " || " . $expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Очистка от бинарных операторов сравнения с только одним операндом (крайние)
|
// Очистка от бинарных операторов сравнения с только одним операндом (крайние)
|
||||||
$statuses_and = trim(trim(trim($statuses_and), '&&'));
|
$statuses_and = trim(trim(trim($statuses_and), '&&'));
|
||||||
|
|
||||||
// Инициализация буфера AQL-выражения для инъекции фильтра по статусам (ИЛИ)
|
|
||||||
$statuses_or = '';
|
|
||||||
|
|
||||||
foreach ($statuses as $name) {
|
|
||||||
// Перебор фильтров статусов (ИЛИ)
|
|
||||||
|
|
||||||
// Инициализация значения (приоритет у cookie) (отсутствие значения или значение 0 вызывают continue)
|
|
||||||
if (empty($value = $_COOKIE["tasks_filter_$name"] ?? $this->session->buffer[$_SERVER['INTERFACE']]['tasks']['filters'][$name] ?? 0)) continue;
|
|
||||||
|
|
||||||
// Генерация AQL-выражения для инъекции в строку запроса
|
|
||||||
if ($value === '2') $statuses_or .= " || task.$name == true";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Очистка от бинарных операторов сравнения с только одним операндом (крайние)
|
|
||||||
$statuses_or = trim(trim(trim($statuses_or), '||'));
|
$statuses_or = trim(trim(trim($statuses_or), '||'));
|
||||||
|
|
||||||
// Инициализация буфера с объёдинёнными буферами c AQL-выражениям "И" и "ИЛИ"
|
// Инициализация буфера с объёдинёнными буферами c AQL-выражениям "И" и "ИЛИ"
|
||||||
|
@ -172,36 +165,60 @@ final class task extends core
|
||||||
if (!empty($statuses_merged)) $filters .= empty($filters) ? $statuses_merged : " && ($statuses_merged)";
|
if (!empty($statuses_merged)) $filters .= empty($filters) ? $statuses_merged : " && ($statuses_merged)";
|
||||||
if (!empty($polysemantic)) $filters .= empty($filters) ? $polysemantic : " && $polysemantic";
|
if (!empty($polysemantic)) $filters .= empty($filters) ? $polysemantic : " && $polysemantic";
|
||||||
|
|
||||||
// Инициализация данных для генерации HTML-документа с таблицей
|
if (isset($parameters['row'])) {
|
||||||
if ($_SERVER['INTERFACE'] === 'worker')
|
// Запрошена строка
|
||||||
$this->view->rows = model::list(before: 'FILTER task.worker == "' . account::worker($this->account->number)?->id . '"' . empty($filters) ? null : " && ($filters)", page: (int) $this->session->buffer['worker']['tasks']['page']);
|
|
||||||
else if ($_SERVER['INTERFACE'] === 'operator')
|
|
||||||
$this->view->rows = model::list(before: empty($filters) ? null : "FILTER ($filters)", page: (int) $this->session->buffer['operator']['tasks']['page']);
|
|
||||||
else if ($_SERVER['INTERFACE'] === 'market')
|
|
||||||
$this->view->rows = model::list(before: 'FILTER task.market == "' . $this->market->id . '"' . empty($filters) ? null : " && ($filters)", page: (int) $this->session->buffer['market']['tasks']['page']);
|
|
||||||
else if ($_SERVER['INTERFACE'] === 'administrator')
|
|
||||||
$this->view->rows = model::list(before: empty($filters) ? null : "FILTER ($filters)", page: (int) $this->session->buffer['administrator']['tasks']['page']);
|
|
||||||
else $this->view->rows = [];
|
|
||||||
|
|
||||||
// Запись в cookie (только таким методом можно записать "hostonly: true")
|
// Добавление идентификатора строки в фильтр
|
||||||
setcookie(
|
$filters .= ' && task._key == "' . $parameters['row'] . '"';
|
||||||
'tasks_page',
|
|
||||||
(string) $this->session->buffer[$_SERVER['INTERFACE']]['tasks']['page'],
|
// Инициализация данных для генерации HTML-документа с таблицей
|
||||||
[
|
if ($_SERVER['INTERFACE'] === 'worker')
|
||||||
'expires' => strtotime('+1 hour'),
|
$this->view->rows = model::list(before: 'FILTER task.worker == "' . account::worker($this->account->number)?->id . '"' . " && ($filters)");
|
||||||
'path' => '/',
|
else if ($_SERVER['INTERFACE'] === 'operator')
|
||||||
'secure' => true,
|
$this->view->rows = model::list(before: "FILTER ($filters)");
|
||||||
'httponly' => false,
|
else if ($_SERVER['INTERFACE'] === 'market')
|
||||||
'samesite' => 'strict'
|
$this->view->rows = model::list(before: 'FILTER task.market == "' . $this->market->id . '"' . " && ($filters)");
|
||||||
]
|
else if ($_SERVER['INTERFACE'] === 'administrator')
|
||||||
);
|
$this->view->rows = model::list(before: "FILTER ($filters)");
|
||||||
|
else $this->view->rows = [];
|
||||||
|
} else {
|
||||||
|
// Запрошена страница (множество строк)
|
||||||
|
|
||||||
|
// Реинициализация актуальной страницы
|
||||||
|
if (isset($parameters['page'])) $this->session->write(['tasks' => ['page' => $parameters['page']]]);
|
||||||
|
else if (empty($this->session->buffer[$_SERVER['INTERFACE']]['tasks']['page'])) $this->session->write(['tasks' => ['page' => 1]]);
|
||||||
|
|
||||||
|
// Инициализация данных для генерации HTML-документа с таблицей
|
||||||
|
if ($_SERVER['INTERFACE'] === 'worker')
|
||||||
|
$this->view->rows = model::list(before: 'FILTER task.worker == "' . account::worker($this->account->number)?->id . '"' . empty($filters) ? null : " && ($filters)", page: (int) $this->session->buffer['worker']['tasks']['page']);
|
||||||
|
else if ($_SERVER['INTERFACE'] === 'operator')
|
||||||
|
$this->view->rows = model::list(before: empty($filters) ? null : "FILTER ($filters)", page: (int) $this->session->buffer['operator']['tasks']['page']);
|
||||||
|
else if ($_SERVER['INTERFACE'] === 'market')
|
||||||
|
$this->view->rows = model::list(before: 'FILTER task.market == "' . $this->market->id . '"' . empty($filters) ? null : " && ($filters)", page: (int) $this->session->buffer['market']['tasks']['page']);
|
||||||
|
else if ($_SERVER['INTERFACE'] === 'administrator')
|
||||||
|
$this->view->rows = model::list(before: empty($filters) ? null : "FILTER ($filters)", page: (int) $this->session->buffer['administrator']['tasks']['page']);
|
||||||
|
else $this->view->rows = [];
|
||||||
|
|
||||||
|
// Запись в cookie (только таким методом можно записать "hostonly: true")
|
||||||
|
setcookie(
|
||||||
|
'tasks_page',
|
||||||
|
(string) $this->session->buffer[$_SERVER['INTERFACE']]['tasks']['page'],
|
||||||
|
[
|
||||||
|
'expires' => strtotime('+1 hour'),
|
||||||
|
'path' => '/',
|
||||||
|
'secure' => true,
|
||||||
|
'httponly' => false,
|
||||||
|
'samesite' => 'strict'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Запись в глобальную переменную шаблонизатора обрабатываемой страницы
|
||||||
|
$this->view->page = $parameters['page'];
|
||||||
|
};
|
||||||
|
|
||||||
// Предобработка строк перед генерацией документа
|
// Предобработка строк перед генерацией документа
|
||||||
$this->view->rows = static::preprocessing($this->view->rows);
|
$this->view->rows = static::preprocessing($this->view->rows);
|
||||||
|
|
||||||
// Запись в глобальную переменную шаблонизатора обрабатываемой страницы
|
|
||||||
$this->view->page = $parameters['page'];
|
|
||||||
|
|
||||||
// Инициализация блока
|
// Инициализация блока
|
||||||
return $this->view->render(DIRECTORY_SEPARATOR . 'elements' . DIRECTORY_SEPARATOR . 'tasks.html');
|
return $this->view->render(DIRECTORY_SEPARATOR . 'elements' . DIRECTORY_SEPARATOR . 'tasks.html');
|
||||||
}
|
}
|
||||||
|
@ -1003,10 +1020,6 @@ final class task extends core
|
||||||
// Инициализация строки в глобальную переменную шаблонизатора
|
// Инициализация строки в глобальную переменную шаблонизатора
|
||||||
$this->view->rows = static::preprocessing(model::list(before: 'FILTER task._key == "' . $parameters['task'] . '"', amount: 1));
|
$this->view->rows = static::preprocessing(model::list(before: 'FILTER task._key == "' . $parameters['task'] . '"', amount: 1));
|
||||||
|
|
||||||
// Запись в глобальную переменную шаблонизатора обрабатываемой страницы (отключение)
|
|
||||||
$this->view->page = null;
|
|
||||||
|
|
||||||
|
|
||||||
// Запись заголовков ответа
|
// Запись заголовков ответа
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
header('Content-Encoding: none');
|
header('Content-Encoding: none');
|
||||||
|
@ -1045,7 +1058,7 @@ final class task extends core
|
||||||
public function commentary(array $parameters = []): void
|
public function commentary(array $parameters = []): void
|
||||||
{
|
{
|
||||||
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator' || $this->account->type === 'market')) {
|
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator' || $this->account->type === 'market')) {
|
||||||
// Авторизован аккаунт оператора
|
// Авторизован аккаунт оператора, администратора или магазина
|
||||||
|
|
||||||
// Инициализация данных
|
// Инициализация данных
|
||||||
$task = model::read('d._key == "' . $parameters['task'] . '"');
|
$task = model::read('d._key == "' . $parameters['task'] . '"');
|
||||||
|
@ -1062,9 +1075,6 @@ final class task extends core
|
||||||
// Инициализация строки в глобальную переменную шаблонизатора
|
// Инициализация строки в глобальную переменную шаблонизатора
|
||||||
$this->view->rows = static::preprocessing(model::list(before: 'FILTER task._key == "' . $parameters['task'] . '"', amount: 1));
|
$this->view->rows = static::preprocessing(model::list(before: 'FILTER task._key == "' . $parameters['task'] . '"', amount: 1));
|
||||||
|
|
||||||
// Запись в глобальную переменную шаблонизатора обрабатываемой страницы (отключение)
|
|
||||||
$this->view->page = null;
|
|
||||||
|
|
||||||
// Запись заголовков ответа
|
// Запись заголовков ответа
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
header('Content-Encoding: none');
|
header('Content-Encoding: none');
|
||||||
|
@ -1092,4 +1102,115 @@ final class task extends core
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Опубликовать
|
||||||
|
*
|
||||||
|
* @param array $parameters Параметры запроса
|
||||||
|
*
|
||||||
|
* @return void В буфер вывода JSON-документ с запрашиваемыми параметрами
|
||||||
|
*/
|
||||||
|
public function publish(array $parameters = []): void
|
||||||
|
{
|
||||||
|
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator')) {
|
||||||
|
// Авторизован аккаунт оператора
|
||||||
|
|
||||||
|
// Инициализация данных
|
||||||
|
$task = model::read('d._key == "' . $parameters['task'] . '"');
|
||||||
|
|
||||||
|
if ($task instanceof _document) {
|
||||||
|
// Найдена заявка
|
||||||
|
|
||||||
|
// Запись статуса о публикации
|
||||||
|
$task->published = true;
|
||||||
|
|
||||||
|
if (_core::update($task)) {
|
||||||
|
// Записано в ArangoDB
|
||||||
|
|
||||||
|
// Инициализация строки в глобальную переменную шаблонизатора
|
||||||
|
$this->view->rows = static::preprocessing(model::list(before: 'FILTER task._key == "' . $parameters['task'] . '"', amount: 1));
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
header('Content-Encoding: none');
|
||||||
|
header('X-Accel-Buffering: no');
|
||||||
|
|
||||||
|
// Инициализация буфера вывода
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
// Генерация ответа
|
||||||
|
echo json_encode(
|
||||||
|
[
|
||||||
|
'published' => true,
|
||||||
|
'row' => $this->view->render(DIRECTORY_SEPARATOR . 'elements' . DIRECTORY_SEPARATOR . 'tasks.html'),
|
||||||
|
'errors' => self::parse_only_text($this->errors)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Length: ' . ob_get_length());
|
||||||
|
|
||||||
|
// Отправка и деинициализация буфера вывода
|
||||||
|
ob_end_flush();
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Снять с публикации
|
||||||
|
*
|
||||||
|
* @param array $parameters Параметры запроса
|
||||||
|
*
|
||||||
|
* @return void В буфер вывода JSON-документ с запрашиваемыми параметрами
|
||||||
|
*/
|
||||||
|
public function unpublish(array $parameters = []): void
|
||||||
|
{
|
||||||
|
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator')) {
|
||||||
|
// Авторизован аккаунт оператора
|
||||||
|
|
||||||
|
// Инициализация данных
|
||||||
|
$task = model::read('d._key == "' . $parameters['task'] . '"');
|
||||||
|
|
||||||
|
if ($task instanceof _document) {
|
||||||
|
// Найдена заявка
|
||||||
|
|
||||||
|
// Запись статуса о публикации
|
||||||
|
$task->published = false;
|
||||||
|
|
||||||
|
if (_core::update($task)) {
|
||||||
|
// Записано в ArangoDB
|
||||||
|
|
||||||
|
// Инициализация строки в глобальную переменную шаблонизатора
|
||||||
|
$this->view->rows = static::preprocessing(model::list(before: 'FILTER task._key == "' . $parameters['task'] . '"', amount: 1));
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
header('Content-Encoding: none');
|
||||||
|
header('X-Accel-Buffering: no');
|
||||||
|
|
||||||
|
// Инициализация буфера вывода
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
// Генерация ответа
|
||||||
|
echo json_encode(
|
||||||
|
[
|
||||||
|
'unpublished' => true,
|
||||||
|
'row' => $this->view->render(DIRECTORY_SEPARATOR . 'elements' . DIRECTORY_SEPARATOR . 'tasks.html'),
|
||||||
|
'errors' => self::parse_only_text($this->errors)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Запись заголовков ответа
|
||||||
|
header('Content-Length: ' . ob_get_length());
|
||||||
|
|
||||||
|
// Отправка и деинициализация буфера вывода
|
||||||
|
ob_end_flush();
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ class core extends model
|
||||||
*/
|
*/
|
||||||
public static function read(
|
public static function read(
|
||||||
string $filter = '',
|
string $filter = '',
|
||||||
string $sort = 'd.created DESC',
|
string $sort = 'd.created DESC, d._key DESC',
|
||||||
int $amount = 1,
|
int $amount = 1,
|
||||||
int $page = 1,
|
int $page = 1,
|
||||||
string $return = 'd',
|
string $return = 'd',
|
||||||
|
|
|
@ -46,7 +46,7 @@ final class registry extends core
|
||||||
?string $before = '',
|
?string $before = '',
|
||||||
int $amount = 100,
|
int $amount = 100,
|
||||||
int $page = 1,
|
int $page = 1,
|
||||||
string $sort = 'worker.created DESC',
|
string $sort = 'worker.created DESC, worker._key DESC',
|
||||||
array &$errors = []
|
array &$errors = []
|
||||||
): array {
|
): array {
|
||||||
try {
|
try {
|
||||||
|
@ -57,7 +57,7 @@ final class registry extends core
|
||||||
$workers = collection::search(static::$arangodb->session, sprintf(
|
$workers = collection::search(static::$arangodb->session, sprintf(
|
||||||
<<<AQL
|
<<<AQL
|
||||||
FOR account IN %s
|
FOR account IN %s
|
||||||
FILTER account.status != 'deleted'
|
FILTER account.type == 'worker' && account.status != 'deleted'
|
||||||
%s
|
%s
|
||||||
LET worker = (FOR worker IN OUTBOUND account._id account_edge_worker FILTER worker.status != 'deleted' LIMIT 1 SORT worker.created DESC RETURN worker)[0]
|
LET worker = (FOR worker IN OUTBOUND account._id account_edge_worker FILTER worker.status != 'deleted' LIMIT 1 SORT worker.created DESC RETURN worker)[0]
|
||||||
FILTER worker != null
|
FILTER worker != null
|
||||||
|
@ -103,7 +103,7 @@ final class registry extends core
|
||||||
?string $before = '',
|
?string $before = '',
|
||||||
int $amount = 100,
|
int $amount = 100,
|
||||||
int $page = 1,
|
int $page = 1,
|
||||||
string $sort = 'market.created DESC',
|
string $sort = 'market.created DESC, market._key DESC',
|
||||||
array &$errors = []
|
array &$errors = []
|
||||||
): array {
|
): array {
|
||||||
try {
|
try {
|
||||||
|
@ -114,7 +114,7 @@ final class registry extends core
|
||||||
$markets = collection::search(static::$arangodb->session, sprintf(
|
$markets = collection::search(static::$arangodb->session, sprintf(
|
||||||
<<<AQL
|
<<<AQL
|
||||||
FOR account IN %s
|
FOR account IN %s
|
||||||
FILTER account.status != 'deleted'
|
FILTER account.type == 'market' && account.status != 'deleted'
|
||||||
%s
|
%s
|
||||||
LET market = (FOR market IN OUTBOUND account._id account_edge_market FILTER market.status != 'deleted' LIMIT 1 SORT market.created DESC RETURN market)[0]
|
LET market = (FOR market IN OUTBOUND account._id account_edge_market FILTER market.status != 'deleted' LIMIT 1 SORT market.created DESC RETURN market)[0]
|
||||||
FILTER market != null
|
FILTER market != null
|
||||||
|
@ -145,4 +145,114 @@ final class registry extends core
|
||||||
// Exit (fail)
|
// Exit (fail)
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate operators list
|
||||||
|
*
|
||||||
|
* @param ?string $before Injection of AQL-code before search
|
||||||
|
* @param int $amount Amount of operators
|
||||||
|
* @param int $page Offset by amount
|
||||||
|
* @param array $errors Errors registry
|
||||||
|
*
|
||||||
|
* @return array Instances from ArangoDB
|
||||||
|
*/
|
||||||
|
public static function operators(
|
||||||
|
?string $before = '',
|
||||||
|
int $amount = 100,
|
||||||
|
int $page = 1,
|
||||||
|
string $sort = 'account.created DESC, account._key DESC',
|
||||||
|
array &$errors = []
|
||||||
|
): array {
|
||||||
|
try {
|
||||||
|
if (collection::init(static::$arangodb->session, account::COLLECTION)) {
|
||||||
|
// Инициализирована коллекция
|
||||||
|
|
||||||
|
// Search the session data in ArangoDB
|
||||||
|
$operators = collection::search(static::$arangodb->session, sprintf(
|
||||||
|
<<<AQL
|
||||||
|
FOR account IN %s
|
||||||
|
FILTER account.type == 'operator' && account.status != 'deleted'
|
||||||
|
%s
|
||||||
|
SORT %s
|
||||||
|
LIMIT %d, %d
|
||||||
|
RETURN {account}
|
||||||
|
AQL,
|
||||||
|
account::COLLECTION,
|
||||||
|
$before,
|
||||||
|
$sort,
|
||||||
|
--$page <= 0 ? 0 : $amount * $page,
|
||||||
|
$amount
|
||||||
|
));
|
||||||
|
|
||||||
|
// Exit (success)
|
||||||
|
return empty($operators) ? [] : (is_array($operators) ? $operators : [$operators]);
|
||||||
|
} else throw new exception('Не удалось инициализировать коллекции');
|
||||||
|
} catch (exception $e) {
|
||||||
|
// Write to the errors registry
|
||||||
|
$errors[] = [
|
||||||
|
'text' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'stack' => $e->getTrace()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit (fail)
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate administrators list
|
||||||
|
*
|
||||||
|
* @param ?string $before Injection of AQL-code before search
|
||||||
|
* @param int $amount Amount of administrators
|
||||||
|
* @param int $page Offset by amount
|
||||||
|
* @param array $errors Errors registry
|
||||||
|
*
|
||||||
|
* @return array Instances from ArangoDB
|
||||||
|
*/
|
||||||
|
public static function administrators(
|
||||||
|
?string $before = '',
|
||||||
|
int $amount = 100,
|
||||||
|
int $page = 1,
|
||||||
|
string $sort = 'account.created DESC, account._key DESC',
|
||||||
|
array &$errors = []
|
||||||
|
): array {
|
||||||
|
try {
|
||||||
|
if (collection::init(static::$arangodb->session, account::COLLECTION)) {
|
||||||
|
// Инициализирована коллекция
|
||||||
|
|
||||||
|
// Search the session data in ArangoDB
|
||||||
|
$administrators = collection::search(static::$arangodb->session, sprintf(
|
||||||
|
<<<AQL
|
||||||
|
FOR account IN %s
|
||||||
|
FILTER account.type == 'administrator' && account.status != 'deleted'
|
||||||
|
%s
|
||||||
|
SORT %s
|
||||||
|
LIMIT %d, %d
|
||||||
|
RETURN {account}
|
||||||
|
AQL,
|
||||||
|
account::COLLECTION,
|
||||||
|
$before,
|
||||||
|
$sort,
|
||||||
|
--$page <= 0 ? 0 : $amount * $page,
|
||||||
|
$amount
|
||||||
|
));
|
||||||
|
|
||||||
|
// Exit (success)
|
||||||
|
return empty($administrators) ? [] : (is_array($administrators) ? $administrators : [$administrators]);
|
||||||
|
} else throw new exception('Не удалось инициализировать коллекции');
|
||||||
|
} catch (exception $e) {
|
||||||
|
// Write to the errors registry
|
||||||
|
$errors[] = [
|
||||||
|
'text' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'stack' => $e->getTrace()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit (fail)
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ final class task extends core
|
||||||
?string $after = '',
|
?string $after = '',
|
||||||
int $amount = 100,
|
int $amount = 100,
|
||||||
int $page = 1,
|
int $page = 1,
|
||||||
string $sort = 'task.created DESC',
|
string $sort = 'task.created DESC, task._key DESC',
|
||||||
array &$errors = []
|
array &$errors = []
|
||||||
): array {
|
): array {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -22,6 +22,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes row-reinitialized {
|
||||||
|
0%,
|
||||||
|
20% {
|
||||||
|
filter: contrast(0.4);
|
||||||
|
background-color: var(--earth-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
50%,
|
||||||
|
100% {
|
||||||
|
filter: unset;
|
||||||
|
background-color: var(--background, --earth-background-above);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes uprise {
|
@keyframes uprise {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
|
@ -85,12 +85,23 @@ section.panel.list > div#title > span {
|
||||||
}
|
}
|
||||||
|
|
||||||
section.panel.list > div.row {
|
section.panel.list > div.row {
|
||||||
|
--background: var(--background-above-1);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
left: 0px;
|
||||||
|
width: calc(100% - 24px);
|
||||||
height: 35px;
|
height: 35px;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
background-color: var(--background-above-1);
|
border-radius: 0px;
|
||||||
|
background-color: var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
section.panel.list > div.row:not(:nth-of-type(1)):hover {
|
||||||
|
left: -12px;
|
||||||
|
padding: 0 24px;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
section.panel.list > div.row:first-of-type {
|
section.panel.list > div.row:first-of-type {
|
||||||
|
@ -106,7 +117,7 @@ section.panel.list > div.row:hover * {
|
||||||
}
|
}
|
||||||
|
|
||||||
section.panel.list > div.row:nth-of-type(2n + 1) {
|
section.panel.list > div.row:nth-of-type(2n + 1) {
|
||||||
background-color: var(--background-above-2);
|
--background: var(--background-above-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
section.panel.list > div.row[data-selected="true"]::before {
|
section.panel.list > div.row[data-selected="true"]::before {
|
||||||
|
@ -149,11 +160,27 @@ section.panel.list > div.row[data-selected="true"]::after {
|
||||||
}
|
}
|
||||||
|
|
||||||
section.panel.list > div.row.confirmed {
|
section.panel.list > div.row.confirmed {
|
||||||
background-color: var(--grass-background-above-2);
|
--background: var(--grass-background-above-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
section.panel.list > div.row.confirmed:nth-of-type(2n + 1) {
|
section.panel.list > div.row.confirmed:nth-of-type(2n + 1) {
|
||||||
background-color: var(--grass-background-above-1);
|
--background: var(--grass-background-above-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
section.panel.list > div.row.published {
|
||||||
|
--background: var(--river-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
section.panel.list > div.row.published:nth-of-type(2n + 1) {
|
||||||
|
--background: var(--river-background-above);
|
||||||
|
}
|
||||||
|
|
||||||
|
section.panel.list > div.row.confirmed.published {
|
||||||
|
--background: var(--sea-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
section.panel.list > div.row.confirmed.published:nth-of-type(2n + 1) {
|
||||||
|
--background: var(--sea-background-above);
|
||||||
}
|
}
|
||||||
|
|
||||||
section.panel.list > div.row.hided {
|
section.panel.list > div.row.hided {
|
||||||
|
@ -180,6 +207,25 @@ section.panel.list > div.row.hided:hover * {
|
||||||
opacity: unset;
|
opacity: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
section.panel.list > div.row.reinitialized {
|
||||||
|
animation-duration: 3s;
|
||||||
|
animation-name: row-reinitialized;
|
||||||
|
animation-timing-function: ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.panel.list
|
||||||
|
> div.row:not(:nth-of-type(1), [data-selected="true"]).reinitializable:before {
|
||||||
|
content: var(--counter, "0");
|
||||||
|
position: absolute;
|
||||||
|
left: -95px;
|
||||||
|
align-self: center;
|
||||||
|
width: 80px;
|
||||||
|
text-align: right;
|
||||||
|
font-size: small;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--earth-text-above);
|
||||||
|
}
|
||||||
|
|
||||||
section.panel.list > div.row > span {
|
section.panel.list > div.row > span {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: auto 0;
|
margin: auto 0;
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
section#administrators.panel.list
|
||||||
|
> div.row:nth-of-type(1)
|
||||||
|
> span[data-column="end"]
|
||||||
|
> i.home {
|
||||||
|
margin-top: 5px;
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#administrators.panel.list
|
||||||
|
> div.row
|
||||||
|
> span:is(
|
||||||
|
[data-column="id"],
|
||||||
|
[data-column="name"],
|
||||||
|
[data-column="number"],
|
||||||
|
[data-column="mail"],
|
||||||
|
[data-column="commentary"],
|
||||||
|
[data-column="status"],
|
||||||
|
|
||||||
|
) {
|
||||||
|
min-width: 220px;
|
||||||
|
width: 220px;
|
||||||
|
display: ruby;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#administrators.panel.list > div.row > span[data-column="id"] {
|
||||||
|
min-width: 102px;
|
||||||
|
width: 102px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#administrators.panel.list > div.row:nth-of-type(1) > span[data-column="id"] {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#administrators.panel.list > div.row > span[data-column="name"] {
|
||||||
|
min-width: 180px;
|
||||||
|
width: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#administrators.panel.list > div.row > span[data-column="number"] {
|
||||||
|
min-width: 130px;
|
||||||
|
width: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#administrators.panel.list > div.row > span[data-column="mail"] {
|
||||||
|
min-width: 300px;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#administrators.panel.list > div.row > span[data-column="commentary"] {
|
||||||
|
min-width: unset;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#administrators.panel.list > div.row > span[data-column="status"] {
|
||||||
|
min-width: 100px;
|
||||||
|
width: 100px;
|
||||||
|
font-size: small;
|
||||||
|
text-align: center;
|
||||||
|
}
|
|
@ -34,8 +34,8 @@ section#markets.panel.list > div.row:nth-of-type(1) > span[data-column="id"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
section#markets.panel.list > div.row > span[data-column="director"] {
|
section#markets.panel.list > div.row > span[data-column="director"] {
|
||||||
min-width: 400px;
|
min-width: 180px;
|
||||||
width: 400px;
|
width: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
section#markets.panel.list > div.row > span[data-column="address"] {
|
section#markets.panel.list > div.row > span[data-column="address"] {
|
||||||
|
|
|
@ -11,16 +11,11 @@ section#operators.panel.list
|
||||||
> span:is(
|
> span:is(
|
||||||
[data-column="id"],
|
[data-column="id"],
|
||||||
[data-column="name"],
|
[data-column="name"],
|
||||||
[data-column="birth"],
|
|
||||||
[data-column="number"],
|
[data-column="number"],
|
||||||
[data-column="passport"],
|
[data-column="mail"],
|
||||||
[data-column="department"],
|
|
||||||
[data-column="city"],
|
|
||||||
[data-column="address"],
|
|
||||||
[data-column="requisites"],
|
|
||||||
[data-column="tax"],
|
|
||||||
[data-column="commentary"],
|
[data-column="commentary"],
|
||||||
[data-column="status"],
|
[data-column="status"],
|
||||||
|
|
||||||
) {
|
) {
|
||||||
min-width: 220px;
|
min-width: 220px;
|
||||||
width: 220px;
|
width: 220px;
|
||||||
|
@ -30,9 +25,10 @@ section#operators.panel.list
|
||||||
}
|
}
|
||||||
|
|
||||||
section#operators.panel.list > div.row > span[data-column="id"] {
|
section#operators.panel.list > div.row > span[data-column="id"] {
|
||||||
min-width: 67px;
|
min-width: 102px;
|
||||||
width: 67px;
|
width: 102px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
section#operators.panel.list > div.row:nth-of-type(1) > span[data-column="id"] {
|
section#operators.panel.list > div.row:nth-of-type(1) > span[data-column="id"] {
|
||||||
|
@ -40,45 +36,18 @@ section#operators.panel.list > div.row:nth-of-type(1) > span[data-column="id"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
section#operators.panel.list > div.row > span[data-column="name"] {
|
section#operators.panel.list > div.row > span[data-column="name"] {
|
||||||
min-width: 200px;
|
min-width: 180px;
|
||||||
width: 200px;
|
width: 180px;
|
||||||
}
|
|
||||||
|
|
||||||
section#operators.panel.list > div.row > span[data-column="birth"] {
|
|
||||||
min-width: 80px;
|
|
||||||
width: 80px;
|
|
||||||
font-size: small;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
section#operators.panel.list > div.row > span[data-column="number"] {
|
section#operators.panel.list > div.row > span[data-column="number"] {
|
||||||
min-width: 120px;
|
min-width: 130px;
|
||||||
width: 120px;
|
width: 130px;
|
||||||
}
|
}
|
||||||
|
|
||||||
section#operators.panel.list > div.row > span[data-column="passport"] {
|
section#operators.panel.list > div.row > span[data-column="mail"] {
|
||||||
min-width: 150px;
|
min-width: 300px;
|
||||||
width: 150px;
|
width: 300px;
|
||||||
}
|
|
||||||
|
|
||||||
section#operators.panel.list > div.row > span[data-column="city"] {
|
|
||||||
min-width: 90px;
|
|
||||||
width: 90px;
|
|
||||||
}
|
|
||||||
|
|
||||||
section#operators.panel.list > div.row > span[data-column="address"] {
|
|
||||||
min-width: 180px;
|
|
||||||
width: 180px;
|
|
||||||
}
|
|
||||||
|
|
||||||
section#operators.panel.list > div.row > span[data-column="requisites"] {
|
|
||||||
min-width: 180px;
|
|
||||||
width: 180px;
|
|
||||||
}
|
|
||||||
|
|
||||||
section#operators.panel.list > div.row > span[data-column="tax"] {
|
|
||||||
min-width: 55px;
|
|
||||||
width: 55px;
|
|
||||||
font-size: small;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
section#operators.panel.list > div.row > span[data-column="commentary"] {
|
section#operators.panel.list > div.row > span[data-column="commentary"] {
|
||||||
|
|
|
@ -39,8 +39,17 @@ section#tasks.panel.list > div.row:nth-of-type(1) > span[data-column="worker"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
section#tasks.panel.list > div.row > span[data-column="name"] {
|
section#tasks.panel.list > div.row > span[data-column="name"] {
|
||||||
min-width: 200px;
|
min-width: 180px;
|
||||||
width: 200px;
|
width: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#tasks.panel.list > div.row > span[data-column="task"] {
|
||||||
|
min-width: 100px;
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#tasks.panel.list > div.row:not(:nth-of-type(1)) > span[data-column="task"] {
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
section#tasks.panel.list > div.row:nth-of-type(1) > span[data-column="start"] {
|
section#tasks.panel.list > div.row:nth-of-type(1) > span[data-column="start"] {
|
||||||
|
@ -69,13 +78,17 @@ section#tasks.panel.list > div.row > span[data-column="hours"] {
|
||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
section#tasks.panel.list > div.row:not(:nth-of-type(1)) > span[data-column="hours"] {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
section#tasks.panel.list > div.row:nth-of-type(1) > span[data-column="market"] {
|
section#tasks.panel.list > div.row:nth-of-type(1) > span[data-column="market"] {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
section#tasks.panel.list > div.row > span[data-column="market"] {
|
section#tasks.panel.list > div.row > span[data-column="market"] {
|
||||||
min-width: 46px;
|
min-width: 60px;
|
||||||
width: 46px;
|
width: 60px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,17 +98,25 @@ section#tasks.panel.list > div.row > span[data-column="address"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
section#tasks.panel.list > div.row > span[data-column="type"] {
|
section#tasks.panel.list > div.row > span[data-column="type"] {
|
||||||
min-width: 53px;
|
min-width: 80px;
|
||||||
width: 53px;
|
width: 80px;
|
||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
section#tasks.panel.list > div.row:not(:nth-of-type(1)) > span[data-column="type"] {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
section#tasks.panel.list > div.row > span[data-column="tax"] {
|
section#tasks.panel.list > div.row > span[data-column="tax"] {
|
||||||
min-width: 55px;
|
min-width: 100px;
|
||||||
width: 55px;
|
width: 100px;
|
||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
section#tasks.panel.list > div.row:not(:nth-of-type(1)) > span[data-column="tax"] {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
section#tasks.panel.list > div.row > span[data-column="commentary"] {
|
section#tasks.panel.list > div.row > span[data-column="commentary"] {
|
||||||
min-width: unset;
|
min-width: unset;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -47,8 +47,10 @@ $router->write('/markets/read', 'market', 'read', 'POST');
|
||||||
$router->write('/markets/list', 'market', 'datalist', 'POST');
|
$router->write('/markets/list', 'market', 'datalist', 'POST');
|
||||||
$router->write('/operators', 'operator', 'index', 'GET');
|
$router->write('/operators', 'operator', 'index', 'GET');
|
||||||
$router->write('/operators', 'operator', 'index', 'POST');
|
$router->write('/operators', 'operator', 'index', 'POST');
|
||||||
$router->write('/administrators', 'administrators', 'index', 'GET');
|
$router->write('/operators/read', 'operator', 'read', 'POST');
|
||||||
$router->write('/administrators', 'administrators', 'index', 'POST');
|
$router->write('/administrators', 'administrator', 'index', 'GET');
|
||||||
|
$router->write('/administrators', 'administrator', 'index', 'POST');
|
||||||
|
$router->write('/administrators/read', 'administrator', 'read', 'POST');
|
||||||
$router->write('/settings', 'settings', 'index', 'GET');
|
$router->write('/settings', 'settings', 'index', 'GET');
|
||||||
$router->write('/settings', 'settings', 'index', 'POST');
|
$router->write('/settings', 'settings', 'index', 'POST');
|
||||||
$router->write('/$id', 'account', 'index', 'GET');
|
$router->write('/$id', 'account', 'index', 'GET');
|
||||||
|
@ -76,6 +78,8 @@ $router->write('/task/$task/description', 'task', 'description', 'POST');
|
||||||
$router->write('/task/$task/commentary', 'task', 'commentary', 'POST');
|
$router->write('/task/$task/commentary', 'task', 'commentary', 'POST');
|
||||||
$router->write('/task/$task/worker/update', 'task', 'update', 'POST');
|
$router->write('/task/$task/worker/update', 'task', 'update', 'POST');
|
||||||
$router->write('/task/$task/market/update', 'task', 'update', 'POST');
|
$router->write('/task/$task/market/update', 'task', 'update', 'POST');
|
||||||
|
$router->write('/task/$task/publish', 'task', 'publish', 'POST');
|
||||||
|
$router->write('/task/$task/unpublish', 'task', 'unpublish', 'POST');
|
||||||
$router->write('/elements/menu', 'index', 'menu', 'POST');
|
$router->write('/elements/menu', 'index', 'menu', 'POST');
|
||||||
|
|
||||||
// Инициализация ядра
|
// Инициализация ядра
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1006,7 +1006,7 @@ if (typeof window.markets !== "function") {
|
||||||
/**
|
/**
|
||||||
* Прочитать
|
* Прочитать
|
||||||
*
|
*
|
||||||
* Читает список сотрудников и модифицирует документ (записывает в общий список)
|
* Читает список и модифицирует документ (записывает в общий список)
|
||||||
*
|
*
|
||||||
* @param {number} page Страница
|
* @param {number} page Страница
|
||||||
*
|
*
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -504,19 +504,29 @@ if (typeof window.tasks !== "function") {
|
||||||
*
|
*
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
static async init(amount = 3, iteration = 0) {
|
static init(amount = 3, iteration = 0) {
|
||||||
if (
|
if (
|
||||||
typeof amount === "number" && typeof iteration === "number" &&
|
typeof amount === "number" && typeof iteration === "number" &&
|
||||||
this.initialized === false
|
this.initialized === false
|
||||||
) {
|
) {
|
||||||
// Получены количество страниц и номер итерации
|
// Получены количество страниц и номер итерации
|
||||||
|
|
||||||
// Инициализация страницы (написал tasks потому, что оптимизатор выдаёт ошибку, что this.read не найдено, хотя всё работает)
|
// Инициализация страницы
|
||||||
await tasks.read(++iteration);
|
tasks.read(++iteration);
|
||||||
|
|
||||||
// Проверка условий и отложенный запуск следующей итерации
|
function generate() {
|
||||||
if (iteration < amount) setTimeout(this.init, 1500, amount, iteration);
|
// Завершено выполнение итерации
|
||||||
else this.initialized = true;
|
|
||||||
|
// Деинициализация слушателя завершения текущей итерации
|
||||||
|
document.removeEventListener("tasks.read." + iteration, generate);
|
||||||
|
|
||||||
|
// Проверка условий и запуск следующей итерации
|
||||||
|
if (iteration < amount) tasks.init(amount, iteration);
|
||||||
|
else this.initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Инициализация слушателя завершения текущей итерации
|
||||||
|
document.addEventListener("tasks.read." + iteration, generate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,10 +568,11 @@ if (typeof window.tasks !== "function") {
|
||||||
|
|
||||||
// Деинициализация страниц
|
// Деинициализация страниц
|
||||||
for (
|
for (
|
||||||
const element of tasks.querySelectorAll(
|
const row of tasks.querySelectorAll(
|
||||||
':scope > :not(form, div[id="title"])',
|
//':scope > :not(form, div[id="title"])',
|
||||||
|
':scope > div[data-row="task"]',
|
||||||
)
|
)
|
||||||
) element.remove();
|
) row.remove();
|
||||||
|
|
||||||
// Сброс статуса инициализированности
|
// Сброс статуса инициализированности
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
|
@ -582,10 +593,10 @@ if (typeof window.tasks !== "function") {
|
||||||
*
|
*
|
||||||
* @param {number} page Страница
|
* @param {number} page Страница
|
||||||
*
|
*
|
||||||
* @return {object} {(bool) exist, (array) errors}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
static read = damper(async (page) => {
|
static read = damper(async (page) => {
|
||||||
if (typeof core === "function" && typeof page !== "number") {
|
if (typeof page !== "number") {
|
||||||
// Не получена страница
|
// Не получена страница
|
||||||
|
|
||||||
// Инициализация страницы (если не получена, то брать из cookie и прибавлять 1)
|
// Инициализация страницы (если не получена, то брать из cookie и прибавлять 1)
|
||||||
|
@ -596,7 +607,7 @@ if (typeof window.tasks !== "function") {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Запрос к серверу
|
// Запрос к серверу
|
||||||
return await fetch("/tasks/read", {
|
await fetch("/tasks/read", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
@ -614,8 +625,11 @@ if (typeof window.tasks !== "function") {
|
||||||
// Запись в документ HTML-данных через буфер
|
// Запись в документ HTML-данных через буфер
|
||||||
element.outerHTML = data;
|
element.outerHTML = data;
|
||||||
|
|
||||||
// Возврат (успех)
|
// Запуск реинициализатора строк
|
||||||
return data;
|
this.reinitializer.start();
|
||||||
|
|
||||||
|
// Вызов события: "итерация чтения завершена"
|
||||||
|
document.dispatchEvent(new CustomEvent("tasks.read." + page));
|
||||||
});
|
});
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
||||||
|
@ -966,7 +980,7 @@ if (typeof window.tasks !== "function") {
|
||||||
})
|
})
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
// Инициализация буффера списка классов
|
// Инициализация буфера списка классов
|
||||||
const buffer = [...row.classList];
|
const buffer = [...row.classList];
|
||||||
|
|
||||||
// Реинициализация строки
|
// Реинициализация строки
|
||||||
|
@ -1040,7 +1054,7 @@ if (typeof window.tasks !== "function") {
|
||||||
})
|
})
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
// Инициализация буффера списка классов
|
// Инициализация буфера списка классов
|
||||||
const buffer = [...row.classList];
|
const buffer = [...row.classList];
|
||||||
|
|
||||||
// Реинициализация строки
|
// Реинициализация строки
|
||||||
|
@ -1239,7 +1253,7 @@ if (typeof window.tasks !== "function") {
|
||||||
if (data.writed) {
|
if (data.writed) {
|
||||||
// Записано новое значение в базу данных
|
// Записано новое значение в базу данных
|
||||||
|
|
||||||
// Инициализация буффера списка классов
|
// Инициализация буфера списка классов
|
||||||
const buffer = [...row.classList];
|
const buffer = [...row.classList];
|
||||||
|
|
||||||
// Реинициализация строки в документе
|
// Реинициализация строки в документе
|
||||||
|
@ -1323,7 +1337,7 @@ if (typeof window.tasks !== "function") {
|
||||||
if (data.writed) {
|
if (data.writed) {
|
||||||
// Записано новое значение в базу данных
|
// Записано новое значение в базу данных
|
||||||
|
|
||||||
// Инициализация буффера списка классов
|
// Инициализация буфера списка классов
|
||||||
const buffer = [...row.classList];
|
const buffer = [...row.classList];
|
||||||
|
|
||||||
// Реинициализация строки в документе
|
// Реинициализация строки в документе
|
||||||
|
@ -1800,7 +1814,7 @@ if (typeof window.tasks !== "function") {
|
||||||
// Инициализация кнопки замены
|
// Инициализация кнопки замены
|
||||||
const publish = document.createElement("button");
|
const publish = document.createElement("button");
|
||||||
publish.classList.add("sea");
|
publish.classList.add("sea");
|
||||||
publish.innerText = "Опубликовать для поиска";
|
publish.innerText = "Опубликовать";
|
||||||
publish.setAttribute(
|
publish.setAttribute(
|
||||||
"onclick",
|
"onclick",
|
||||||
`tasks.worker.publish(document.getElementById('${task}'), this)`,
|
`tasks.worker.publish(document.getElementById('${task}'), this)`,
|
||||||
|
@ -1997,7 +2011,7 @@ if (typeof window.tasks !== "function") {
|
||||||
if (data.updated) {
|
if (data.updated) {
|
||||||
// Записано обновление
|
// Записано обновление
|
||||||
|
|
||||||
// Инициализация буффера списка классов
|
// Инициализация буфера списка классов
|
||||||
const buffer = [...row.classList];
|
const buffer = [...row.classList];
|
||||||
|
|
||||||
// Реинициализация строки
|
// Реинициализация строки
|
||||||
|
@ -2075,16 +2089,13 @@ if (typeof window.tasks !== "function") {
|
||||||
|
|
||||||
if (this.errors(data.errors)) {
|
if (this.errors(data.errors)) {
|
||||||
// Сгенерированы ошибки
|
// Сгенерированы ошибки
|
||||||
|
|
||||||
// Разблокировка полей ввода и кнопок
|
|
||||||
unblock();
|
|
||||||
} else {
|
} else {
|
||||||
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
||||||
|
|
||||||
if (data.updated) {
|
if (data.updated) {
|
||||||
// Записано обновление
|
// Записано обновление
|
||||||
|
|
||||||
// Инициализация буффера списка классов
|
// Инициализация буфера списка классов
|
||||||
const buffer = [...row.classList];
|
const buffer = [...row.classList];
|
||||||
|
|
||||||
// Реинициализация строки
|
// Реинициализация строки
|
||||||
|
@ -2107,6 +2118,194 @@ if (typeof window.tasks !== "function") {
|
||||||
}
|
}
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Опубликовать
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} row Строка
|
||||||
|
* @param {HTMLElement} button Кнопка
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
static publish(row, button) {
|
||||||
|
// Запуск выполнения
|
||||||
|
this._publish(row, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Опубликовать (системное)
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} row Строка
|
||||||
|
* @param {HTMLElement} button Кнопка
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
static _publish = damper(async (row, button) => {
|
||||||
|
if (
|
||||||
|
row instanceof HTMLElement &&
|
||||||
|
button instanceof HTMLElement
|
||||||
|
) {
|
||||||
|
// Получена строка и кнопка
|
||||||
|
|
||||||
|
// Инициализация идентификатора строки
|
||||||
|
const id = row.getAttribute("id");
|
||||||
|
|
||||||
|
if (typeof id === "string") {
|
||||||
|
// Инициализирован идентификатор
|
||||||
|
|
||||||
|
// Запуск отсрочки разблокировки на случай, если сервер не отвечает
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
this.errors(["Сервер не отвечает"]);
|
||||||
|
unblock();
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
// Запрос к серверу
|
||||||
|
return await fetch(`/task/${id}/publish`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
// Удаление отсрочки разблокировки
|
||||||
|
clearTimeout(timeout);
|
||||||
|
|
||||||
|
if (this.errors(data.errors)) {
|
||||||
|
// Сгенерированы ошибки
|
||||||
|
} else {
|
||||||
|
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
||||||
|
|
||||||
|
if (data.published) {
|
||||||
|
// Опубликована заявка
|
||||||
|
|
||||||
|
// Инициализация буфера списка классов
|
||||||
|
const buffer = [...row.classList];
|
||||||
|
|
||||||
|
// Инициализация идентификатора строки
|
||||||
|
const id = row.getAttribute("id");
|
||||||
|
|
||||||
|
// Реинициализация строки
|
||||||
|
row.outerHTML = data.row;
|
||||||
|
|
||||||
|
// Реинициализация строки (выражение странное, но правильное)
|
||||||
|
row = document.getElementById(id);
|
||||||
|
|
||||||
|
// Копирование классов из буфера классов удалённой строки и добавление соответствующего
|
||||||
|
row.classList.add(...buffer, "published");
|
||||||
|
|
||||||
|
// Запись текста состояния кнопки
|
||||||
|
button.innerText = "Снять с публикации";
|
||||||
|
|
||||||
|
// Реинициализация стиля кнопки
|
||||||
|
button.classList.remove("sea");
|
||||||
|
button.classList.add("clay");
|
||||||
|
|
||||||
|
// Инициализация вызова функции: "снять с публикации"
|
||||||
|
button.setAttribute(
|
||||||
|
"onclick",
|
||||||
|
`tasks.worker.unpublish(document.getElementById('${id}'), this)`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Снять с публикации
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} row Строка
|
||||||
|
* @param {HTMLElement} button Кнопка
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
static unpublish(row, button) {
|
||||||
|
// Запуск выполнения
|
||||||
|
this._unpublish(row, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Снять с публикации (системное)
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} row Строка
|
||||||
|
* @param {HTMLElement} button Кнопка
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
static _unpublish = damper(async (row, button) => {
|
||||||
|
if (
|
||||||
|
row instanceof HTMLElement &&
|
||||||
|
button instanceof HTMLElement
|
||||||
|
) {
|
||||||
|
// Получена строка и кнопка
|
||||||
|
|
||||||
|
// Инициализация идентификатора строки
|
||||||
|
const id = row.getAttribute("id");
|
||||||
|
|
||||||
|
if (typeof id === "string") {
|
||||||
|
// Инициализирован идентификатор
|
||||||
|
|
||||||
|
// Запуск отсрочки разблокировки на случай, если сервер не отвечает
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
this.errors(["Сервер не отвечает"]);
|
||||||
|
unblock();
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
// Запрос к серверу
|
||||||
|
return await fetch(`/task/${id}/unpublish`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
// Удаление отсрочки разблокировки
|
||||||
|
clearTimeout(timeout);
|
||||||
|
|
||||||
|
if (this.errors(data.errors)) {
|
||||||
|
// Сгенерированы ошибки
|
||||||
|
} else {
|
||||||
|
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
||||||
|
|
||||||
|
if (data.unpublished) {
|
||||||
|
// Снята с публикации заявка
|
||||||
|
|
||||||
|
// Инициализация буфера списка классов
|
||||||
|
const buffer = [...row.classList];
|
||||||
|
|
||||||
|
// Реинициализация строки
|
||||||
|
row.outerHTML = data.row;
|
||||||
|
|
||||||
|
// Реинициализация строки (выражение странное, но правильное)
|
||||||
|
row = document.getElementById(row.getAttribute("id"));
|
||||||
|
|
||||||
|
// Копирование классов из буфера классов удалённой строки и добавление соответствующего
|
||||||
|
row.classList.add(...buffer, "published");
|
||||||
|
|
||||||
|
// Удаление класса неактуального состояния
|
||||||
|
row.classList.remove("published");
|
||||||
|
|
||||||
|
// Запись текста состояния кнопки
|
||||||
|
button.innerText = "Опубликовать";
|
||||||
|
|
||||||
|
// Реинициализация стиля кнопки
|
||||||
|
button.classList.remove("clay");
|
||||||
|
button.classList.add("sea");
|
||||||
|
|
||||||
|
// Инициализация вызова функции: "опубликовать"
|
||||||
|
button.setAttribute(
|
||||||
|
"onclick",
|
||||||
|
`tasks.worker.publish(document.getElementById('${id}'), this)`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Сгенерировать HTML-элемент со списком ошибок
|
* Сгенерировать HTML-элемент со списком ошибок
|
||||||
*
|
*
|
||||||
|
@ -2662,7 +2861,7 @@ if (typeof window.tasks !== "function") {
|
||||||
if (data.updated) {
|
if (data.updated) {
|
||||||
// Записано обновление
|
// Записано обновление
|
||||||
|
|
||||||
// Инициализация буффера списка классов
|
// Инициализация буфера списка классов
|
||||||
const buffer = [...row.classList];
|
const buffer = [...row.classList];
|
||||||
|
|
||||||
// Реинициализация строки
|
// Реинициализация строки
|
||||||
|
@ -2694,7 +2893,6 @@ if (typeof window.tasks !== "function") {
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
static remove(row, button) {
|
static remove(row, button) {
|
||||||
console.log("bebre", this);
|
|
||||||
// Запуск выполнения
|
// Запуск выполнения
|
||||||
this._remove(row, button);
|
this._remove(row, button);
|
||||||
}
|
}
|
||||||
|
@ -2747,7 +2945,7 @@ if (typeof window.tasks !== "function") {
|
||||||
if (data.updated) {
|
if (data.updated) {
|
||||||
// Записано обновление
|
// Записано обновление
|
||||||
|
|
||||||
// Инициализация буффера списка классов
|
// Инициализация буфера списка классов
|
||||||
const buffer = [...row.classList];
|
const buffer = [...row.classList];
|
||||||
|
|
||||||
// Реинициализация строки
|
// Реинициализация строки
|
||||||
|
@ -3079,7 +3277,7 @@ if (typeof window.tasks !== "function") {
|
||||||
// Удаление анимации ошибки
|
// Удаление анимации ошибки
|
||||||
textarea.classList.remove("error");
|
textarea.classList.remove("error");
|
||||||
|
|
||||||
// Инициализация буффера списка классов
|
// Инициализация буфера списка классов
|
||||||
const buffer = [...row.classList];
|
const buffer = [...row.classList];
|
||||||
|
|
||||||
// Реинициализация строки
|
// Реинициализация строки
|
||||||
|
@ -3101,12 +3299,128 @@ if (typeof window.tasks !== "function") {
|
||||||
}
|
}
|
||||||
}, 300);
|
}, 300);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static reinitializer = class {
|
||||||
|
/**
|
||||||
|
* Ссылка на ядро (родительский класс)
|
||||||
|
*/
|
||||||
|
static core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Запустить
|
||||||
|
*
|
||||||
|
* @param {HTMLElement|null} target Строка
|
||||||
|
*/
|
||||||
|
static start(target) {
|
||||||
|
// Инициализация оболочки
|
||||||
|
const tasks = document.getElementById("tasks");
|
||||||
|
|
||||||
|
for (
|
||||||
|
const row of typeof target === "undefined"
|
||||||
|
? tasks.querySelectorAll(':scope > div[data-row="task"]')
|
||||||
|
: [target]
|
||||||
|
) {
|
||||||
|
// Перебор строк
|
||||||
|
|
||||||
|
// Инициализация номера итерации по умолчанию
|
||||||
|
if (typeof row.counter === "undefined") {
|
||||||
|
// Не инициализирован счётчик итерации
|
||||||
|
|
||||||
|
row.counter = Math.floor(Math.random() * 280 + 20);
|
||||||
|
row.style.setProperty("--counter", '"' + row.counter + '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Инициализация самообновления
|
||||||
|
if (typeof row.updater === "undefined") {
|
||||||
|
// Не инициализирована функция самообновления
|
||||||
|
|
||||||
|
row.updater = setInterval(
|
||||||
|
() => {
|
||||||
|
if (--row.counter <= 0) {
|
||||||
|
// Отсчёт таймера завершён
|
||||||
|
|
||||||
|
// Блокировка строки
|
||||||
|
|
||||||
|
// Деинициализация реинициализатора строки (для защиты от повторного запроса)
|
||||||
|
this.stop(row);
|
||||||
|
|
||||||
|
// Запись анимации (запуск)
|
||||||
|
row.classList.add("reinitialized");
|
||||||
|
|
||||||
|
// Запрос к серверу
|
||||||
|
fetch("/tasks/read", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
},
|
||||||
|
body: `row=${row.getAttribute("id")}`,
|
||||||
|
})
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((data) => {
|
||||||
|
// Инициализация идентифиатора
|
||||||
|
const id = row.getAttribute("id");
|
||||||
|
|
||||||
|
// Реинициализация строки
|
||||||
|
row.outerHTML = data;
|
||||||
|
|
||||||
|
// Инициализация перезаписанной строки
|
||||||
|
const _row = document.getElementById(id);
|
||||||
|
|
||||||
|
// Инициализация реинициализатора строки (для пересчёта таймера для setInterval)
|
||||||
|
if (_row instanceof HTMLElement) {
|
||||||
|
setTimeout(() => this.start(_row), 5000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {row.style.setProperty(
|
||||||
|
"--counter",
|
||||||
|
'"' + row.counter + '"',
|
||||||
|
);}
|
||||||
|
},
|
||||||
|
Math.floor(
|
||||||
|
Math.random() * tasks.querySelectorAll(
|
||||||
|
':scope > div[data-row="task"]',
|
||||||
|
).length *
|
||||||
|
200 + 300,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Остановить
|
||||||
|
*
|
||||||
|
* @param {HTMLElement|null} target Строка
|
||||||
|
*/
|
||||||
|
static stop(target) {
|
||||||
|
// Инициализация оболочки
|
||||||
|
const tasks = document.getElementById("tasks");
|
||||||
|
|
||||||
|
for (
|
||||||
|
const row of typeof target === "undefined"
|
||||||
|
? tasks.querySelectorAll(':scope > div[data-row="task"]')
|
||||||
|
: [target]
|
||||||
|
) {
|
||||||
|
// Перебор строк
|
||||||
|
|
||||||
|
// Деинициализация самообновления
|
||||||
|
clearInterval(row.updater);
|
||||||
|
|
||||||
|
// Удаление идентификатора
|
||||||
|
row.updater = row.counter = undefined;
|
||||||
|
|
||||||
|
// Удаление анимации (сброс)
|
||||||
|
row.classList.remove("reinitialized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Инициализация ссылок на ядро
|
// Инициализация ссылок на ядро
|
||||||
window.tasks.worker.core =
|
window.tasks.worker.core =
|
||||||
window.tasks.market.core =
|
window.tasks.market.core =
|
||||||
window.tasks.commentary.core =
|
window.tasks.commentary.core =
|
||||||
|
window.tasks.reinitializer.core =
|
||||||
window.tasks;
|
window.tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
{% if page != null %}<!-- PAGE #{{ page }} -->{% endif %}
|
||||||
|
{% for row in rows %}
|
||||||
|
<div id="{{ row.account._key }}" class="row {{ row.account.status }}" data-row="administrator">
|
||||||
|
<span data-column="id" title="{{ row.account._key }}" onclick="administrators.administrator.popup(this.parentElement)">{{
|
||||||
|
row.account._key }}</span>
|
||||||
|
<span data-column="name"
|
||||||
|
title="{% if row.account.name.first is not empty %}{{ row.account.name.first }}{% endif %}{% if row.account.name.second is not empty %} {{ row.account.name.second }}{% endif %}{% if row.account.name.last is not empty %} {{ row.account.name.last }}{% endif %}"
|
||||||
|
onclick="administrators.administrator.popup(this.parentElement)">{% if row.account.name.first is not empty %}{{
|
||||||
|
row.account.name.first|slice(0, 1)|upper }}.{% endif %}{% if row.account.name.last is not empty %} {{
|
||||||
|
row.account.name.last|slice(0, 1)|upper }}.{% endif %}{% if row.account.name.second is not empty %} {{
|
||||||
|
row.account.name.second }}{% endif %}</span>
|
||||||
|
<span data-column="number" onclick="administrators.administrator.popup(this.parentElement)">{{ row.account.number }}</span>
|
||||||
|
<span data-column="mail" onclick="administrators.administrator.popup(this.parentElement)">{{ row.account.mail }}</span>
|
||||||
|
<span data-column="requisites" onclick="administrators.administrator.popup(this.parentElement)">{{ row.account.requisites }} {{
|
||||||
|
row.account.payment }}</span>
|
||||||
|
<span data-column="commentary" title="{{ row.account.commentary }}"
|
||||||
|
onclick="administrators.commentary.popup(this.parentElement)">{{ row.account.commentary }}</span>
|
||||||
|
<span data-column="status" title="Непрочитанные сообщения" onclick="administrators.status(this.parentElement)">{{
|
||||||
|
row.account.status }}</span>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
|
@ -1,10 +1,10 @@
|
||||||
{% if page != null %}<!-- PAGE #{{ page }} -->{% endif %}
|
{% if page != null %}<!-- PAGE #{{ page }} -->{% endif %}
|
||||||
{% for row in rows %}
|
{% for row in rows %}
|
||||||
<div id="{{ row.market._key }}" class="row {{ row.market.status }}">
|
<div id="{{ row.market._key }}" class="row {{ row.market.status }}" data-row="market">
|
||||||
<span data-column="id" title="{{ row.market.id }}" onclick="markets.market.popup(this.parentElement)">{{
|
<span data-column="id" title="{{ row.market.id }}" onclick="markets.market.popup(this.parentElement)">{{
|
||||||
row.market.id }}</span>
|
row.market.id }}</span>
|
||||||
<span data-column="director" title="{{ row.market.director }}" onclick="markets.market.popup(this.parentElement)">{{
|
<span data-column="director" title="{% if row.market.director.first is not empty %}{{ row.market.director.first }}{% endif %}{% if row.market.director.second is not empty %} {{ row.market.director.second }}{% endif %}{% if row.market.director.last is not empty %} {{ row.market.director.last }}{% endif %}" onclick="markets.market.popup(this.parentElement)">{% if row.market.director.first is not empty %}{{ row.market.director.first|slice(0, 1)|upper }}.{% endif %}{% if row.market.director.last is not empty %} {{ row.market.director.last|slice(0, 1)|upper }}.{% endif %}{% if row.market.director.second is not empty %} {{ row.market.director.second }}{% endif %}</span>
|
||||||
row.market.director }}</span>
|
<span data-column="number" onclick="operators.market.popup(this.parentElement)">{{ row.market.number }}</span>
|
||||||
<span data-column="address" title="{{ row.market.city }} {{ row.market.district }} {{ row.market.address }}"
|
<span data-column="address" title="{{ row.market.city }} {{ row.market.district }} {{ row.market.address }}"
|
||||||
onclick="markets.market.popup(this.parentElement)">{{ row.market.city }} {{ row.market.district }} {{
|
onclick="markets.market.popup(this.parentElement)">{{ row.market.city }} {{ row.market.district }} {{
|
||||||
row.market.address }}</span>
|
row.market.address }}</span>
|
||||||
|
|
|
@ -1,24 +1,21 @@
|
||||||
{% if page != null %}<!-- PAGE #{{ page }} -->{% endif %}
|
{% if page != null %}<!-- PAGE #{{ page }} -->{% endif %}
|
||||||
{% for row in rows %}
|
{% for row in rows %}
|
||||||
<div id="{{ row.operator._key }}" class="row {{ row.operator.status }}">
|
<div id="{{ row.account._key }}" class="row {{ row.account.status }}" data-row="operator">
|
||||||
<span data-column="id" title="{{ row.operator.id }}" onclick="operators.operator.popup(this.parentElement)">{{
|
<span data-column="id" title="{{ row.account._key }}" onclick="operators.operator.popup(this.parentElement)">{{
|
||||||
row.operator.id }}</span>
|
row.account._key }}</span>
|
||||||
<span data-column="name" title="{{ row.operator.name }}" onclick="operators.operator.popup(this.parentElement)">{{
|
<span data-column="name"
|
||||||
row.operator.name }}</span>
|
title="{% if row.account.name.first is not empty %}{{ row.account.name.first }}{% endif %}{% if row.account.name.second is not empty %} {{ row.account.name.second }}{% endif %}{% if row.account.name.last is not empty %} {{ row.account.name.last }}{% endif %}"
|
||||||
<span data-column="birth" onclick="operators.operator.popup(this.parentElement)">{{ row.operator.birth }}</span>
|
onclick="operators.operator.popup(this.parentElement)">{% if row.account.name.first is not empty %}{{
|
||||||
<span data-column="number" onclick="operators.operator.popup(this.parentElement)">{{ row.operator.number }}</span>
|
row.account.name.first|slice(0, 1)|upper }}.{% endif %}{% if row.account.name.last is not empty %} {{
|
||||||
<span data-column="passport" title="{{ row.operator.passport }} {{ row.operator.department }} {{ row.operator.issued }}"
|
row.account.name.last|slice(0, 1)|upper }}.{% endif %}{% if row.account.name.second is not empty %} {{
|
||||||
onclick="operators.operator.popup(this.parentElement)">{{ row.operator.passport }} {{ row.operator.department }} {{
|
row.account.name.second }}{% endif %}</span>
|
||||||
row.operator.issued }}</span>
|
<span data-column="number" onclick="operators.operator.popup(this.parentElement)">{{ row.account.number }}</span>
|
||||||
<span data-column="address" title="{{ row.operator.city }} {{ row.operator.district }} {{ row.operator.address }}"
|
<span data-column="mail" onclick="operators.operator.popup(this.parentElement)">{{ row.account.mail }}</span>
|
||||||
onclick="operators.operator.popup(this.parentElement)">{{ row.operator.city }} {{ row.operator.district }} {{
|
<span data-column="requisites" onclick="operators.operator.popup(this.parentElement)">{{ row.account.requisites }} {{
|
||||||
row.operator.address }}</span>
|
row.account.payment }}</span>
|
||||||
<span data-column="tax" onclick="operators.operator.popup(this.parentElement)">{{ row.operator.tax }}</span>
|
<span data-column="commentary" title="{{ row.account.commentary }}"
|
||||||
<span data-column="requisites" onclick="operators.operator.popup(this.parentElement)">{{ row.operator.requisites }} {{
|
onclick="operators.commentary.popup(this.parentElement)">{{ row.account.commentary }}</span>
|
||||||
row.operator.payment }}</span>
|
|
||||||
<span data-column="commentary" title="{{ row.operator.commentary }}"
|
|
||||||
onclick="operators.commentary.popup(this.parentElement)">{{ row.operator.commentary }}</span>
|
|
||||||
<span data-column="status" title="Непрочитанные сообщения" onclick="operators.status(this.parentElement)">{{
|
<span data-column="status" title="Непрочитанные сообщения" onclick="operators.status(this.parentElement)">{{
|
||||||
row.operator.status }}</span>
|
row.account.status }}</span>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
{% if page != null %}<!-- PAGE #{{ page }} -->{% endif %}
|
{% if page != null %}<!-- PAGE #{{ page }} -->{% endif %}
|
||||||
{% for row in rows %}
|
{% for row in rows %}
|
||||||
<div id="{{ row.task._key }}"
|
<div id="{{ row.task._key }}" style="--columns: 12;"
|
||||||
class="row{% if row.task.confirmed %} confirmed{% endif %}{% if row.task.hided %} hided{% endif %}">
|
class="row reinitializable{% if row.task.confirmed %} confirmed{% endif %}{% if row.task.published %} published{% endif %}{% if row.task.hided %} hided{% endif %}" data-row="task">
|
||||||
<span data-column="date" title="Заявка создана: {{ row.task.created is empty ? 'Никогда' :
|
<span data-column="date" title="Заявка создана: {{ row.task.created is empty ? 'Никогда' :
|
||||||
row.task.created|date('Y.m.d h:i:s') }}; Заявка обновлена: {{ row.task.updated is empty ? 'Никогда' :
|
row.task.created|date('Y.m.d h:i:s') }}; Заявка обновлена: {{ row.task.updated is empty ? 'Никогда' :
|
||||||
row.task.updated|date('Y.m.d h:i:s') }}" onclick="tasks.popup(this.parentElement)">{{ row.task.date|date('d.m.Y')
|
row.task.updated|date('Y.m.d h:i:s') }}" onclick="tasks.popup(this.parentElement)">{{ row.task.date|date('d.m.Y')
|
||||||
}}</span>
|
}}</span>
|
||||||
<span data-column="worker" title="{{ row.worker.id }}" onclick="tasks.worker.popup(this.parentElement)">{{
|
<span data-column="worker" title="{{ row.worker.id }}" onclick="tasks.worker.popup(this.parentElement)">{{
|
||||||
row.worker.id }}</span>
|
row.worker.id }}</span>
|
||||||
<span data-column="name" title="{{ row.worker.name }}" onclick="tasks.worker.popup(this.parentElement)">{{
|
<span data-column="name" title="{% if row.worker.name.first is not empty %}{{ row.worker.name.first }}{% endif %}{% if row.worker.name.second is not empty %} {{ row.worker.name.second }}{% endif %}{% if row.worker.name.last is not empty %} {{ row.worker.name.last }}{% endif %}" onclick="tasks.worker.popup(this.parentElement)">{% if row.worker.name.first is not empty %}{{ row.worker.name.first|slice(0, 1)|upper }}.{% endif %}{% if row.worker.name.last is not empty %} {{ row.worker.name.last|slice(0, 1)|upper }}.{% endif %}{% if row.worker.name.second is not empty %} {{ row.worker.name.second }}{% endif %}</span>
|
||||||
row.worker.name }}</span>
|
|
||||||
<span data-column="task" title="{{ row.task.description }}" onclick="tasks.popup(this.parentElement)">{{ row.task.work
|
<span data-column="task" title="{{ row.task.description }}" onclick="tasks.popup(this.parentElement)">{{ row.task.work
|
||||||
}}</span>
|
}}</span>
|
||||||
<span data-column="start" onclick="tasks.popup(this.parentElement)">{{
|
<span data-column="start" onclick="tasks.popup(this.parentElement)">{{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% if page != null %}<!-- PAGE #{{ page }} -->{% endif %}
|
{% if page != null %}<!-- PAGE #{{ page }} -->{% endif %}
|
||||||
{% for row in rows %}
|
{% for row in rows %}
|
||||||
<div id="{{ row.worker._key }}" class="row {{ row.worker.status }}">
|
<div id="{{ row.worker._key }}" class="row {{ row.worker.status }}" data-row="worker">
|
||||||
<span data-column="id" title="{{ row.worker.id }}" onclick="workers.worker.popup(this.parentElement)">{{
|
<span data-column="id" title="{{ row.worker.id }}" onclick="workers.worker.popup(this.parentElement)">{{
|
||||||
row.worker.id }}</span>
|
row.worker.id }}</span>
|
||||||
<span data-column="name" title="{% if row.worker.name.first is not empty %}{{ row.worker.name.first }}{% endif %}{% if row.worker.name.second is not empty %} {{ row.worker.name.second }}{% endif %}{% if row.worker.name.last is not empty %} {{ row.worker.name.last }}{% endif %}" onclick="workers.worker.popup(this.parentElement)">{% if row.worker.name.first is not empty %}{{ row.worker.name.first|slice(0, 1)|upper }}.{% endif %}{% if row.worker.name.last is not empty %} {{ row.worker.name.last|slice(0, 1)|upper }}.{% endif %}{% if row.worker.name.second is not empty %} {{ row.worker.name.second }}{% endif %}</span>
|
<span data-column="name" title="{% if row.worker.name.first is not empty %}{{ row.worker.name.first }}{% endif %}{% if row.worker.name.second is not empty %} {{ row.worker.name.second }}{% endif %}{% if row.worker.name.last is not empty %} {{ row.worker.name.last }}{% endif %}" onclick="workers.worker.popup(this.parentElement)">{% if row.worker.name.first is not empty %}{{ row.worker.name.first|slice(0, 1)|upper }}.{% endif %}{% if row.worker.name.last is not empty %} {{ row.worker.name.last|slice(0, 1)|upper }}.{% endif %}{% if row.worker.name.second is not empty %} {{ row.worker.name.second }}{% endif %}</span>
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
{% extends('index.html') %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
<link type="text/css" rel="stylesheet" data-reinitializer-once="true" href="/css/list.css">
|
||||||
|
<link type="text/css" rel="stylesheet" data-reinitializer-once="true" href="/css/pages/administrators.css">
|
||||||
|
<link type="text/css" rel="stylesheet" data-reinitializer-once="true" href="/css/icons/user.css">
|
||||||
|
<link type="text/css" rel="stylesheet" data-reinitializer-once="true" href="/css/icons/user_add.css">
|
||||||
|
<link type="text/css" rel="stylesheet" data-reinitializer-once="true" href="/css/icons/work_alt.css">
|
||||||
|
<link type="text/css" rel="stylesheet" data-reinitializer-once="true" href="/css/icons/home.css">
|
||||||
|
<link type="text/css" rel="stylesheet" data-reinitializer-once="true" href="/css/icons/timer.css">
|
||||||
|
<link type="text/css" rel="stylesheet" data-reinitializer-once="true" href="/css/icons/shopping_cart.css">
|
||||||
|
<link type="text/css" rel="stylesheet" data-reinitializer-once="true" href="/css/icons/search.css">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<section id="administrators" class="panel medium list">
|
||||||
|
<form id="actions" class="row menu separated" onsubmit="return false">
|
||||||
|
<label for="actions">
|
||||||
|
{% if account.type == 'administrator' or account.type == 'administrator' or account.type == 'administrator' %}
|
||||||
|
<button class="grass" onclick="administrators.create()">Создать</button>
|
||||||
|
{% endif %}
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
<form id="filters" class="row menu stretched" onsubmit="return false">
|
||||||
|
<label for="filters">
|
||||||
|
<button class="{{ active ?? 'earth' }}" onclick="administrators.filter('active', null, this); administrators.reinit()" {% if
|
||||||
|
active=='sand' %}title="... и активные" {% elseif active=='river' %}title="... или активные" {% endif
|
||||||
|
%}>Активный</button>
|
||||||
|
<button class="{{ inactive ?? 'earth' }}" onclick="administrators.filter('inactive', null, this); administrators.reinit()" {% if
|
||||||
|
inactive=='sand' %}title="... и неактивные" {% elseif inactive=='river' %}title="... или неактивные" {% endif
|
||||||
|
%}>Неактивный</button>
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
<form class="row menu wide stretched" onsubmit="return false">
|
||||||
|
<label class="solid">
|
||||||
|
<i class="icon search"></i>
|
||||||
|
<input class="clue merged right" type="search" name="search" id="search"
|
||||||
|
placeholder="Глобальный поиск по администраторам" />
|
||||||
|
<button class="sea merged left" onclick="administrators.search(this.previousSiblingElement, this)">Поиск</button>
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
<div id="title" class="row unselectable">
|
||||||
|
<span data-column="id" class="button" title="Идентификатор"><i class="icon bold user"></i></span>
|
||||||
|
<span data-column="name" class="button">ФИО</span>
|
||||||
|
<span data-column="number" class="button">Номер</span>
|
||||||
|
<span data-column="mail" class="button">Почта</span>
|
||||||
|
<span data-column="commentary" class="button">Комментарий</span>
|
||||||
|
<span data-column="status" class="button">Статус</span>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<script data-reinitializer-once="true">
|
||||||
|
if (typeof window.administrators_main_initialized === 'undefined') {
|
||||||
|
// Не выполнялся скрипт
|
||||||
|
|
||||||
|
document.addEventListener('administrators.initialized', (e) => {
|
||||||
|
// Инициализированы администраторы
|
||||||
|
|
||||||
|
// Инициализация допустимой страницы для выполнения
|
||||||
|
e.detail.administrators.page = 'administrators';
|
||||||
|
|
||||||
|
// Инициализация страниц
|
||||||
|
e.detail.administrators.init();
|
||||||
|
|
||||||
|
// Блокировка от повторного выполнения
|
||||||
|
window.administrators_main_initialized = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script data-reinitializer-once="true">
|
||||||
|
if (typeof window.administrators_scroll_initialized === 'undefined') {
|
||||||
|
// Не выполнялся скрипт
|
||||||
|
|
||||||
|
window.onscroll = function(e) {
|
||||||
|
// Инициализация чтения новых задач при достижения конца страницы
|
||||||
|
|
||||||
|
if (core.page === 'administrators') {
|
||||||
|
// Инициализирована требуемая для выполнения страница
|
||||||
|
|
||||||
|
if ((window.innerHeight + Math.round(window.scrollY)) >= document.body.offsetHeight) administrators.read();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Блокировка от повторного выполнения
|
||||||
|
window.administrators_scroll_initialized = true;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
<script type="text/javascript" data-reinitializer-once="true" src="/js/imask-7.1.0-alpha.js" defer></script>
|
||||||
|
<script type="text/javascript" src="/js/administrators.js" defer></script>
|
||||||
|
{% endblock %}
|
|
@ -42,6 +42,7 @@
|
||||||
<div id="title" class="row unselectable">
|
<div id="title" class="row unselectable">
|
||||||
<span data-column="id" class="button" title="Идентификатор"><i class="icon bold user"></i></span>
|
<span data-column="id" class="button" title="Идентификатор"><i class="icon bold user"></i></span>
|
||||||
<span data-column="director" class="button">Директор</span>
|
<span data-column="director" class="button">Директор</span>
|
||||||
|
<span data-column="number" class="button">Номер</span>
|
||||||
<span data-column="address" class="button">Адрес</span>
|
<span data-column="address" class="button">Адрес</span>
|
||||||
<span data-column="type" class="button">Тип</span>
|
<span data-column="type" class="button">Тип</span>
|
||||||
<span data-column="commentary" class="button">Комментарий</span>
|
<span data-column="commentary" class="button">Комментарий</span>
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
<div id="title" class="row unselectable">
|
<div id="title" class="row unselectable">
|
||||||
<span data-column="id" class="button" title="Идентификатор"><i class="icon bold user"></i></span>
|
<span data-column="id" class="button" title="Идентификатор"><i class="icon bold user"></i></span>
|
||||||
<span data-column="name" class="button">ФИО</span>
|
<span data-column="name" class="button">ФИО</span>
|
||||||
<span data-column="number" class="button">Адрес</span>
|
<span data-column="number" class="button">Номер</span>
|
||||||
<span data-column="mail" class="button">Тип</span>
|
<span data-column="mail" class="button">Почта</span>
|
||||||
<span data-column="commentary" class="button">Комментарий</span>
|
<span data-column="commentary" class="button">Комментарий</span>
|
||||||
<span data-column="status" class="button">Статус</span>
|
<span data-column="status" class="button">Статус</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -48,8 +48,8 @@
|
||||||
confirmed=='sand' %}title="... и подтверждённые" {% elseif confirmed=='river'
|
confirmed=='sand' %}title="... и подтверждённые" {% elseif confirmed=='river'
|
||||||
%}title="... или подтверждённые" {% endif %}>Подтверждён</button>
|
%}title="... или подтверждённые" {% endif %}>Подтверждён</button>
|
||||||
<button class="{{ waiting ?? 'earth' }}" onclick="tasks.filter('waiting', null, this); tasks.reinit()" {% if
|
<button class="{{ waiting ?? 'earth' }}" onclick="tasks.filter('waiting', null, this); tasks.reinit()" {% if
|
||||||
waiting=='sand' %}title="... и ожидающие" {% elseif waiting=='river' %}title="... или ожидающие"
|
waiting=='sand' %}title="... и неподтверждённые" {% elseif waiting=='river' %}title="... или неподтверждённые"
|
||||||
{% endif %}>Ожидает</button>
|
{% endif %}>Неподтверждён</button>
|
||||||
<button class="{{ published ?? 'earth' }}" onclick="tasks.filter('published', null, this); tasks.reinit()" {% if
|
<button class="{{ published ?? 'earth' }}" onclick="tasks.filter('published', null, this); tasks.reinit()" {% if
|
||||||
published=='sand' %}title="... и опубликованные" {% elseif published=='river'
|
published=='sand' %}title="... и опубликованные" {% elseif published=='river'
|
||||||
%}title="... или" {% endif %}>Опубликован</button>
|
%}title="... или" {% endif %}>Опубликован</button>
|
||||||
|
|
Reference in New Issue