This commit is contained in:
parent
4c6e5cdd1d
commit
26eced8fed
|
@ -268,4 +268,106 @@ final class account extends core
|
|||
// Возврат (провал)
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Пометить заблокированным
|
||||
*
|
||||
* @param array $parameters Параметры запроса
|
||||
*/
|
||||
public function ban(array $parameters = []): ?string
|
||||
{
|
||||
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator')) {
|
||||
// Авторизован аккаунт администратора или оператора
|
||||
|
||||
// Инициализация данных аккаунта
|
||||
$account = model::read('d._key == "' . $parameters['id'] . '"');
|
||||
|
||||
if (!empty($account)) {
|
||||
// Найден аккаунт
|
||||
|
||||
// Блокирование
|
||||
$account->active = false;
|
||||
$account->banned = true;
|
||||
|
||||
if (_core::update($account)) {
|
||||
// Записаны данные аккаунта
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Type: application/json');
|
||||
header('Content-Encoding: none');
|
||||
header('X-Accel-Buffering: no');
|
||||
|
||||
// Инициализация буфера вывода
|
||||
ob_start();
|
||||
|
||||
// Генерация ответа
|
||||
echo json_encode([
|
||||
'banned' => true,
|
||||
'errors' => self::parse_only_text($this->errors)
|
||||
]);
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Length: ' . ob_get_length());
|
||||
|
||||
// Отправка и деинициализация буфера вывода
|
||||
ob_end_flush();
|
||||
flush();
|
||||
} else throw new exception('Не удалось записать изменения в базу данных');
|
||||
} else throw new exception('Не удалось найти аккаунт');
|
||||
}
|
||||
|
||||
// Возврат (провал)
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Снять пометку заблокированного (разблокировать)
|
||||
*
|
||||
* @param array $parameters Параметры запроса
|
||||
*/
|
||||
public function unban(array $parameters = []): ?string
|
||||
{
|
||||
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator')) {
|
||||
// Авторизован аккаунт администратора или оператора
|
||||
|
||||
// Инициализация данных аккаунта
|
||||
$account = model::read('d._key == "' . $parameters['id'] . '"');
|
||||
|
||||
if (!empty($account)) {
|
||||
// Найден аккаунт
|
||||
|
||||
// Блокирование
|
||||
$account->active = true;
|
||||
$account->banned = false;
|
||||
|
||||
if (_core::update($account)) {
|
||||
// Записаны данные аккаунта
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Type: application/json');
|
||||
header('Content-Encoding: none');
|
||||
header('X-Accel-Buffering: no');
|
||||
|
||||
// Инициализация буфера вывода
|
||||
ob_start();
|
||||
|
||||
// Генерация ответа
|
||||
echo json_encode([
|
||||
'unbanned' => true,
|
||||
'errors' => self::parse_only_text($this->errors)
|
||||
]);
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Length: ' . ob_get_length());
|
||||
|
||||
// Отправка и деинициализация буфера вывода
|
||||
ob_end_flush();
|
||||
flush();
|
||||
} else throw new exception('Не удалось записать изменения в базу данных');
|
||||
} else throw new exception('Не удалось найти аккаунт');
|
||||
}
|
||||
|
||||
// Возврат (провал)
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,9 @@ use mirzaev\ebala\views\templater,
|
|||
// Фреймворк PHP
|
||||
use mirzaev\minimal\controller;
|
||||
|
||||
// Встроенные библиотеки
|
||||
use exception;
|
||||
|
||||
/**
|
||||
* Ядро контроллеров
|
||||
*
|
||||
|
|
|
@ -31,6 +31,11 @@ final class task extends core
|
|||
{
|
||||
use errors;
|
||||
|
||||
/**
|
||||
* Типы работ
|
||||
*/
|
||||
final public const WORKS = ['Кассир', 'Выкладчик', 'Гастроном', 'Бригадир', 'Грузчик', 'Мобильный грузчик', 'Мобильный универсал'];
|
||||
|
||||
/**
|
||||
* Создать
|
||||
*
|
||||
|
@ -477,7 +482,7 @@ final class task extends core
|
|||
];
|
||||
|
||||
if ($account->type === 'worker') {
|
||||
// Оператор или администратор
|
||||
// Сотрудник
|
||||
|
||||
foreach ($link->task['chats']['worker'] ?? [] as $message) {
|
||||
// Перебор сообщений из чата: СОТРУДНИК <-> ОПЕРАТОР
|
||||
|
@ -486,7 +491,7 @@ final class task extends core
|
|||
if (!array_key_exists((string) $account->getKey(), $message['readed'] ?? [])) ++$generated['chat']['unreaded'];
|
||||
}
|
||||
} else if ($account->type === 'market') {
|
||||
// Оператор или администратор
|
||||
// Магазин
|
||||
|
||||
foreach ($link->task['chats']['market'] ?? [] as $message) {
|
||||
// Перебор сообщений из чата: МАГАЗИН <-> ОПЕРАТОР
|
||||
|
@ -1767,7 +1772,10 @@ final class task extends core
|
|||
public function works(array $parameters = []): void
|
||||
{
|
||||
try {
|
||||
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator' || $this->account->type === 'market')) {
|
||||
if (!empty($parameters['task'])) {
|
||||
// Запрошены данные работ по заявке
|
||||
|
||||
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator' || $this->account->type === 'market' || $this->account->type === 'worker')) {
|
||||
// Авторизован аккаунт администратора, оператора или магазина
|
||||
|
||||
// Инициализация данных
|
||||
|
@ -1776,8 +1784,16 @@ final class task extends core
|
|||
if ($this->view->task instanceof _document) {
|
||||
// Найдена заявка
|
||||
|
||||
// Заявка не принадлежит запросившему магазину?
|
||||
if ($this->account->type === 'market' and $this->view->task->market !== account::market($this->account->getId())?->id)
|
||||
throw new exception('Вы не авторизованы для просмотра типа работы этой заявки');
|
||||
|
||||
// Заявка не принадлежит запросившему сотруднику?
|
||||
if ($this->account->type === 'worker' and $this->view->task->worker !== account::worker($this->account->getId())?->id)
|
||||
throw new exception('Вы не авторизованы для просмотра типа работы этой заявки');
|
||||
|
||||
// Инициализация списка работ
|
||||
$this->view->works = ['Кассир', 'Выкладчик', 'Гастроном', 'Бригадир', 'Грузчик', 'Мобильный грузчик', 'Мобильный универсал'];
|
||||
$this->view->works = static::WORKS;
|
||||
|
||||
// Проверка на существование записанной в задаче работы в списке существующих работ и запись об этом в глобальную переменную шаблонизатора
|
||||
foreach ($this->view->works as $work) if ($this->view->task->work === $work) $this->view->exist = true;
|
||||
|
@ -1806,6 +1822,85 @@ final class task extends core
|
|||
flush();
|
||||
} else throw new exception('Не найдена заявка');
|
||||
} else throw new exception('Вы не авторизованы');
|
||||
} else if (!empty($parameters['worker'])) {
|
||||
// Запрошены данные работ по сотруднику
|
||||
|
||||
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator' || $this->account->type === 'worker')) {
|
||||
// Авторизован аккаунт администратора, оператора или магазина
|
||||
|
||||
// Инициализация данных
|
||||
$this->view->worker = worker::read('d.id == "' . $parameters['worker'] . '"');
|
||||
|
||||
if ($this->view->worker instanceof _document) {
|
||||
// Найден сотрудник
|
||||
|
||||
// Сотрудник не принадлежит запросившему аккаунту?
|
||||
if ($this->account->type === 'worker' and $this->view->worker->id !== account::worker($this->account->getId())?->id)
|
||||
throw new exception('Вы не авторизованы для просмотра типа работы этого сотрудника');
|
||||
|
||||
// Инициализация списка работ
|
||||
$this->view->works = static::WORKS;
|
||||
|
||||
// Проверка на существование записанной в задаче работы в списке существующих работ и запись об этом в глобальную переменную шаблонизатора
|
||||
foreach ($this->view->works as $work) if ($this->view->worker->work === $work) $this->view->exist = true;
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Type: application/json');
|
||||
header('Content-Encoding: none');
|
||||
header('X-Accel-Buffering: no');
|
||||
|
||||
// Инициализация буфера вывода
|
||||
ob_start();
|
||||
|
||||
// Генерация ответа
|
||||
echo json_encode(
|
||||
[
|
||||
'works' => $this->view->render(DIRECTORY_SEPARATOR . 'lists' . DIRECTORY_SEPARATOR . 'works.html'),
|
||||
'errors' => self::parse_only_text($this->errors)
|
||||
]
|
||||
);
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Length: ' . ob_get_length());
|
||||
|
||||
// Отправка и деинициализация буфера вывода
|
||||
ob_end_flush();
|
||||
flush();
|
||||
} else throw new exception('Не найден сотрудник');
|
||||
} else throw new exception('Вы не авторизованы');
|
||||
} else {
|
||||
// Запрошен список работ
|
||||
|
||||
if ($this->account->status()) {
|
||||
// Авторизован аккаунт
|
||||
|
||||
// Инициализация списка работ
|
||||
$this->view->works = ['Кассир', 'Выкладчик', 'Гастроном', 'Бригадир', 'Грузчик', 'Мобильный грузчик', 'Мобильный универсал'];
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Type: application/json');
|
||||
header('Content-Encoding: none');
|
||||
header('X-Accel-Buffering: no');
|
||||
|
||||
// Инициализация буфера вывода
|
||||
ob_start();
|
||||
|
||||
// Генерация ответа
|
||||
echo json_encode(
|
||||
[
|
||||
'works' => $this->view->render(DIRECTORY_SEPARATOR . 'lists' . DIRECTORY_SEPARATOR . 'works.html'),
|
||||
'errors' => self::parse_only_text($this->errors)
|
||||
]
|
||||
);
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Length: ' . ob_get_length());
|
||||
|
||||
// Отправка и деинициализация буфера вывода
|
||||
ob_end_flush();
|
||||
flush();
|
||||
} else throw new exception('Вы не авторизованы');
|
||||
}
|
||||
} catch (exception $e) {
|
||||
// Запись в реестр ошибок
|
||||
$this->errors[] = [
|
||||
|
|
|
@ -29,6 +29,11 @@ final class worker extends core
|
|||
{
|
||||
use errors;
|
||||
|
||||
/**
|
||||
* Типы работ
|
||||
*/
|
||||
final public const WORKS = ['Кассир', 'Выкладчик', 'Гастроном', 'Бригадир', 'Грузчик', 'Мобильный грузчик', 'Мобильный универсал'];
|
||||
|
||||
/**
|
||||
* Главная страница
|
||||
*
|
||||
|
@ -261,6 +266,7 @@ final class worker extends core
|
|||
if (!empty($parameters['requisites']) && $parameters['worker_requisites'][-1] === '.') $parameters['worker_requisites'] .= '.';
|
||||
if (!empty($parameters['worker_birth'])) $parameters['worker_birth'] = DateTime::createFromFormat('Y-m-d', $parameters['worker_birth'])->getTimestamp();
|
||||
if (!empty($parameters['worker_issued'])) $parameters['worker_issued'] = DateTime::createFromFormat('Y-m-d', $parameters['worker_issued'])->getTimestamp();
|
||||
if (!empty($parameters['work'])) $parameters['work'] = in_array($parameters['work'], static::WORKS) ? $parameters['work'] : static::WORKS[0];
|
||||
if (!empty($parameters['worker_hiring'])) $parameters['worker_hiring'] = DateTime::createFromFormat('Y-m-d', $parameters['worker_hiring'])->getTimestamp();
|
||||
|
||||
// Создание аккаунта
|
||||
|
@ -353,6 +359,7 @@ final class worker extends core
|
|||
'city' => $parameters['worker_city'],
|
||||
'district' => $parameters['worker_district'],
|
||||
'address' => $parameters['worker_address'],
|
||||
'work' => $parameters['worker_work'],
|
||||
'hiring' => $parameters['worker_hiring'],
|
||||
'rating' => 3
|
||||
],
|
||||
|
@ -389,7 +396,7 @@ final class worker extends core
|
|||
// Авторизован аккаунт администратора или оператора
|
||||
|
||||
// Инициализация данных сотрудника
|
||||
$worker = model::read('d.id == "' . $parameters['id'] . '"', return: '{ name: d.name, number: d.number, mail: d.mail, birth: d.birth, passport: d.passport, issued: d.issued, department: d.department, requisites: d.requisites, payment: d.payment, tax: d.tax, city: d.city, district: d.district, address: d.address, hiring: d.hiring}')->getAll();
|
||||
$worker = model::read('d.id == "' . $parameters['id'] . '"', return: '{ name: d.name, number: d.number, mail: d.mail, birth: d.birth, passport: d.passport, issued: d.issued, department: d.department, requisites: d.requisites, payment: d.payment, tax: d.tax, city: d.city, district: d.district, address: d.address, worl: d.work, hiring: d.hiring}')->getAll();
|
||||
|
||||
if (!empty($worker)) {
|
||||
// Найдены данные сотрудника
|
||||
|
@ -437,6 +444,7 @@ final class worker extends core
|
|||
// Универсализация
|
||||
if (!empty($parameters['birth'])) $parameters['birth'] = DateTime::createFromFormat('Y-m-d', $parameters['birth'])->getTimestamp();
|
||||
if (!empty($parameters['issued'])) $parameters['issued'] = DateTime::createFromFormat('Y-m-d', $parameters['issued'])->getTimestamp();
|
||||
if (!empty($parameters['work'])) $parameters['work'] = in_array($parameters['work'], static::WORKS) ? $parameters['work'] : static::WORKS[0];
|
||||
if (!empty($parameters['hiring'])) $parameters['hiring'] = DateTime::createFromFormat('Y-m-d', $parameters['hiring'])->getTimestamp();
|
||||
|
||||
// Инициализация параметров (перезапись переданными значениями)
|
||||
|
@ -458,6 +466,7 @@ final class worker extends core
|
|||
if ($parameters['city'] !== $worker->city) $worker->city = $parameters['city'];
|
||||
if ($parameters['district'] !== $worker->district) $worker->district = $parameters['district'];
|
||||
if ($parameters['address'] !== $worker->address) $worker->address = $parameters['address'];
|
||||
if ($parameters['work'] !== $worker->work) $worker->work = $parameters['work'];
|
||||
if ($parameters['hiring'] !== $worker->hiring) $worker->hiring = $parameters['hiring'];
|
||||
|
||||
if (_core::update($worker)) {
|
||||
|
@ -513,6 +522,114 @@ final class worker extends core
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Пометить уволенным
|
||||
*
|
||||
* @param array $parameters Параметры запроса
|
||||
*/
|
||||
public function fire(array $parameters = []): ?string
|
||||
{
|
||||
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator')) {
|
||||
// Авторизован аккаунт администратора или оператора
|
||||
|
||||
// Инициализация данных сотрудника
|
||||
$worker = model::read('d.id == "' . $parameters['id'] . '"');
|
||||
|
||||
if (!empty($worker)) {
|
||||
// Найден сотрудник
|
||||
|
||||
// Увольнение
|
||||
$worker->active = false;
|
||||
$worker->fired = true;
|
||||
|
||||
if (_core::update($worker)) {
|
||||
// Записаны данные сотрудника
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Type: application/json');
|
||||
header('Content-Encoding: none');
|
||||
header('X-Accel-Buffering: no');
|
||||
|
||||
// Инициализация буфера вывода
|
||||
ob_start();
|
||||
|
||||
// Инициализация буфера ответа
|
||||
$return = [
|
||||
'fired' => true,
|
||||
'errors' => self::parse_only_text($this->errors)
|
||||
];
|
||||
|
||||
// Генерация ответа
|
||||
echo json_encode($return);
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Length: ' . ob_get_length());
|
||||
|
||||
// Отправка и деинициализация буфера вывода
|
||||
ob_end_flush();
|
||||
flush();
|
||||
} else throw new exception('Не удалось записать изменения в базу данных');
|
||||
} else throw new exception('Не удалось найти аккаунт');
|
||||
}
|
||||
|
||||
// Возврат (провал)
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Снять пометку уволенного (нанять)
|
||||
*
|
||||
* @param array $parameters Параметры запроса
|
||||
*/
|
||||
public function hire(array $parameters = []): ?string
|
||||
{
|
||||
if ($this->account->status() && ($this->account->type === 'administrator' || $this->account->type === 'operator')) {
|
||||
// Авторизован аккаунт администратора или оператора
|
||||
|
||||
// Инициализация данных сотрудника
|
||||
$worker = model::read('d.id == "' . $parameters['id'] . '"');
|
||||
|
||||
if (!empty($worker)) {
|
||||
// Найден сотрудник
|
||||
|
||||
// Увольнение
|
||||
$worker->active = true;
|
||||
$worker->fired = false;
|
||||
|
||||
if (_core::update($worker)) {
|
||||
// Записаны данные сотрудника
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Type: application/json');
|
||||
header('Content-Encoding: none');
|
||||
header('X-Accel-Buffering: no');
|
||||
|
||||
// Инициализация буфера вывода
|
||||
ob_start();
|
||||
|
||||
// Инициализация буфера ответа
|
||||
$return = [
|
||||
'hired' => true,
|
||||
'errors' => self::parse_only_text($this->errors)
|
||||
];
|
||||
|
||||
// Генерация ответа
|
||||
echo json_encode($return);
|
||||
|
||||
// Запись заголовков ответа
|
||||
header('Content-Length: ' . ob_get_length());
|
||||
|
||||
// Отправка и деинициализация буфера вывода
|
||||
ob_end_flush();
|
||||
flush();
|
||||
} else throw new exception('Не удалось записать изменения в базу данных');
|
||||
} else throw new exception('Не удалось найти аккаунт');
|
||||
}
|
||||
|
||||
// Возврат (провал)
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Прочитать данные сотрудников для <datalist>
|
||||
*
|
||||
|
|
|
@ -42,7 +42,7 @@ final class account extends core
|
|||
* Конструктор
|
||||
*
|
||||
* @param ?session $session Инстанция сессии
|
||||
* @param ?string $authenticate Аутентифицировать аккаунт? Если да, то какой категории? ([worker|operator|market] из $_SERVER['INTERFACE'])
|
||||
* @param ?string $authenticate Аутентифицировать аккаунт? Если да, то какой категории? ([worker|market|operator|administrator] из $_SERVER['INTERFACE'])
|
||||
* @param array &$errors Реестр ошибок
|
||||
*
|
||||
* @return static Инстанция аккаунта
|
||||
|
@ -62,12 +62,19 @@ final class account extends core
|
|||
// Связь сессии с аккаунтом
|
||||
session::connect($session->getId(), $this->document->getId(), $errors);
|
||||
|
||||
// Блокировка доступа
|
||||
if ($account?->active !== true) throw new exception('Свяжитесь с оператором');
|
||||
else if ($account?->banned === true) throw new exception('Свяжитесь с оператором');
|
||||
else if ($account->type === 'worker')
|
||||
if (($worker = account::worker($account->getId()))?->active !== true) throw new exception('Свяжитесь с оператором');
|
||||
else if ($worker?->fired === true) throw new exception('Свяжитесь с оператором');
|
||||
|
||||
return $this;
|
||||
} else {
|
||||
// Не найден связанный с сессией аккаунт
|
||||
if (
|
||||
match ($authenticate) {
|
||||
'worker', 'operator', 'market', 'administrator' => true,
|
||||
'worker', 'market', 'operator', 'administrator' => true,
|
||||
default => false
|
||||
}
|
||||
) {
|
||||
|
@ -94,11 +101,16 @@ final class account extends core
|
|||
// Удаление использованных данных из буфера сессии
|
||||
$session->write(['entry' => ['number' => null, 'password' => null]]);
|
||||
|
||||
// Блокировка доступа
|
||||
if ($account?->active !== true) throw new exception('Свяжитесь с оператором');
|
||||
else if ($account?->banned === true) throw new exception('Свяжитесь с оператором');
|
||||
else if ($account->type === 'worker')
|
||||
if (($worker = account::worker($account->getId()))?->active !== true) throw new exception('Свяжитесь с оператором');
|
||||
else if ($worker?->fired === true) throw new exception('Свяжитесь с оператором');
|
||||
|
||||
// Выход (успех)
|
||||
return $this;
|
||||
} else throw new exception('Неправильный пароль');
|
||||
|
||||
throw new exception('Неизвестная ошибка на этапе проверки пароля');
|
||||
} else throw new exception('Не найден аккаунт');
|
||||
} else throw new exception('Не найден пароль в буфере сессии');
|
||||
} else if (!empty($session->buffer['operator']['entry']['_key'])) {
|
||||
|
@ -125,8 +137,6 @@ final class account extends core
|
|||
// Выход (успех)
|
||||
return $this;
|
||||
} else throw new exception('Неправильный пароль');
|
||||
|
||||
throw new exception('Неизвестная ошибка на этапе проверки пароля');
|
||||
}
|
||||
} else throw new exception('Не найден пароль в буфере сессии');
|
||||
} else if (!empty($session->buffer['market']['entry']['id'])) {
|
||||
|
@ -153,8 +163,6 @@ final class account extends core
|
|||
// Выход (успех)
|
||||
return $this;
|
||||
} else throw new exception('Неправильный пароль');
|
||||
|
||||
throw new exception('Неизвестная ошибка на этапе проверки пароля');
|
||||
}
|
||||
} else throw new exception('Не найден пароль в буфере сессии');
|
||||
} else if (!empty($session->buffer['administrator']['entry'])) {
|
||||
|
@ -181,8 +189,6 @@ final class account extends core
|
|||
// Выход (успех)
|
||||
return $this;
|
||||
} else throw new exception('Неправильный пароль');
|
||||
|
||||
throw new exception('Неизвестная ошибка на этапе проверки пароля');
|
||||
}
|
||||
} else throw new exception('Не найден пароль в буфере сессии');
|
||||
} else throw new exception('Не найдены данные первичной идентификации в буфере сессии');
|
||||
|
@ -227,7 +233,7 @@ final class account extends core
|
|||
LIMIT 1
|
||||
RETURN e
|
||||
)
|
||||
FILTER d._id == e[0]._to && d.active == true
|
||||
FILTER d._id == e[0]._to
|
||||
SORT d.created DESC, d._key DESC
|
||||
LIMIT 1
|
||||
RETURN d
|
||||
|
@ -285,7 +291,7 @@ final class account extends core
|
|||
LIMIT 1
|
||||
RETURN e
|
||||
)
|
||||
FILTER d._id == e[0]._to && d.active == true
|
||||
FILTER d._id == e[0]._to
|
||||
SORT d.created DESC, d.id DESC
|
||||
LIMIT 1
|
||||
RETURN d
|
||||
|
|
|
@ -17,34 +17,34 @@ section.panel.list.medium {
|
|||
width: 80%;
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu {
|
||||
section.panel.list> :is(form, search).row.menu {
|
||||
margin-bottom: 10px;
|
||||
transition: 0s;
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu > label {
|
||||
section.panel.list> :is(form, search).row.menu>label {
|
||||
height: max-content;
|
||||
min-height: 30px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu > label:not(.solid) {
|
||||
section.panel.list> :is(form, search).row.menu>label:not(.solid) {
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu.wide > label {
|
||||
section.panel.list> :is(form, search).row.menu.wide>label {
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu.separated {
|
||||
section.panel.list> :is(form, search).row.menu.separated {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
div#popup > section.list > div.row.endless {
|
||||
div#popup>section.list>div.row.endless {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu > label > button {
|
||||
section.panel.list> :is(form, search).row.menu>label>button {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
@ -52,14 +52,11 @@ section.panel.list > :is(form, search).row.menu > label > button {
|
|||
height: 30px;
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu > label > button.separated {
|
||||
section.panel.list> :is(form, search).row.menu>label>button.separated {
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
section.panel.list
|
||||
> :is(form, search).row.menu
|
||||
> label
|
||||
> button.separated:before {
|
||||
section.panel.list> :is(form, search).row.menu>label>button.separated:before {
|
||||
content: "";
|
||||
left: -12px;
|
||||
position: absolute;
|
||||
|
@ -68,54 +65,47 @@ section.panel.list
|
|||
border-left: 2px solid var(--earth-above);
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu.stretched > label > button,
|
||||
section.panel.list
|
||||
> :is(form, search).row.menu.stretched
|
||||
> label
|
||||
> input[type="search"] {
|
||||
section.panel.list> :is(form, search).row.menu.stretched>label>button,
|
||||
section.panel.list> :is(form, search).row.menu.stretched>label>input[type="search"] {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu.stretched > label > button {
|
||||
section.panel.list> :is(form, search).row.menu.stretched>label>button {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu > label > input {
|
||||
section.panel.list> :is(form, search).row.menu>label>input {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu > label > input:not(.merged) {
|
||||
section.panel.list> :is(form, search).row.menu>label>input:not(.merged) {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
section.panel.list > :is(form, search).row.menu > label > input[type="date"] {
|
||||
section.panel.list> :is(form, search).row.menu>label>input[type="date"] {
|
||||
width: 115px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
section.panel.list
|
||||
> :is(form, search).row.menu
|
||||
> label
|
||||
> input[type="search"]
|
||||
+ button {
|
||||
section.panel.list> :is(form, search).row.menu>label>input[type="search"]+button {
|
||||
height: 100%;
|
||||
padding: 0 30px;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
section.panel.list > div#title {
|
||||
section.panel.list>div#title {
|
||||
margin-top: 20px;
|
||||
height: 50px;
|
||||
background-color: var(--background-below-6);
|
||||
}
|
||||
|
||||
section.panel.list > div#title > span {
|
||||
section.panel.list>div#title>span {
|
||||
font-weight: unset;
|
||||
font-size: unset;
|
||||
color: unset;
|
||||
}
|
||||
|
||||
section.panel.list > div.row {
|
||||
section.panel.list>div.row {
|
||||
--gap: 12px;
|
||||
--background: var(--cloud);
|
||||
position: relative;
|
||||
|
@ -128,11 +118,11 @@ section.panel.list > div.row {
|
|||
border-radius: 0px;
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)) {
|
||||
section.panel.list>div.row:not(:nth-of-type(1)) {
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)) > span {
|
||||
section.panel.list>div.row:not(:nth-of-type(1))>span {
|
||||
height: 100%;
|
||||
line-height: 2.2;
|
||||
padding: 0;
|
||||
|
@ -142,7 +132,7 @@ section.panel.list > div.row:not(:nth-of-type(1)) > span {
|
|||
-moz-box-shadow: var(--box-shadow);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)):is(:hover, :focus) {
|
||||
section.panel.list>div.row:not(:nth-of-type(1)):is(:hover, :focus) {
|
||||
--padding-left: 24px;
|
||||
--padding-right: 24px;
|
||||
left: -12px;
|
||||
|
@ -151,23 +141,23 @@ section.panel.list > div.row:not(:nth-of-type(1)):is(:hover, :focus) {
|
|||
transition: 0s;
|
||||
}
|
||||
|
||||
section.panel.list > div.row:first-of-type {
|
||||
section.panel.list>div.row:first-of-type {
|
||||
border-radius: 3px 3px 0 0;
|
||||
}
|
||||
|
||||
section.panel.list > div.row:last-of-type {
|
||||
section.panel.list>div.row:last-of-type {
|
||||
border-radius: 0 0 3px 3px;
|
||||
}
|
||||
|
||||
section.panel.list > div.row:is(:hover, :focus) * {
|
||||
section.panel.list>div.row:is(:hover, :focus) * {
|
||||
transition: unset;
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)):nth-child(2n + 1) {
|
||||
section.panel.list>div.row:not(:nth-of-type(1)):nth-child(2n + 1) {
|
||||
--background: var(--cloud-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row[data-selected="true"]:before {
|
||||
section.panel.list>div.row[data-selected="true"]:before {
|
||||
left: -25px;
|
||||
top: 0.08rem;
|
||||
position: absolute;
|
||||
|
@ -186,7 +176,7 @@ section.panel.list > div.row[data-selected="true"]:before {
|
|||
color: var(--interface-brown);
|
||||
}
|
||||
|
||||
section.panel.list > div.row[data-selected="true"]:after {
|
||||
section.panel.list>div.row[data-selected="true"]:after {
|
||||
right: -25px;
|
||||
bottom: 0.08rem;
|
||||
rotate: 180deg;
|
||||
|
@ -206,85 +196,14 @@ section.panel.list > div.row[data-selected="true"]:after {
|
|||
color: var(--interface-brown);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).confirmed {
|
||||
--background: var(--grass);
|
||||
}
|
||||
|
||||
section.panel.list
|
||||
> div.row:not(:nth-of-type(1)):nth-child(2n + 1).confirmed {
|
||||
--background: var(--grass-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).published {
|
||||
--background: var(--river);
|
||||
}
|
||||
|
||||
section.panel.list
|
||||
> div.row:not(:nth-of-type(1)):nth-child(2n + 1).published {
|
||||
--background: var(--river-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).confirmed.published:not(.problematic) {
|
||||
--background: var(--sea);
|
||||
}
|
||||
|
||||
section.panel.list
|
||||
> div.row:not(:nth-of-type(1)).confirmed.published:not(.problematic):nth-child(2n + 1) {
|
||||
--background: var(--sea-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).problematic {
|
||||
--background: var(--clay);
|
||||
}
|
||||
|
||||
section.panel.list
|
||||
> div.row:not(:nth-of-type(1)):nth-child(2n + 1).problematic {
|
||||
--background: var(--clay-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).coming {
|
||||
--background: var(--magma);
|
||||
}
|
||||
|
||||
section.panel.list
|
||||
> div.row:not(:nth-of-type(1)):nth-child(2n + 1).coming {
|
||||
--background: var(--magma-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).completed:not(.problematic) {
|
||||
--background: var(--sand);
|
||||
}
|
||||
|
||||
section.panel.list
|
||||
> div.row:not(:nth-of-type(1)):nth-child(2n + 1).completed:not(.problematic) {
|
||||
--background: var(--sand-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).passed {
|
||||
filter: brightness(0.8);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).hided * {
|
||||
filter: blur(1px);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).hided:is(:hover, :focus) * {
|
||||
filter: unset;
|
||||
opacity: unset;
|
||||
}
|
||||
|
||||
section.panel.list > div.row.reinitialized {
|
||||
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 {
|
||||
section.panel.list>div.row:not(:nth-of-type(1),
|
||||
[data-selected="true"]).reinitializable:before {
|
||||
content: attr(data-counter);
|
||||
position: absolute;
|
||||
left: -95px;
|
||||
|
@ -297,16 +216,13 @@ section.panel.list
|
|||
color: var(--earth-text);
|
||||
}
|
||||
|
||||
section.panel.list
|
||||
> div.row:not(:nth-of-type(1), [data-selected="true"]).reinitializable:is(
|
||||
:hover,
|
||||
:focus
|
||||
):before {
|
||||
section.panel.list>div.row:not(:nth-of-type(1), [data-selected="true"]).reinitializable:is(:hover,
|
||||
:focus):before {
|
||||
content: attr(id);
|
||||
color: var(--earth-text-important-below);
|
||||
}
|
||||
|
||||
section.panel.list > div.row > span {
|
||||
section.panel.list>div.row>span {
|
||||
position: relative;
|
||||
margin: auto 0;
|
||||
padding: 8px 0;
|
||||
|
@ -314,52 +230,52 @@ section.panel.list > div.row > span {
|
|||
transition: 0s;
|
||||
}
|
||||
|
||||
section.panel.list > div.row:is(:hover, :focus) > span {
|
||||
section.panel.list>div.row:is(:hover, :focus)>span {
|
||||
transition: 0s;
|
||||
}
|
||||
|
||||
section.panel.list > div.row > span:not(:first-child) {
|
||||
section.panel.list>div.row>span:not(:first-child) {
|
||||
--padding-left: calc(var(--gap) / 2);
|
||||
}
|
||||
|
||||
section.panel.list > div.row > span:not(:last-child) {
|
||||
section.panel.list>div.row>span:not(:last-child) {
|
||||
--padding-right: calc(var(--gap) / 2);
|
||||
}
|
||||
|
||||
section.panel.list > div.row > span:first-child {
|
||||
section.panel.list>div.row>span:first-child {
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
|
||||
section.panel.list > div.row > span:last-child {
|
||||
section.panel.list>div.row>span:last-child {
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:hover, :focus) > span:first-child {
|
||||
section.panel.list>div.row:not(:hover, :focus)>span:first-child {
|
||||
--padding-left: var(--gap, 12px);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:hover, :focus) > span:last-child {
|
||||
section.panel.list>div.row:not(:hover, :focus)>span:last-child {
|
||||
--padding-right: var(--gap, 12px);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:nth-of-type(1) > span {
|
||||
section.panel.list>div.row:nth-of-type(1)>span {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
section.panel.list > div.row:nth-of-type(1) > span > i {
|
||||
section.panel.list>div.row:nth-of-type(1)>span>i {
|
||||
position: relative;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
section.panel.list > div.row > span[onclick] {
|
||||
section.panel.list>div.row>span[onclick] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
section.panel.list > div.row > span.field {
|
||||
section.panel.list>div.row>span.field {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)) > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row:not(:nth-of-type(1))>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--margin: calc(var(--gap) / 2);
|
||||
--border-left: calc(var(--padding-left, var(--margin, 0px)) * -1);
|
||||
--border-right: var(--padding-right, var(--margin, 0px));
|
||||
|
@ -367,54 +283,196 @@ section.panel.list > div.row:not(:nth-of-type(1)) > span:is(.important, .interac
|
|||
--box-shadow: var(--border-left, 0) 0 0 0 var(--box-shadow-color, var(--background)), var(--border-right, 0) 0 0 0 var(--box-shadow-color, var(--background));
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)):nth-child(2n + 1) > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).confirmed {
|
||||
--background: var(--grass);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1).confirmed {
|
||||
--background: var(--grass-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).published {
|
||||
--background: var(--river);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1).published {
|
||||
--background: var(--river-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).confirmed.published:not(.problematic) {
|
||||
--background: var(--sea);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).confirmed.published:not(.problematic):nth-child(2n + 1) {
|
||||
--background: var(--sea-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).problematic {
|
||||
--background: var(--clay);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1).problematic {
|
||||
--background: var(--clay-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).coming {
|
||||
--background: var(--magma);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1).coming {
|
||||
--background: var(--magma-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).completed:not(.problematic) {
|
||||
--background: var(--sand);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1).completed:not(.problematic) {
|
||||
--background: var(--sand-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).passed {
|
||||
filter: brightness(0.8);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)).banned {
|
||||
--background: var(--clay);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)).banned a {
|
||||
--color: var(--clay-text);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)).banned a:is(:hover, :focus) {
|
||||
--color: var(--clay-text-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)).banned a:active {
|
||||
--color: var(--clay-text-below);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)):nth-child(2n + 1).banned {
|
||||
--background: var(--clay-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)):nth-child(2n + 1).banned a {
|
||||
--color: var(--clay-text);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)):nth-child(2n + 1).banned a:is(:hover, :focus) {
|
||||
--color: var(--clay-text-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)):nth-child(2n + 1).banned a:active {
|
||||
--color: var(--clay-text-below);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)).fired {
|
||||
--background: var(--magma);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)).fired a:is(:hover, :focus) {
|
||||
--color: var(--magma-text-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)).fired a:active {
|
||||
--color: var(--magma-text-below);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)).fired a {
|
||||
--color: var(--magma-text);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)):nth-child(2n + 1).fired {
|
||||
--background: var(--magma-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)):nth-child(2n + 1).fired a {
|
||||
--color: var(--magma-text);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)):nth-child(2n + 1).fired a:is(:hover, :focus) {
|
||||
--color: var(--magma-text-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)):nth-child(2n + 1).fired a:active {
|
||||
--color: var(--magma-text-below);
|
||||
}
|
||||
|
||||
section.panel.list>div.row:not(:nth-of-type(1)).hided * {
|
||||
filter: blur(1px);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
section.panel.list>div.row:not(:nth-of-type(1)).hided:is(:hover, :focus) * {
|
||||
filter: unset;
|
||||
opacity: unset;
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1)>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--cloud-rainy-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).published > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).published>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--river-deep);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)):nth-child(2n + 1).published > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1).published>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--river-deep-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).confirmed > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).confirmed>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--grass-dense);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)):nth-child(2n + 1).confirmed > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1).confirmed>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--grass-dense-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).confirmed.published:not(.problematic) > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).confirmed.published:not(.problematic)>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--sea-deep);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)):nth-child(2n + 1).confirmed.published:not(.problematic) > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1).confirmed.published:not(.problematic)>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--sea-deep-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).problematic > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).problematic>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--clay-important);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)):nth-child(2n + 1).problematic > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1).problematic>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--clay-important-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).coming > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).coming>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--magma-important);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)):nth-child(2n + 1).coming > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1).coming>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--magma-important-above);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)).completed:not(.problematic) > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)).completed:not(.problematic)>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--sand-important);
|
||||
}
|
||||
|
||||
section.panel.list > div.row:not(:nth-of-type(1)):nth-child(2n + 1).completed:not(.problematic) > span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
section.panel.list>div.row[data-row="task"]:not(:nth-of-type(1)):nth-child(2n + 1).completed:not(.problematic)>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--sand-important-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)).banned>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--clay-important);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)):nth-child(2n + 1).banned>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--clay-important-above);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)).fired>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--magma-important);
|
||||
}
|
||||
|
||||
section.panel.list>div.row[data-row="worker"]:not(:nth-of-type(1)):nth-child(2n + 1).fired>span:is(.important, .interactive:is(:hover, :focus)) {
|
||||
--background: var(--magma-important-above);
|
||||
}
|
||||
|
|
|
@ -259,15 +259,16 @@ button:is(.transparent, .transparent:is(:hover, :focus), .transparent:active) {
|
|||
}
|
||||
|
||||
a {
|
||||
color: var(--link);
|
||||
--color: var(--link);
|
||||
color: var(--color);
|
||||
}
|
||||
|
||||
a:is(:hover, :focus) {
|
||||
color: var(--link-hover);
|
||||
--color: var(--link-hover);
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: var(--link-active);
|
||||
--color: var(--link-active);
|
||||
transition: unset;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ section#workers.panel.list
|
|||
[data-column="worker"],
|
||||
[data-column="name"],
|
||||
[data-column="number"],
|
||||
[data-column="mail"],
|
||||
[data-column="work"],
|
||||
[data-column="passport"],
|
||||
[data-column="address"],
|
||||
[data-column="tax"],
|
||||
|
|
|
@ -38,7 +38,6 @@ div#popup>section.stretched {
|
|||
flex-grow: unset;
|
||||
}
|
||||
|
||||
|
||||
div#popup>section.calculated {
|
||||
width: calc(var(--calculated-width) - var(--padding-horizontal, 0px) * 2);
|
||||
}
|
||||
|
@ -53,6 +52,11 @@ div#popup>section.list {
|
|||
border-radius: 3px;
|
||||
}
|
||||
|
||||
div#popup>section.list.extensive {
|
||||
max-width: unset;
|
||||
max-height: unset;
|
||||
}
|
||||
|
||||
div#popup>section.list>h3 {
|
||||
margin-top: 4px;
|
||||
margin-bottom: 22px;
|
||||
|
|
|
@ -83,10 +83,9 @@
|
|||
--sand-important: #d7c06c;
|
||||
--sand-important-below: #dfc79a;
|
||||
|
||||
--magma-text-above: ;
|
||||
--magma-text: ;
|
||||
--magma-text-below: ;
|
||||
--magma-text-below-1: ;
|
||||
--magma-text-above: #111;
|
||||
--magma-text: #5e1a1a;
|
||||
--magma-text-below: #826d1c;
|
||||
--magma-above: #ffd325;
|
||||
--magma: #e6bf26;
|
||||
--magma-below: ;
|
||||
|
|
|
@ -40,6 +40,7 @@ $router->write('/worker/$worker/read', 'task', 'worker', 'POST');
|
|||
$router->write('/worker/$id/fields', 'worker', 'fields', 'POST');
|
||||
$router->write('/worker/$id/update', 'worker', 'update', 'POST');
|
||||
$router->write('/worker/$id/fire', 'worker', 'fire', 'POST');
|
||||
$router->write('/worker/$id/hire', 'worker', 'hire', 'POST');
|
||||
$router->write('/workers', 'worker', 'index', 'GET');
|
||||
$router->write('/workers', 'worker', 'index', 'POST');
|
||||
$router->write('/workers/read', 'worker', 'read', 'POST');
|
||||
|
@ -68,6 +69,8 @@ $router->write('/$id', 'account', 'index', 'POST');
|
|||
$router->write('/$id/fields', 'account', 'fields', 'POST');
|
||||
$router->write('/$id/update', 'account', 'update', 'POST');
|
||||
$router->write('/$id/delete', 'account', 'delete', 'POST');
|
||||
$router->write('/$id/ban', 'account', 'ban', 'POST');
|
||||
$router->write('/$id/unban', 'account', 'unban', 'POST');
|
||||
$router->write('/session/worker', 'session', 'worker', 'POST');
|
||||
$router->write('/session/write', 'session', 'write', 'POST');
|
||||
$router->write('/session/read', 'session', 'read', 'POST');
|
||||
|
@ -79,6 +82,7 @@ $router->write('/session/invite', 'session', 'invite', 'POST');
|
|||
$router->write('/tasks/create', 'task', 'create', 'POST');
|
||||
$router->write('/tasks/read', 'task', 'read', 'POST');
|
||||
$router->write('/works/list', 'work', 'datalist', 'POST');
|
||||
$router->write('/tasks/works', 'task', 'works', 'POST');
|
||||
$router->write('/task/$task/read', 'task', 'task', 'POST');
|
||||
$router->write('/task/$task/value', 'task', 'value', 'POST');
|
||||
$router->write('/task/$task/confirm', 'task', 'confirm', 'POST');
|
||||
|
@ -88,7 +92,6 @@ $router->write('/task/$task/hide', 'task', 'hide', 'POST');
|
|||
$router->write('/task/$task/remove', 'task', 'remove', 'POST');
|
||||
$router->write('/task/$task/work', 'task', 'work', 'POST');
|
||||
$router->write('/task/$task/date', 'task', 'date', 'POST');
|
||||
$router->write('/task/$task/works', 'task', 'works', 'POST');
|
||||
$router->write('/task/$task/description', 'task', 'description', 'POST');
|
||||
$router->write('/task/$task/commentary', 'task', 'commentary', 'POST');
|
||||
$router->write('/task/$task/worker/update', 'task', 'update', 'POST');
|
||||
|
|
|
@ -338,7 +338,7 @@ if (typeof window.administrators !== "function") {
|
|||
|
||||
// Инициализация оболочки всплывающего окна
|
||||
const popup = document.createElement("section");
|
||||
popup.classList.add("list", "small");
|
||||
popup.classList.add("list", "extensive", "small");
|
||||
|
||||
// Инициализация заголовка всплывающего окна
|
||||
const title = document.createElement("h3");
|
||||
|
@ -1056,7 +1056,7 @@ if (typeof window.administrators !== "function") {
|
|||
);
|
||||
|
||||
/**
|
||||
* Сгенерировать окно с формой создания аккаунт
|
||||
* Сгенерировать окно с формой создания аккаунта
|
||||
*
|
||||
* @param {HTMLElement} row Строка
|
||||
*
|
||||
|
@ -1069,7 +1069,7 @@ if (typeof window.administrators !== "function") {
|
|||
|
||||
// Инициализация оболочки всплывающего окна
|
||||
const popup = document.createElement("section");
|
||||
popup.classList.add("list", "small");
|
||||
popup.classList.add("list", "extensive", "small");
|
||||
|
||||
// Инициализация заголовка всплывающего окна
|
||||
const title = document.createElement("h3");
|
||||
|
|
|
@ -339,7 +339,7 @@ if (typeof window.markets !== "function") {
|
|||
|
||||
// Инициализация всплывающего окна
|
||||
const popup = document.createElement("section");
|
||||
popup.classList.add("list", "medium");
|
||||
popup.classList.add("list", "extensive", "medium");
|
||||
|
||||
// Инициализация заголовка всплывающего окна
|
||||
const title = document.createElement("h3");
|
||||
|
@ -1774,7 +1774,7 @@ if (typeof window.markets !== "function") {
|
|||
|
||||
// Инициализация всплывающего окна
|
||||
const popup = document.createElement("section");
|
||||
popup.classList.add("list", "medium");
|
||||
popup.classList.add("list", "extensive", "medium");
|
||||
|
||||
// Инициализация заголовка всплывающего окна
|
||||
const title = document.createElement("h3");
|
||||
|
|
|
@ -338,7 +338,7 @@ if (typeof window.operators !== "function") {
|
|||
|
||||
// Инициализация оболочки всплывающего окна
|
||||
const popup = document.createElement("section");
|
||||
popup.classList.add("list", "small");
|
||||
popup.classList.add("list", "extensive", "small");
|
||||
|
||||
// Инициализация заголовка всплывающего окна
|
||||
const title = document.createElement("h3");
|
||||
|
@ -1069,7 +1069,7 @@ if (typeof window.operators !== "function") {
|
|||
|
||||
// Инициализация оболочки всплывающего окна
|
||||
const popup = document.createElement("section");
|
||||
popup.classList.add("list", "small");
|
||||
popup.classList.add("list", "extensive", "small");
|
||||
|
||||
// Инициализация заголовка всплывающего окна
|
||||
const title = document.createElement("h3");
|
||||
|
|
|
@ -2573,7 +2573,7 @@ if (typeof window.tasks !== "function") {
|
|||
// Инициализация списка выбора типа работы
|
||||
const work = document.createElement("select");
|
||||
work.classList.add("row", "connected", "stretched");
|
||||
this.works(row).then((html) => (work.innerHTML = html));
|
||||
this.works(task).then((html) => (work.innerHTML = html));
|
||||
work.setAttribute("title", "Тип работы");
|
||||
|
||||
// Инициализация поля ввода описания
|
||||
|
@ -3840,28 +3840,22 @@ if (typeof window.tasks !== "function") {
|
|||
}
|
||||
|
||||
/**
|
||||
* Сгенерировать список работ и выбрать в нём ту, что записана в базе данных у заявки
|
||||
* Список работ
|
||||
*
|
||||
* @param {HTMLElement} row Строка
|
||||
* Сгенерировать список работ и выбрать в нём ту, что записана в базе данных у заявки, если передана
|
||||
*
|
||||
* @param {number|null} id Идентификатор заявки
|
||||
*
|
||||
* @return {array|null} Массив HTML-элементов <option>
|
||||
*/
|
||||
static async works(row) {
|
||||
if (row instanceof HTMLElement) {
|
||||
// Получена строка
|
||||
|
||||
// Инициализация идентификатора строки
|
||||
const id = row.getAttribute("id");
|
||||
|
||||
if (typeof id === "string") {
|
||||
// Инициализирован идентификатор
|
||||
|
||||
static async works(id) {
|
||||
// Запрос к серверу
|
||||
return await fetch(`/task/${id}/works`, {
|
||||
return await fetch(`/tasks/works`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: `task=${id}`,
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
|
@ -3874,8 +3868,6 @@ if (typeof window.tasks !== "function") {
|
|||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Записать тип работы
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,7 +17,7 @@
|
|||
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 class="unselectable interactive" data-column="work" title="{{ row.task.description }}">{{ row.task.work
|
||||
<span class="unselectable interactive" data-column="work" title="{{ row.task.description }}">{{ row.task.work|work
|
||||
}}</span>
|
||||
<span class="unselectable interactive" data-column="start">{{
|
||||
row.task.generated.start }}</span>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% if page != null %}<!-- PAGE #{{ page }} -->{% endif %}
|
||||
{% for row in rows %}
|
||||
<div id="{{ row.account._key }}"
|
||||
class="row{% if row.account.active is same as(true) %} active{% else %} hided{% endif %}" data-row="worker">
|
||||
class="row{% if row.account.active is same as(true) %} active{% endif %}{% if row.account.banned is same as(true) %} banned{% endif %}{% if row.worker.fired is same as(true) %} fired{% endif %}" data-row="worker">
|
||||
<span class="unselectable interactive" data-column="account" title="Настройки аккаунта"
|
||||
onclick="workers.account.update(this.parentElement)">{{
|
||||
row.account._key }}</span>
|
||||
|
@ -17,8 +17,7 @@
|
|||
row.worker.name.second }}{% endif %}</span>
|
||||
<span class="unselectable interactive" data-column="number"><a href="tel:{{ row.worker.number }}" title="Позвонить">{{
|
||||
row.worker.number|storaged_number_to_readable }}</a></span>
|
||||
<span class="unselectable interactive" data-column="mail"><a href="mailto:{{ row.worker.mail }}" title="Написать">{{
|
||||
row.worker.mail }}</a></span>
|
||||
<span class="unselectable interactive" data-column="work">{{ row.worker.work }}</span>
|
||||
<span class="unselectable interactive" data-column="address"
|
||||
title="{{ (row.worker.city ~ ' ' ~ row.worker.district ~ ' ' ~ row.worker.address)|trim }}"
|
||||
onclick="navigator.clipboard.writeText('{{ row.worker.city ~ ' ' ~ row.worker.district ~ ' ' ~ row.worker.address }}')">{%
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
{% if task %}
|
||||
{% if exist is same as(true) %}
|
||||
{% for work in works %}
|
||||
<option value="{{ work }}" {% if task.work==work %} selected{% endif %}>{{ work }}</option>
|
||||
|
@ -14,3 +15,25 @@
|
|||
{% endfor %}
|
||||
</optgroup>
|
||||
{% endif %}
|
||||
{% elseif worker %}
|
||||
{% if exist is same as(true) %}
|
||||
{% for work in works %}
|
||||
<option value="{{ work }}" {% if worker.work==work %} selected{% endif %}>{{ work }}</option>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% if worker is not null %}
|
||||
<optgroup label="Текущее">
|
||||
<option value="{{ worker.work }}" selected>{{ worker.work }}</option>
|
||||
</optgroup>
|
||||
{% endif %}
|
||||
<optgroup label="Доступное">
|
||||
{% for work in works %}
|
||||
<option value="{{ work }}">{{ work }}</option>
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% for work in works %}
|
||||
<option value="{{ work }}">{{ work }}</option>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
<button class="grass dense" onclick="tasks.create()">Создать</button>
|
||||
{% endif %}
|
||||
{% if account.type == 'administrator' or account.type == 'operator' %}
|
||||
<button class="sea" onclick="payments.workers()">Зарплата</button>
|
||||
<button class="sea" onclick="payments.markets()">Сверка</button>
|
||||
<button class="sea" onclick="payments.workers()">Сотрудники</button>
|
||||
<button class="sea" onclick="payments.markets()">Магазины</button>
|
||||
{% endif %}
|
||||
</label>
|
||||
</form>
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
<span data-column="worker" 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="work" class="button">Работа</span>
|
||||
<span data-column="address" class="button">Адрес</span>
|
||||
<span data-column="passport" class="button">Паспорт</span>
|
||||
<span data-column="tax" class="button">ИНН</span>
|
||||
|
|
|
@ -59,7 +59,7 @@ final class templater extends controller implements ArrayAccess
|
|||
}
|
||||
if (!empty($account->status())) $this->twig->addGlobal('account', $account);
|
||||
|
||||
// Инициализация фильтров
|
||||
// Инициализация фильтра
|
||||
$this->twig->addFilter(
|
||||
new TwigFilter(
|
||||
'storaged_number_to_readable',
|
||||
|
@ -67,7 +67,7 @@ final class templater extends controller implements ArrayAccess
|
|||
)
|
||||
);
|
||||
|
||||
// Инициализация фильтров
|
||||
// Инициализация фильтра
|
||||
$this->twig->addFilter(
|
||||
new TwigFilter(
|
||||
'storaged_requisites_to_card',
|
||||
|
@ -78,7 +78,7 @@ final class templater extends controller implements ArrayAccess
|
|||
)
|
||||
);
|
||||
|
||||
// Инициализация фильтров
|
||||
// Инициализация фильтра
|
||||
$this->twig->addFilter(
|
||||
new TwigFilter(
|
||||
'storaged_requisites_preview',
|
||||
|
@ -86,7 +86,7 @@ final class templater extends controller implements ArrayAccess
|
|||
)
|
||||
);
|
||||
|
||||
// Инициализация фильтров
|
||||
// Инициализация фильтра
|
||||
$this->twig->addFilter(
|
||||
new TwigFilter(
|
||||
'date_to_russian',
|
||||
|
@ -94,7 +94,7 @@ final class templater extends controller implements ArrayAccess
|
|||
)
|
||||
);
|
||||
|
||||
// Инициализация фильтров
|
||||
// Инициализация фильтра
|
||||
$this->twig->addFilter(
|
||||
new TwigFilter(
|
||||
'account_type_to_russian',
|
||||
|
@ -108,6 +108,14 @@ final class templater extends controller implements ArrayAccess
|
|||
)
|
||||
);
|
||||
|
||||
// Инициализация фильтра
|
||||
$this->twig->addFilter(
|
||||
new TwigFilter(
|
||||
'work',
|
||||
fn (string $work) => preg_replace('/^Мобильный/', 'Моб.', $work)
|
||||
)
|
||||
);
|
||||
|
||||
// Инициализация расширений
|
||||
$this->twig->addExtension(new intl());
|
||||
}
|
||||
|
|
Reference in New Issue