Настройка навигатора в Showcase

Материал из Course Orchestra
Перейти к: навигация, поиск
Showcase

Создание решений на КУРС:Showcase

Создание навигатора

Описание навигатора может:

  • находиться в xml файле в папке userdata/navigatorstorage;
  • возвращаться Celesta-скриптом;
  • возвращаться jython-скриптом;
  • возвращаться хранимой процедурой вида:
CREATE PROC 
	@session_context xml='',
	@data xml ='' output
  • возвращаться при выполнении SQL скрипта с теми же параметрами, что и для хранимой процедуры + 2 стандартных параметра для возврата ошибок их БД.

Выбор источника, из которого будет идти загрузка данных, определяется согласно принципу универсальных источников.

Структура навигатора

См. схему navigator.xsd.

Навигатор состоит из групп, в каждой из которых находится иерархическое "дерево". Навигатор задается при помощи хранимой процедуры на сервере. Имя хранимой процедуры указывается в параметре navigator.proc.name в файле "app.properties" в папке userdata. На вход процедуры передается контекст сессии в переменной @session_context (внутри данного параметра, в частности, содержится имя пользователя, для которого необходимо построить навигатор). Процедура возвращает данные в xml-формате в output параметре @navigator. Примерный вид xml-файла для задания навигатора:

<?xml version="1.0" encoding="UTF-8"?>
<navigator width="100px" hideOnLoad="true">
    <group id="22221" name="Регионы" icon="Default.png">
        <level1 id="22222" name="г. Москва">
            <level2 id="11115" name="СЗАО" selectOnLoad="true"/>
        </level1>
        <level1 id="22223" name="Ярославская область">
            <level2 id="22224" name="Заволжский район" >
	        <action>
                    <main_context>проект=150</main_context>
                    <datapanel type="a.xml" tab="код вкладки" dataPanelCaching="true">                        
                        <element id="код элемента">
                              <add_context>SQL-условие</add_context>
                        </element>
                        <element id="код элемента">
                              <add_context>SQL-условие</add_context>
                        </element>
                    </datapanel>
                </action>
            </level2>
        </level1>
        <level1 id="11117" name="Краснодарский край"> </level1>
    </group>
    <group id="21112" name="Объекты"/>
</navigator>

Дерево должно иметь строго определенную структуру: корневой элемент – navigator (тэг <navigator>), далее идут элементы group (тэг <group>), следующие уровни — level{номер уровня} (тэг <level{номер уровня}>) (например, level1 или level2, до пятого уровня ). Каждый элемент группы или уровня должен иметь уникальный идентификатор, содержащийся в атрибуте id соответствующего тэга (некая уникальная строка для всего навигатора) и подпись для отображения элемента, указываемую в атрибуте name соответствующего тэга. У одного из тэгов <level> может быть атрибут selectOnLoad = "true". Это означает, что при первой загрузке дерева (или обновлении страницы) будет выделен соответствующий уровень (level) в дереве с последующим открытием привязанной к уровню информационной панели. Все элементы дерева могут иметь тэг <action> (см раздел Задание и структура действия), в котором прописываются события при клике на элемент (уровень - level) дерева в навигаторе. В частности, при клике справа от дерева может отображаться информационная панель (datapanel), это событие задается с помощью тэгов <datepanel> внутри тэга <action>. Описание информационной панели соответствующего типа должно находиться в xml-файле в папке userdata\datapanelstorage (имя файла должно быть равно значению, которое будет использоваться в атрибуте type тэга <datapanel> - например, "a.xml" или "b.xml"). Два элемента дерева могут ссылаться как на одну и ту же, так и на разные информационные панели. Параметр tab тэга <datapanel> (id вкладки информационной панели, которая открывается по умолчанию) - необязательный. Если он не задан, то открывается первая вкладка информационной панели.

Атрибут width задает ширину навигатора в пикселях или процентах. В первом случае значение должно содержать префикс "px", во втором - префикс "%". Атрибут hideOnLoad означает, что навигатор должен быть скрыт при загрузке главной страницы. При этом навигатор должен храниться в памяти на клиентской стороне для того, чтобы работали действия (action), связанные с ним, а также на случай, если в будущем появится действие "Показать навигатор".

Описание значений атрибута add_context см в разделе Задание контекста

