Мобильная Торговля
Версия
Модульные отчеты

modular_reports.js - это библиотека, позволяющая создавать модульные отчеты
Модули — это самостоятельные блоки интерфейса, которые состоят из JS-скрипта и HTML-шаблона. Также в модуль можно включить дополнительные CSS и JS-файлы.

Преимущества использования модулей

  • Ускорение загрузки отчетов (загрузка по запросу).
  • Конфигурирование отчетов под требования клиентов (например, добавить инди-модули в дополнение к стандартным).

Принцип работы

  1. Дата-скрипт считывает из манифеста список модулей.
  2. Для каждого модуля шаблонизатор создает HTML-элемент с кнопкой.
  3. По клику на кнопку, в дата-скрипте подключается модуль и исполняется его код.
  4. В HTML возвращаются данные для вставки.

Как создать модульный отчет:

Модульный отчет имеет следующую структуру:

my_report
├──my_report.js
├── my_report.html
├── modules
│   └── my_module
│      ├── my_module.html
│      └── my_module.js
└── manifest.json

Манифест модульного отчета выглядит следующим образом и может иметь нижеследующие поля:

{
"uri": "stmobile://report/outletreports/myreport",
...
"config": {
"settingsKey": "myreport_open_modules",
"modules": [
{
"name": "my_module",
"position": 1,
"uiName": "qsTr(My module)",
"visibilityCheck": true,
"reloadCheck": "self",
"isDisabled": false,
"collapsingState": "open",
"features": [
"featureFlag1",
"featureFlag2"
]
}
]
}
}

Обязательные параметры

  • name - Имя модуля (в этом примере - "my_module"). Должно быть таким же, как и имя папки с файлами модуля.
  • position - Определяет порядок сортировки. Чем меньше число, тем ближе к началу. Можно задавать дробные и отрицательные числа.
  • uiName - Название, которое будет отображено в интерфейсе. Можно указать строку или ключ для перевода через lng-файлы.

Дополнительные параметры

  • visibilityCheck - boolean. Нужна ли проверка на отображение модуля. Если задано true, при подключении будет запущена проверка, от результата которой зависит будет ли отображен модуль.
  • reloadCheck - "self" или "full". Нужна ли проверка на необходимость перезагрузки модуля при возврате в отчет.
  • isDisabled - boolean. Если установлено значение true, модуль не будет загружен.
  • collapsingState - "open" или "closed". Определяет состояние свернутости/развернутости блока при открытии страницы отчета (например, при значении open блок будет развернут независимо от того закрывал ли его пользователь ранее).\ В случае, если свойство не указано (или значение некорректно) применяется стандартный механизм, сохраняющий состояние, установленное пользователем в ходе работы (по умолчанию блоки свернуты).
  • features - string[]. Список фиче-флагов необходимых для работы модуля. Модуль загрузится, если хотя бы один фиче-флаг из списка будет включен.

Подключение обработчика модульных отчетов

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

<link type="text/css" rel="stylesheet" href="{{libPath}}/libs/modular_reports/modular_reports.css">
...
<script type="text/javascript" src="{{libPath}}/libs/modular_reports/modules_handler.js"></script>

Скрипт-обработчик необходимо подключать в конце HTML-файла до закрывающего тега </body>, чтобы исключить обращение скрипта к несуществующим элементам.
Внимание! для корректной работы необходимо подключение MTCHANNEL. Для более подробного описания см. раздел Взаимодействие HTML с Data-скриптом

Структура модуля

Модуль состоит из файлов my_module.js и my_module.html

Файл module_name.js имеет следующую структуру:

// Предоставляет данные для передачи в HTML шаблон
function getData () {
return {
/*Data to pass into HTML*/
};
}
// Предоставляет текст подзаголовка для модуля(опционально)
function getModuleSubtitle () {
return String;
}
// Проверяет необходимость отображения модуля, если в manifest.json включен флаг visibilityCheck
function shouldBeVisible () {
return Boolean;
}
// Проверяет необходимость перезагрузки модуля, если в manifest.json значение reloadCheck задано как "self" или "full"
function shouldReloadPage () {
return Boolean;
}
module.exports = {
getData,
getModuleSubtitle,
shouldBeVisible,
shouldReloadPage,
};

Обязательно необходимо экспортировать getData (а также и другие методы модулей, к которым будет необходим доступ из HTML-файла)

