Шаблоны заявок: создание и редактирование

Типы данных для заполнения:

MfpcInputsInterface {
  type:
    | 'static'// статичный текст
    | 'text' // текстовое поле
    | 'password' // поле ввода пароля
    | 'number' // числовое поле ввода
    | 'datepicker' // выбор даты
    | 'datepicker-range-start' // выбор стартовой даты для диапазона дат
    | 'datepicker-range-end' // выбор конечной даты для диапазона дат
    | 'file' // загрузка файла
    | 'file-multi' // множественная загрузка файлов
    | 'textarea' // многострочное поле ввода
    | 'checkbox' // чекбокс
    | 'radio' // радио-кнопки
    | 'select' // выпадающий список
    | 'select-multi' // выпадающий список с множественным выбором
    | 'select-filter' // выпадающий список с фильтрацией и множественным выбором
    | 'arr-smart'; // группа произвольных полей
  formControlName?: string; // отвечает за наименования ключа данных в паре ключ-значение
  label?: string; // отвечает за название поля в интерфейсе
  value?: string; // предустанавливает значение поля
  placeholder?: string; // отображаемый текст в подсказке к полю ввода
  optionList?: { value: string | number; title: string }[]; // элементы выпадающего списка для типа 'select' и 'select-filter'
  optionListRequestAlias?: string; // алиас, строковое значение ключа для получения элементов выпадающего списка для типа 'select' и 'select-filter' с помощью метода GET /wa_issueTypes/optionList/<alias>
  selectMultiple?: boolean; // Параметр, отвечающий за включение режима выбора нескольких элементов выпадающего списка
  selectParentTree?: boolean; // Параметр, отвечающий за включение вида иерархического списка у элемента <select>. Формирование происходит по параметру parentID
  autoSelectFirst?: boolean; // Параметр, отвечающий за включение режима автоматического выбора перовго значения выпадающего списка(работает только, если поле "select" скрыто).
  gridClasses?: string[]; // css-класс, отвечающий за размер поля ввода в соответствии со спецификацией Bootstrap Grid
  validations?: ValidationTypes[0][]; // значения отвечающие за работу валидации текущего поля ввода, описаны ниже в блоке "ValidationTypes". Не допускается пустое значение, только пустой массив - [ ]
  errorMessages?: { [key: string]: string }; // Сообщения об ошибках для конкретных валидаторов
  hintMessage?: string; // Сообщение под текущим полем ввода
  icon?: { name: string; clearMode: boolean }; // name - название иконки из коллекции Material Icons, для отображения внутри поля; clearMode - будут ли стираться введенные в поле данные при нажатии на иконку
  disabled?: boolean; // Заблокировано ли поле
  edited?: boolean; // поле разрешено для редактирования (если false - поле отображается как текст)
  startDateControl?: string; // formControlName поля типа "datepicker-range-start", если текущее поля является типом "datepicker-range-end", для парного взаимодействия
  endDateControl?: string; // formControlName поля типа "datepicker-range-end", если текущее поля является типом "datepicker-range-start", для парного взаимодействия
  startDateMathDay: number |
    {
      type: 'month' | 'year';
      count: number;
    };
    // Значения для корректировки минимально допустимого значения даты, высчитывается от текущей даты в днях, допускаются отрицательные значения
    // При указании объекта можно указать конец/начало текущего/следующего/предыдущего месяца/года.
    // Где count: -1 - начало предыдущего периода, 0 - начало текущего периода, 1 - конец текущего периода, 2 - конец след периода и тд. (например {"type": "month", "count": 1} - конец текущего месяца, а {"type": "year", "count": 0} - начало текущего года)
  endDateMathDay: number |
    {
      type: 'month' | 'year';
      count: number;
    };
    // Значения для корректировки максимально допустимого значения даты, высчитывается от текущей даты в днях, допускаются отрицательные значения
    // При указании объекта можно указать конец/начало текущего/следующего/предыдущего месяца/года.
    // Где count: -1 - начало предыдущего периода, 0 - начало текущего периода, 1 - конец текущего периода, 2 - конец след периода и тд. (например {"type": "month", "count": 1} - конец текущего месяца, а {"type": "year", "count": 0} - начало текущего года)   minReferenceDateControl?: string; // formControlName поля типа "datepicker", которое будет являться точкой отсчета даты через "startDateMathDay", без указания значения - точкой отсчета будет считаться сегодняшняя дата
  maxReferenceDateControl?: string; // formControlName поля типа "datepicker", которое будет являться точкой отсчета даты через "endDateMathDay", без указания значения - точкой отсчета будет считаться сегодняшняя дата
  mask?: string; // шаблон для маски ввода
  fileTypesAccept?: string; // перечисление расширений файлов доступных для выпора в поле 'file' и 'file-multi'. Формат записи: {"fileTypesAccept": ".png, .jpg, .gif"}
  arrSmartList?: MfpcInputsInterface[]; // Массив "MfpcInputsInterface" для создания вложенных данных (интерфейс фэктори, где с помощью "+/-" можно добавлять и удалять строки с полями ввода)
  arrSmartOpened?: number; // Количество открытых элементов списка arr-smart во время создания формы
  requiredToFill?: string[]; // Принимает массив formControlName. Поле становится заблокированным, пока хотябы одино из перечисленных полей (formControlName) не заполнено.
  dependent?: { // Принимает массив объектов, для создания зависимостей полей ввода. Варианты зависимости: 1) отображение поля по условию, 2) клонирование значения
    control: string; // Название (formControlName) зависимого поля ввода. Обязательно для заполнения при создании зависимости.
    condition?: string; // Условия для отображения зависимого поля. Строковое значение, синтаксис формирования условия смотри ниже под заголовком (Синтаксис условия созависимых полей)
    clone?: boolean; // Принимает значение true или false. Указанный control ВСЕГДА принимает значение текущего поля ввода. Одновременно может быть указано либо свойство clone для создания клона, либо condition для создания условия отображения зависимого поля.
  }[];
  onlyFirst?: boolean; // Используется только в типе arr-smart для блокировки текущего поля в списке, кроме 1го значения (пример - заявка на работу в выходной, выбор типа компенсации открыт только в первой опции)
  optionListRequestParams?: { // Создает зависимость списка выбора (select, select-filter, select-multi) от значения другого поля ввода/списка (см. раздел "Примеры" ниже)
    name: string; // Название параметра, который будет добавляться к запросу на список выбора (по optionListRequestAlias)
    control: string; // Название (formControlName) поля ввода, значение которого будет отправляться по параметру указанному выше для получение списка выбора
  }[];
  dateHighlightType?: "none" | "common" | "schedule"; // Выделение выходных дней в календаре, По-умолчанию принимает значение 'common'. 'none' - не выделять выходные, 'common' - выделять выходные по производственному календарю, 'schedule' - выделять выходные по рабочему/индивидуальному графикам.
}
ValidationTypes {
  [x: number]:
    | 'required' // Проверка на заполненность поля (ошибка если пустое)
    | 'email' // Являются ли данные email-адресом
    | { "min": number } // Минимальное значение (число или дата), если меньше, то ошибка
    | { max: number } // Максимальное значение (число или дата), если больше, то ошибка
    | { minLength: number } // Минимальная длина данных (например, для слова "Москва", minLength = 6), если меньше, то ошибка
    | { maxLength: number } // Максимальная длина данных (например, для слова "Москва", minLength = 6), если больше, то ошибка
    | { pattern: string } // Регулярное выражение для проверки значения, если проверка не пройдена, то ошибка
    | { filesType: string }; // Разрешенные типы файлов для полей ввода типа 'file' и 'multi-file'. Формат ввода: {"filesType": ".png, .jpg"}
    | { "notEqual": string } // Запрет на равенство текущего поля ввода с указанное (например, для запрета равенства текущего поля ввода с полем ввода formControlName "date2", { "notEqual": "date2" }), если значения полей равны, то ошибка
    | "needToBeChanged" // Проверка на то, что значение в поле изменилось (ошибка, если значение осталось тем же)
    | "dynamic-required" // Тот же required, НО для динамических полей, т.е. если динамическое поле скрыто и не заполнено, то не является обазательным
    | { "date": "dayoff" | "workday" | number[] } // для календаря (datepicker) позволяет ограничить выбор даты. Принимаемы значения "dayoff" - позволяет выбирать только выходной/праздничный день, "workday" - только рабочие дни, number[] - массив дней недели, которые разрешено выбрать (0 - ВС, 1 - ПН, ..., 6 - СБ. Т.е. для ограничения выбора только суббот и воскресений - [0, 6], только понедельники - [1] и тд.)
    | { "workSchedule": true | false } // УСТАРЕВШИЙ. Лучше использовать синхронный валидатор (см. строку ниже). Учет рабочего/индивидульного графиков работы при выборе дат. Нежелательно использование вместе с валидатором "date". При установке true - потребует выбора рабочего дня по графику, при установке false - выходного дня по графику.
    | { "syncWorkSchedule": "dayoff" | "workday" | number[] } // Синхронный валидатор. Работает в версиях 1.38.0 и выше. Учет рабочего/индивидульного графиков работы при выборе дат. Нежелательно использование вместе с валидатором "date". Для календаря (datepicker) позволяет ограничить выбор даты. Принимаемы значения "dayoff" - позволяет выбирать только выходной/праздничный день, "workday" - только рабочие дни
    | {"pattern": "^(!?[^а-яА-ЯёЁ]+)$"} // валидатор на отсутствие кириллицы в поле ввода.
    | {"pattern": "^(!?[^a-zA-Z]+)$"} // валидатор на отсутствие латиницы в поле ввода.
    | { "periodsGap": { "end": string, "gap"?: number, "less"?: boolean, "exclude"?: string[]  } } // Валидатор ограничения между разрывами периодов в массиве с datepicker-range. end - название контрола окончания промежутка, остальные параметры необязательные (gap - количество допустимых дней разрыва, less - булево значение допускающее разрыв не только конкретного числа дней, но и меньше чем это число, exclude - массив с типами дней workDay, holiday или dayOff, которые исключаются из подсчета дней в разрыве). См. пример использования ниже. 
}

