forked from CITKParus/P8-Panels
295 lines
12 KiB
JavaScript
295 lines
12 KiB
JavaScript
/*
|
||
Парус 8 - Панели мониторинга - УДП - Доски задач
|
||
Дополнительная разметка и вёрстка клиентских элементов
|
||
*/
|
||
|
||
//---------
|
||
//Константы
|
||
//---------
|
||
|
||
//Перечисление "Состояние события"
|
||
export const EVENT_STATES = Object.freeze({ 0: "Все", 1: "Не аннулированные", 2: "Аннулированные" });
|
||
|
||
//Допустимые значение поля сортировки
|
||
export const sortAttrs = [
|
||
{ id: "SEVNSTAT_CODE", descr: "Мнемокод" },
|
||
{ id: "SEVNSTAT_NAME", descr: "Наименование" },
|
||
{ id: "SEVPOINT_DESCR", descr: "Описание точки маршрута" }
|
||
];
|
||
|
||
//Допустимые значения направления сортировки
|
||
export const sortDest = [];
|
||
sortDest[-1] = "desc";
|
||
sortDest[1] = "asc";
|
||
|
||
//Цвета статусов
|
||
export const COLORS = [
|
||
"mediumSlateBlue",
|
||
"lightSalmon",
|
||
"fireBrick",
|
||
"orange",
|
||
"gold",
|
||
"limeGreen",
|
||
"yellowGreen",
|
||
"mediumAquaMarine",
|
||
"paleTurquoise",
|
||
"steelBlue",
|
||
"skyBlue",
|
||
"tan"
|
||
];
|
||
|
||
//Перечисление "Цвет задачи"
|
||
export const TASK_COLORS = Object.freeze({ EXPIRED: "#ff0000", EXPIRES_SOON: "#ffdf00", LINKED: "#1e90ff" });
|
||
|
||
//Перечисление Доп. свойства "Значение по умолчанию"
|
||
export const DP_DEFAULT_VALUE = Object.freeze({ 0: "SDEFAULT_STR", 1: "NDEFAULT_NUM", 2: "DDEFAULT_DATE", 3: "NDEFAULT_NUM" });
|
||
//Перечисление Доп. свойства "Префикс формата данных"
|
||
export const DP_TYPE_PREFIX = Object.freeze({ 0: "S", 1: "N", 2: "D", 3: "N" });
|
||
//Перечисление Доп. свойства "Входящее значение дополнительного словаря"
|
||
export const DP_IN_VALUE = Object.freeze({ 0: "pos_str_value", 1: "pos_num_value", 2: "pos_date_value", 3: "pos_num_value" });
|
||
//Перечисление Доп. свойства "Исходящее значение дополнительного словаря"
|
||
export const DP_RETURN_VALUE = Object.freeze({ 0: "str_value", 1: "num_value", 2: "date_value", 3: "num_value" });
|
||
|
||
//-----------
|
||
//Тело модуля
|
||
//-----------
|
||
|
||
//Формирование массива из 0, 1 и более элементов
|
||
export const makeArray = arr => {
|
||
return arr ? (arr.length ? arr : [arr]) : [];
|
||
};
|
||
|
||
//Конвертация формата HEX в формат RGB
|
||
const convertHexToRGB = hex => {
|
||
let r = parseInt(hex.slice(1, 3), 16);
|
||
let g = parseInt(hex.slice(3, 5), 16);
|
||
let b = parseInt(hex.slice(5, 7), 16);
|
||
let a = 0.5;
|
||
r = Math.round((a * (r / 255) + a * (255 / 255)) * 255);
|
||
g = Math.round((a * (g / 255) + a * (255 / 255)) * 255);
|
||
b = Math.round((a * (b / 255) + a * (255 / 255)) * 255);
|
||
return "rgb(" + r + ", " + g + ", " + b + ")";
|
||
};
|
||
|
||
//Считывание заливки события по условию
|
||
export const getTaskBgColorByRule = (task, colorRule) => {
|
||
//Инициализируем значения
|
||
let ruleCode = "";
|
||
//Исходя из типа определяем наименование
|
||
switch (colorRule.STYPE) {
|
||
case "number":
|
||
ruleCode = `N${colorRule.SFIELD}`;
|
||
break;
|
||
case "date":
|
||
ruleCode = `D${colorRule.SFIELD}`;
|
||
break;
|
||
default:
|
||
ruleCode = `S${colorRule.SFIELD}`;
|
||
break;
|
||
}
|
||
//Определяем цвет заливки
|
||
let bgColor = ruleCode && task.docProps[ruleCode] == colorRule.fromValue ? convertHexToRGB(colorRule.SCOLOR) : null;
|
||
//Возвращаем цвет заливки
|
||
return bgColor;
|
||
};
|
||
|
||
//Индикация истечения срока отработки события
|
||
export const getTaskExpiredColor = task => {
|
||
//Определяем текущую дату
|
||
let sysDate = new Date();
|
||
//Определяем дату истечения срока события
|
||
let expireDate = task.dExpireDate ? new Date(task.dExpireDate) : null;
|
||
//Если дата истечения срока определена
|
||
if (expireDate) {
|
||
//Определяем разницу между датами
|
||
let daysDiff = ((expireDate.getTime() - sysDate.getTime()) / (1000 * 60 * 60 * 24)).toFixed(2);
|
||
//Если разница меньше 0 - срок истечен
|
||
if (daysDiff < 0) return TASK_COLORS.EXPIRED;
|
||
//Если разница меньше 4 - скоро истечет
|
||
if (daysDiff < 4) return TASK_COLORS.EXPIRES_SOON;
|
||
}
|
||
return null;
|
||
};
|
||
|
||
//Цвет из hsl формата в rgba формат
|
||
const convertHslToRgba = (h, s, l) => {
|
||
s /= 100;
|
||
l /= 100;
|
||
const k = n => (n + h / 30) % 12;
|
||
const a = s * Math.min(l, 1 - l);
|
||
const f = n => l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
|
||
return `rgba(${Math.floor(255 * f(0))},${Math.floor(255 * f(8))},${Math.floor(255 * f(4))},0.3)`;
|
||
};
|
||
|
||
//Формирование случайного цвета
|
||
export const getRandomColor = index => {
|
||
const hue = index * 137.508;
|
||
return convertHslToRgba(hue, 50, 70);
|
||
};
|
||
|
||
//Формат дополнительного свойства типа число (длина, точность)
|
||
const formatRegExpNum = (width, precision) =>
|
||
new RegExp("^(\\d{1," + (width - precision) + "}" + (precision > 0 ? "((\\.|,)\\d{1," + precision + "})?" : "") + ")?$");
|
||
|
||
//Формат дополнительного свойства типа строка (длина)
|
||
const formatRegExpStr = length => new RegExp("^.{0," + length + "}$");
|
||
|
||
//Проверка валидности числа
|
||
const isValidNum = (width, precision, value) => {
|
||
return formatRegExpNum(width, precision).test(value);
|
||
};
|
||
|
||
//Проверка валидности строки
|
||
const isValidStr = (length, value) => {
|
||
return formatRegExpStr(length).test(value);
|
||
};
|
||
|
||
//Признак ошибки валидации
|
||
export const validationError = (value = "", format, numWidth, numPrecision, strLength) => {
|
||
//Исходим от формата
|
||
switch (format) {
|
||
//Проверка строки
|
||
case 0:
|
||
return isValidStr(strLength, value);
|
||
//Проверка числа
|
||
case 1:
|
||
return isValidNum(numWidth, numPrecision, value);
|
||
//Остальное не проверяем
|
||
default:
|
||
return true;
|
||
}
|
||
};
|
||
|
||
//Конвертация времени в привычный формат
|
||
export const formatSqlDate = timeStamp => {
|
||
//Если есть разделитель
|
||
if (timeStamp.indexOf(".") !== -1) {
|
||
//Определяем секунды
|
||
let seconds = 24 * 60 * 60 * timeStamp;
|
||
//Определяем часы
|
||
const hours = Math.trunc(seconds / (60 * 60));
|
||
//Переопределяем секунды
|
||
seconds = seconds % (60 * 60);
|
||
//Определяем минуты
|
||
const minutes = Math.trunc(seconds / 60);
|
||
//Определяем остаток секунд
|
||
seconds = Math.round(seconds % 60);
|
||
//Форматируем
|
||
const formattedTime = ("0" + hours).slice(-2) + ":" + ("0" + minutes).slice(-2) + ":" + ("0" + seconds).slice(-2);
|
||
//Возвращаем результат
|
||
return formattedTime;
|
||
}
|
||
return timeStamp;
|
||
};
|
||
|
||
//Считывание значений из локального хранилища
|
||
export const getLocalStorageValue = (sName, defaultValue = null) => {
|
||
return localStorage.getItem(sName) ? localStorage.getItem(sName) : defaultValue;
|
||
};
|
||
|
||
//Форматирование фильтра в массив для отбора
|
||
export const convertFilterValuesToArray = filterValues => {
|
||
//Инициализируем значение "с" состояния ("Все", "Не аннулированные" - 0, "Аннулированые" - 1)
|
||
let nClosedFrom = filterValues.sState ? ([EVENT_STATES[0], EVENT_STATES[1]].includes(filterValues.sState) ? 0 : 1) : 0;
|
||
//Инициализируем значение "по" состояния ("Все", "Аннулированные" - 1, "Не аннулированные" - 0)
|
||
let nClosedTo = filterValues.sState ? ([EVENT_STATES[0], EVENT_STATES[2]].includes(filterValues.sState) ? 1 : 0) : 0;
|
||
//Формируем массив значений фильтра
|
||
let filterValuesArray = [
|
||
{ name: "NCLOSED", from: nClosedFrom, to: nClosedTo },
|
||
{ name: "SEVTYPE_CODE", from: filterValues.sType, to: null },
|
||
{ name: "NCRN", from: filterValues.sCrnRnList, to: null },
|
||
{ name: "SSEND_PERSON", from: filterValues.sSendPerson, to: null },
|
||
{ name: "SSEND_DIVISION", from: filterValues.sSendDivision, to: null },
|
||
{ name: "SSEND_USRGRP", from: filterValues.sSendUsrGrp, to: null },
|
||
{ name: "NLINKED_RN", from: filterValues.sDocLink, to: null }
|
||
];
|
||
return filterValuesArray;
|
||
};
|
||
|
||
//Формирование массива действий карточки события
|
||
export const makeCardActionsArray = (onEdit, onEditClient, onDelete, onStateChange, onReturn, onSend, onNotesOpen, onFileLinksOpen) => {
|
||
//Формируем список действий карточки
|
||
return [
|
||
{
|
||
method: "EDIT",
|
||
name: "Исправить",
|
||
icon: "edit",
|
||
visible: false,
|
||
delimiter: false,
|
||
tasksReload: false,
|
||
needAccountsReload: false,
|
||
func: onEdit
|
||
},
|
||
{
|
||
method: "EDIT_CLIENT",
|
||
name: "Исправить в разделе",
|
||
icon: "edit_note",
|
||
visible: true,
|
||
delimiter: false,
|
||
tasksReload: false,
|
||
needAccountsReload: false,
|
||
func: onEditClient
|
||
},
|
||
{
|
||
method: "DELETE",
|
||
name: "Удалить",
|
||
icon: "delete",
|
||
visible: true,
|
||
delimiter: true,
|
||
tasksReload: true,
|
||
needAccountsReload: false,
|
||
func: onDelete
|
||
},
|
||
{
|
||
method: "TASK_STATE_CHANGE",
|
||
name: "Перейти",
|
||
icon: "turn_right",
|
||
visible: true,
|
||
delimiter: false,
|
||
tasksReload: true,
|
||
needAccountsReload: true,
|
||
func: onStateChange
|
||
},
|
||
{
|
||
method: "TASK_RETURN",
|
||
name: "Выполнить возврат",
|
||
icon: "turn_left",
|
||
visible: true,
|
||
delimiter: false,
|
||
tasksReload: true,
|
||
needAccountsReload: true,
|
||
func: onReturn
|
||
},
|
||
{
|
||
method: "TASK_SEND",
|
||
name: "Направить",
|
||
icon: "send",
|
||
visible: true,
|
||
delimiter: true,
|
||
tasksReload: true,
|
||
needAccountsReload: true,
|
||
func: onSend
|
||
},
|
||
{
|
||
method: "NOTES",
|
||
name: "Примечания",
|
||
icon: "event_note",
|
||
visible: true,
|
||
delimiter: true,
|
||
tasksReload: false,
|
||
needAccountsReload: false,
|
||
func: onNotesOpen
|
||
},
|
||
{
|
||
method: "FILE_LINKS",
|
||
name: "Присоединенные документы",
|
||
icon: "attach_file",
|
||
visible: true,
|
||
delimiter: false,
|
||
tasksReload: false,
|
||
needAccountsReload: false,
|
||
func: onFileLinksOpen
|
||
}
|
||
];
|
||
};
|