При необходимости подключения дополнительных скриптов или стилей в теле модуля допускается использование следующего решения:

var extensionsPath = api.warp.app.absolutePath("script").value,
moduleCSS = api.textfile.read(extensionsPath + "/modules/module_name/module_name.css");

Переменную moduleCSS необходимо сделать одним из свойств объекта, возвращаемого getData().

Подключение стиля производится следующим образом:

<style>
{{moduleCSS|safe}}
</style>

Методы библиотеки modular_reports.js

loadModulesHTML()
Выполняет загрузку инициализацию всех модулей и раскрывает их при необходимости.

 Возвращает HTML-код, который необходимо вставить в основной HTML-файл отчета следующим образом:
{{modules|safe}}

Пример вызова:

mapper.modules = loadModulesHTML();

getModule(moduleName)
Возвращает HTML-код с содержимым модуля

  • moduleName - Строка с названием модуля, содержимое которого надо загрузить.

getModulesToReload()
Возвращает массив названий модулей, которые необходимо перезагрузить при изменении данных. В случае, если находится модуль, требующий полной перезагрузки отчета, перезагружает отчет.

callModuleFunction(args)
Служит для вызова какой-либо функции модуля из HTML-файла.

  • args - это объект следующего вида:
{
moduleName: "my_module" // Название модуля
functionName: "my_function" // Имя вызываемой функции
functionArgs: [] // Аргументы вызываемой функции
}

saveOpenModules(modules)
Сохраняет названия открытых модулей в файле конфигурации.

  • modules - массив строк с названиями модулей

Методы обработчика модульности modules_handler.js

loadAllModules()
Восстанавливает сохраненное состояние модулей - загружает содержимое и раскрывает модули, открытые при последней работе с отчетом.

Должна вызываться следующим образом в основном HTML-файле отчета:

$(function() {
window.setTimeout(loadAllModules, 300);
})

300 - это таймаут для вызова в милисекундах. Необходимо для корректной подгрузки и работы обработчика модулей.

callModuleFunction(options, callback)
Служит для вызова какой-либо функции модуля в отдельном потоке.
Внимание! Не рекомендуется объявлять глобальные переменные в модульных отчетах, т.к. они доступны только в основном потоке.

  • options Объект, содержащий параметры вызова функции.
    {
    moduleName: "my_module", // Название модуля
    functionName: "my_function", // Имя вызываемой функции
    functionArgs: [] // Аргументы вызываемой функции
    }
  • callback Функция, вызываемая по окончанию работы метода модуля.

callMainThreadFunction(options, callback) Служит для вызова какой-либо функции модуля в основном потоке

  • options Объект, содержащий параметры вызова функции.
    {
    moduleName: "my_module", // Название модуля
    functionName: "my_function", // Имя вызываемой функции
    functionArgs: [] // Аргументы вызываемой функции
    }
  • callback Функция, вызываемая по окончанию работы метода модуля.

Добавление нового модуля в серийный отчет при индивидуальном конфигурировании

Для того чтобы новый модуль работал совместно с серийными модулями, необходимо создать манифест без указания data-скрипта.

Пример манифеста:

{
"uri": "stmobile://report/outletreports/outletcard",
"type": "report",
"config": {
    "settingsKey": "taskNumber_taskDescriptionShort",
    "modules": [
            // индивидуальный модуль
            {
                "name": "new_module",
                "position": 1,
                "uiName": "qsTr(New module)",
                "visibilityCheck": true,
                "features": [
                    "moduleRequiredFeatureFlag"
                ]
            },
            // серийные модули
            {
                "name": "limits",
                "position": 2,
                "uiName": "qsTr(Limits)",
                "visibilityCheck": true
            },
            {
                "name": "visits_calendar",
                "position": 3,
                "uiName": "qsTr(Visits calendar)"
            }
        ]
    }
}

Расположить манифест и файлы нового модуля по пути:

extensions
└── modules
└── taskNumber_taskDescriptionShort // имя папки должно совпадать с полем settingsKey в манифесте
├── new_module // имя папки должно совпадать с полем name в манифесте
|   ├── new_module.html // имя файла должно совпадать с полем name в манифесте
 |   └── new_module.js // имя файла должно совпадать с полем name в манифесте
└── manifest.json

Внимание! При изменении серийного модуля необходимо, чтобы название измененного модуля отличалось от серийного