Форматы даты:

"type":"datepicker-year" 
 | "format": "yyyy" // отправки даты в формате ГГГГ
 | "format": "dd.mm.yyyy" // отправки даты в формате ДД.ММ.ГГГГ
 | "format": "mm.yyyy" // отправки даты в формате ММ.ГГГГ
 
 СПРАВОЧНО: доступные варианты указания дат см. https://angular.io/api/common/DatePipe 

Перечень полей для сопоставления:

userID - ID пользователя (физического лица)
EmployeeID - ID сотрудника
issueTypeID- ID типа заявки
dateBegin - дата начала
dateEnd - дата окончания
message - произвольное сообщение пользователя (в ряде случаев "Причина", где заполняется пользователем)
vacationTypeID - ID вида отпуска
payType1 - код вида оплаты за работу в выходной 1: 0 - Двойная оплата, 1 - дополнительный выходной
payType2 - код вида оплаты за работу в выходной 2: 0 - Двойная оплата, 1 - дополнительный выходной
dayOff1 - дата дополнительного выходного 1
dayOff2 - дата дополнительного выходного 2
stateCity - Страна/город
purpose - цель поездки
purposeOther - произвольное сообщение, если пользователь в качестве цели поездки выбрал "Другое"

Настройки (options) - правое поле ввода:

Содержит в себе технические настройки для обмена данными клиент-сервер, а так же для настройки отображения вспомогательной информации и элементов интерфейса

{
"changeStrategy": "push", // политика обновления шаблонов формы в веб-приложении созданного на ts-фреймворке Angular
"appearanceElements": "outline", // описание внешнего вида полей формы, реализованных на компонентах Angular Material (см. https://material.angular.io/components/form-field/overview#form-field-appearance-variants)
"editMode": boolean, // разрешить редактирование
"viewMode": "edit" | "show", // режим работы формы: просмотр или редактирование. Режим просмотра преобразует поля формы в статические html-объекты
"staticInfo": string[], // перечисление дополнительной информации, см. ниже
"loadFileType": "base64", // ОБЯЗАТЕЛЬНЫЙ параметр для работы с файлами, указывающий какой метод использовать для работы с текстовыми файлами и/или изображениями
"showProfileButton": boolean // Показывать ли кнопку для перехода в профиль пользователя
"submitDebounceTime"?: boolean; // Включает автоматическую отправку формы после ввода данных в поле (без кнопки "отправить")
"vacationSchedule" //выводит периоды запланированного отпуска на форму заявки.
"markRequired": boolean; выводиь знак * рядом с обязательными полями
}

Для отображения данных в правой части интерфейса заявки необходимо добавить атрибут из списка ниже в интерфейсе options:

Настройка статической информации

Статическая информация настраивается теперь через справочник Поля статической информации.

По умолчанию в справочнике есть поля "предопределенной" статической информации, которые заполняются по кадровым данным и по данным остатков отпусков, их нельзя выключить и настроить. По ним можно настроить только наименования на различных языках:

Также в справочник можно добавить произвольные поля с произвольным кодом:

