/* Парус 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 } ]; };