Начиная с версии 4.1.0.4115 Showcase в тег <datapanel> добавлен атрибут dataPanelCaching, отвечающий за то, кэшировать ли данную информационную панель (значение true) или нет (значение false) (по умолчанию false - кэширования не происходит).

Обратите внимание, что каждому пункту навигатора в dom-модели страницы на клиенте присваивается уникальный идентификатор вида: "gwt-uid-[Number]_navigator_{$id}", где {$id} - id пункта навигатора, указанный при его задании.

Запуск клиентской js-функции при загрузке или обновлении навигатора

Для запуска клиентской js-функции необходимо определить ее в файле solution.js папке пользовательских данных (в папке js перспективы, библиотеки или системной библиотеки). Функция должна называться onLoadNavigator(). Функции не передаются никакие параметры. Данная пользовательская функция будет выполнятся автоматически сразу после загрузки навигатора (после его прорисовки), а также после обновления навигатора используя действие Showcase. Использование данной функции полезно для выдачи сообщений пользователю, выделения пунктов навигатора и т.д.

In-Memory кэширование

Термин In-Memory Caching означает буквально кэширование в оперативную память (в т.н. кучу (heap), выражаясь в терминах java). В данном случае понимается кэширование данных на сервере, а не на клиенте (не путать с кэшированием браузером статического контента приходящего на клиент от сервера - файлов html, js, jpg, png и т.п.). Кэширование в Showcase реализовано с помощью свободной java библиотеки ehcache, которая позволяет организовать кэширование объектов в оперативную память (In-Memory Caching). Данная библиотека обладает гибкими настройками механизма кэширования, позволяет задавать время жизни закэшированных объектов, реализовывать intelligence управление объектами в кэше на основе параметров среды (дисковое пространство, значение ОЗУ) и многое другое.

Обычно, в решениях информационные панели задаются в виде статических xml-файлов. В этом случае каждый раз при открытии информационной панели ее значение считывается с жесткого диска сервера. Если количество пользователей системы не велико, то это не критично. Однако, когда системой пользуется большое количество пользователей, то их одновременная работа может привести к большому количеству чтений одного и того же файла, тем самым нагрузив жесткий диск на сервере. В результате могут возникать задержки в считывании информации (тормоза) и ошибки совместного доступа к файлам. Введение кэширования позволит избавится от этой проблемы. При включенном функционале кэширования файлы информационной панели будут считываться с диска один раз для всех пользователей, из них будет создаваться экземпляр информационной панели, который будет сохраняться в памяти сервера Showcase в объекте cacheManager, который является устойчивым к одновременной многопоточной работе (concurrent). Таким образом чтение с диска, и обработка файлов информационной панели будут происходить один раз, а не при каждом запросе клиентов. Это значительно сократит нагрузку на жесткие диски сервера, и ускорит работу серверной части Showcase.

В случае, когда источником информационной панели выступает скрипт celesta, python или хранимая процедура ситуация усложняется. Действительно, ведь теперь на вход скрипту или хранимой процедуре приходит текущий контекст пользователя (в зависимости от которого скрипты и хранимые процедуры обрабатывают и возвращают необходимые данные). И этот контекст в общем случае может быть разным. Более того, результат работы хранимых процедур и скриптов зависит от значений в базе данных, а также внешних источников данных (например, внешних сервисов у которых скрипты могут брать информацию). Поэтому кэширование происходит не только по названию скрипта (или хранимой процедуры), но и по значению контекста. В этом случае включать функцию кэширования имеет смысл только в том случае, когда хранимые процедуры и скрипты для получения информационной панели не зависят от значений в базе данных или во внешних источниках (но могут зависеть от контекста!), либо эти скрипты статичны.

В зависимости от источника данных кэширование информационных панелей происходит по следующим параметрам (см. таблицу):

Источник задания информационной панели Информация, хранящаяся в ключе кэша
XML-файл Полный путь к файлу на диске сервера
Хранимая процедура в базе данных Название хранимой процедуры + приходящий в неё контекст
Celesta-скрипт / Jython-скрипт Полный путь к скрипту на диске сервера + приходящий в него контекст