Для таких полей можно включить/выключить видимость, а также настроить код получения данного поля.

Затем данные поля заполняются в типах заявок, указав идентификаторы полей статической информации:

(Архив)Перечень полей для вывода статических данных:

{
"employeeID": "333da084-7bff-11e2-9362-001b11b25590",
"userID": "333da085-7bff-11e2-9362-001b11b25590",
"fullName": "Минчев Аристотель Борисович",
"position": "Первый заместитель генерального директора",
"employmentDate": "2010-01-25T00:00:00",
"salary": 70000,
"passRepresentation": "Паспорт гражданина РФ, серия: 12 34, № 111102, выдан: 01 января 2000 года, ПВР №1",
"registrationAddress": "РОССИЯ, 105122, Москва г, Амурская ул, дом № 1, квартира 1",
"surname": "Минчев",
"familyStatus": "Состоит в зарегистрированном браке",
"country": "РОССИЯ",
"email": "KIS_test@wiseadvice.ru",
"cellPhone": null,
"vacationBalance": "0 д."
}

Пример заполнения текстового описания:

{
    "type": "static",
    "label": "Заголовок",
    "value": "Произвольное описание чего-то неопределенного",
    "gridClasses": ["col-md-12"],
}

Отображение остатка отпуска, дополнительного отпуска и остатков отгула

additionalVacationBalance - остаток доп отпуска (определяется по тем видам отпусков, у которых НЕТ флага Основной отпуск)

dayOffBalance - остаток дней отгулов

(+ изменен параметр vacationBalance - там теперь остаток только основного отпуска).

В тип заявки можно добавить новые параметры в поля статической информации и они выведутся:

Доработка со стороны фронта:

Запрос /staticData теперь отдает еще поля additionalVacationBalance и dayOffBalance 👍

Синтаксис условия созависимых полей

Условие для динамического отображения является строкой с условием, результатом которого должно быть значение ИСТИНА или ЛОЖЬ (стандартное условие).

ВАЖНО! Созависимые и изначально скрытые поля - должны быть указаны в шаблоне как и стандартные поля. Для начального скрытия их при первой загрузке, рекомендуется в свойство gridClasses добавить значение hidden в зависимом поле ввода ("gridClasses": ["hidden"], помимо hidden могут быть и стандартные классы, указывающие ширину поля ввода).

ВАЖНО! Значение для создания условий созависимых полей - должно соответствовать значению (а не представлению), заполненному в поле.

Разделение логических приоритетов выполняется круглым скобками - "(условие1 || условие2) && условие3 && !условие4"

=== - проверка равенства значений;
!== - проверка неравенства значений;
> - больше;
< - меньше;
<= - меньше равно;
>= - больше равно;
|| - ИЛИ;
&& - И;
! - НЕ;
$V - значение текущего поля ввода;
$T - зачение типа выбранной даты (варианты: приздничный день - 'holiday', рабочий день - 'workDay', выходной - 'dayOff')
m(ЗНАЧЕНИЕ) - функция преобразования строкового ЗНАЧЕНИЯ в дату. Строка передается между круглых скобок (пример m($V) - для datepicker преобразовать значение в дату. m() - получение текущей даты);
m(ЗНАЧЕНИЕ).day() - получение выбранного дня недели (начиная с воскресенья, т.е. 0 - ВС, 1 - ПН, ..., 6 - СБ);

Синтаксис создания запрета разрыва периодов

Примеры:

// Запрет разрыва периодов и отображение сообщения при нарушении валидатора
{
  "type":"datepicker-range-start",
  "formControlName":"dateBegin",
  "validations": [{ "periodsGap": { "end": "dateEnd" }],
  "errorMessages": { "periodsGap": "Начало периода должно быть следующим днем от завершения предыдущего периода" }
  ...
},
{
  "type":"datepicker-range-end",
  "formControlName":"dateEnd",
  ...
}, ...
 
 
// Продвинутый запрет разрыва периодов, исключающий из подсчета выходные и праздничные дни, а так же ограничивает разрыв между периодами 3мя днями (от 0 до 3х дней)
{
  "type":"datepicker-range-start",
  "formControlName":"dateBegin",
  "validations": [{ "periodsGap": { "end": "dateEnd", "gap": 3, "less": true, "exclude": ["dayOff", "holiday"] }]
  ...
},
{
  "type":"datepicker-range-end",
  "formControlName":"dateEnd",
  ...
}, ...  

Last updated