По умолчанию кэширование отключено! Включить кэширование можно, прописав атрибут dataPanelCaching в теге <datapanel> при задании навигатора и установив его в true (см. конец предыдущего пункта). Удалить все закэшированные к данному моменту объекты информационных панелей можно, нажав кнопку "Сбросить кэш датапанелей" на странице /control/memory.jsp. Над данной кнопкой отображается число объектов информационных панелей, которые находятся в кэше. Нажатие кнопки "Перезагрузить userdata", помимо всего прочего, также приведёт к сбросу кэша информационных панелей.

На данный момент реализовано кэширование только информационных панелей! Планируется распространить функционал кэширования на другие элементы Showcase.

Кнопки истории переходов «вперед-назад» браузера

Начиная с версии 5.0.0 Showcase добавлена работоспособность кнопок истории переходов «вперед-назад» браузера.

Теперь при переходе по пунктам навигатора, а также по закладкам информационной панели браузер сохраняет историю переходов.

При нажатии на кнопки вперед или назад браузера будет происходить переход на предыдущую или последующую сохраненную позицию.


Переход на JS-навигатор

В рамках перевода пользовательского интерфейса Showcase на JavaScript-библиотеку dojo, начиная с версии DDDDDD, в trunk-ветке Showcase произошел переход на JS-навигатор (раньше навигатор был сделан на основе GWT).

При этом, в xml-описание навигатора добавлены следующие атрибуты

  • в корневой тег <navigator>
    • swapSelectExpand - если равно "false", то при клике на запись отрабатывает action, а при клике на "tree"-картинку происходит раскрытие/закрытие уровня. Если значение равно "true", то наоборот -- при клике на запись происходит раскрытие/закрытие уровня, а при клике на "tree"-картинку отрабатывает action. Значение по умолчанию "false".
  • в тег группы <group>
    • classNameTitle - имя класса стиля заголовка группы,
    • styleTitle - стиль заголовка группы,
    • classNameGrid - имя класса стиля грида,
    • classNameColumn - имя класса стиля ячеек грида,
    • styleColumn - стиль ячеек грида
  • в тег уровня <levelN>
    • closeIcon, openIcon, leafIcon - картинки для закрытого/открытого/"без потомков" уровня (по аналогии с tree-dgrid'ом),
    • classNameRow - имя класса стиля строчки грида, соответствующего данному уровню

Пример

<?xml version="1.0" encoding="UTF-8"?>
<navigator width="230px" swapSelectExpand = "false">

  <group id="00" name="Фичи"
             icon="favicon32.png" 
             classNameTitle="class1" styleTitle="height:37px; font-size: 11pt; font-weight: bold;" 
             classNameGrid="class2"
             classNameColumn="class3" styleColumn=""
  >

     <level1 id="extJsTreePlugin" name="Новый триселектор" selectOnLoad="true"
      	  classNameRow="classNameRow1"
      	  closeIcon="resources/internal/TreeGridJointClose.gif" 
          openIcon="resources/internal/TreeGridJointOpen.gif" 
          leafIcon="resources/internal/TreeGridLeafNode.png"
     >
        <action>
          <main_context>none</main_context>
          <datapanel type="extJsTree.xml" tab="firstOrCurrent" ></datapanel>
        </action>
     </level1>

  </group>

</navigator>

Настройка высоты групп в навигаторе

Для данной юзердаты высота групп навигатора определяется в файле app.properties свойством navigator.group.height, которое может принимать дробные числовые значения, например, 2.3.

Чтобы иконки групп соответствовали размерам группы их следует уменьшить или увеличить, например, с помощью фотошопа. Также следует подбирать размер заголовка группы. Это делается с помощью стилей в файле solution.css данной юзердаты. CSS-класс, соответствующий заголовку группы, называется cw-StackPanelHeader. Пример:

.cw-StackPanelHeader { 
font-size: 10px;
}

Также с помощью стилей можно выставить расстояние между группами (светлые "прослойки"). Наиболее приемлемые настройки, для приведённых выше значений высоты групп и размера шрифта, следующие:

.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader {
	cursor: pointer;
	font-weight: bold;
	font-size: small;
	padding: 1px;
	background: #565c5c;
	border: none;
	height: 25px;
    text-overflow: ellipsis;
    overflow: hidden;
	border-radius: 4px;
}

Главнейшую роль здесь играют параметры padding и height. Изменение их хотя бы на 1-2 пикселя сильно влияет на внешний вид навигатора.