Перед каждым аналитиком возникает выбор представления и формирования информации. Конечно, хочется выбрать более легкий способ, но не всегда этот способ соответствует ожиданиям читающего. В данной статье я поделюсь проблемами, которые были решены в рамках формирования и сопровождения реальных требований. Надеюсь, моя статья вдохновит на использование более сложных инструментов confluence.
Динамический поиск по дочерним страницам
Пространство моего проекта содержит более 800 страниц требований. При использовании стандартного поиска confluence, я столкнулся с проблемой. Дело в том, что поиск выполняется по всему пространству и требует фильтрации для более узкой выборки. Дополнительно, поиск выполняется по содержимому страниц и названиям загруженных файлов. Это не всегда удобно, особенно если необходимо искать страницы в определённой области пространства. В результате была поставлена задача реализовать поиск только по названию страниц.
Для реализации необходимо определить область поиска. У меня это был раздел требований в котором содержались страницы следующей иерархии:
Требования (родительская страница)
Эпик
Фича
User story
Use case
Создаем пустую страницу в любом месте пространства и добавляем макрос «Отображение дочерних»:
![](https://habrastorage.org/getpro/habr/upload_files/075/6a3/0ee/0756a30ee0cca04235c9bdfe2cee91a2.png)
В настройках макроса указываем родительскую страницу. Это будет область нашего поиска. После сохранения на странице отобразятся все дочерние страницы каждого уровня иерархии. Кликаем правой кнопкой на странице и выбираем «Просмотр кода страницы». В коде страницы нам необходимо найти и скопировать все ссылки дочерних страниц в html. Так как на странице много кода, можно воспользоваться поиском по названию одной из страниц. Ссылки на странице размещены одной строкой и содержат лишние теги. С помощью инструментов форматирования html (для массового удаления лишних тегов используем word), код необходимо привести к виду:
<li>
<a href="/pages/viewpage.action?pageId=1">Название страницы 1</a>
<li>
<a href="/pages/viewpage.action?pageId=2">Название страницы 2</a>
<li>
<a href="/pages/viewpage.action?pageId=3">Название страницы 3</a>
</li>
……
Вторым шагом создаем страницу, где будет размещаться наш поиск. На страницу добавляем макрос-рамку «HTML»:
![](https://habrastorage.org/getpro/habr/upload_files/a02/0f0/5c4/a020f05c4833c297612a4bf858691247.png)
Данный макрос выполнит код html, который мы разместим в рамку. В зависимости от ваших потребностей, вы можете разместить любые вспомогательные html-элементы на форме. Реализуем следующим образом:
1) Разместим два раскрывающихся списка (при выборе значения списка, текст подставляется в строку поиска):
<! Выпадающий список с профилем пользователя>
<form><select id="Ultra" style="font-size:18px;" onchange="run1()">
<option value="">Профиль</option>
<option value="Администратор">Администратор</option>
<option value="Пользователь">Пользователь</option>
<option value="Еще профиль">Еще профиль</option>
</select>
<! Выпадающий список с популярными активностями в названиях страниц.
С помощью различных инструментов можно подсчитать количество популярных
слов в наборе ссылок>
<select id="Ultra1" style="font-size:18px;" onchange="run1()">
<option value="">Активность</option>
<option value=" редактирует">редактирует</option>
<option value=" получает">получает</option>
<option value=" создает">создает</option>
</select>
2) Разместим поле для поиска и кнопку «очистить»:
<input style="font-size:18px" type="text" id="mySearch" onkeyup="myFunction()" placeholder="Введите значение" size="40">
<input type="button" value="очистить" onclick="resetForm(this);" style="font-size:15px">
</form>
3) Далее добавим ссылки из первого шага:
<ul id="myMenu">
<li>
<a href="/pages/viewpage.action?pageId=1">Название страницы 1 </a>
<li>
<a href="/pages/viewpage.action?pageId=2"> Название страницы 2 </a>
<li>
<a href="/pages/viewpage.action?pageId=3"> Название страницы 3 </a>
</li>
</ul>
4) Добавляем скрипты для раскрывающихся списков, поиска и кнопки «очистить»:
<script>
function run() {
document.getElementById("mySearch").value = document.getElementById("Ultra").value + document.getElementById("Ultra1").value;
}
</script>
<script>
function myFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("mySearch");
filter = input.value.toUpperCase();
ul = document.getElementById("myMenu");
li = ul.getElementsByTagName("li");
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
function run1() {
run();
myFunction()
}
</script>
<script>
function resetForm(element) {
element.form.reset();
myFunction()
}
</script>
5) Сохраняем страницу и пользуемся.
6*) Для более эстетичного отображения страницы, можно разместить макрос html в рамке макроса Aura Panel.
![](https://habrastorage.org/getpro/habr/upload_files/83e/1ab/fb0/83e1abfb0ac0bd104d493b72c23e0eff.png)
В результате мы реализовали возможность выполнять динамический поиск по заданной области пространства. Я не сомневаюсь, что разработчики и тестировщики оценят такую фичу и будут чаще читать ваши максимально «понятные» требования. Минус данного подхода: при добавлении новых страниц потребуется обновление набора ссылок. Но это займет всего 10 минут вашего времени.
Многоуровневые формы
Часто аналитику требуется объединять большие объёмы сложно читаемых данных. Для этого Сonfluence предоставляет большой набор макросов. Например, с помощью макросов Aura-Tab и Aura-Tab Group можно создать объект с табами. Макросы обладают гибкими настройками, но проблема заключается в одном уровне вложенности создаваемых форм. В результате была поставлена задача реализовать многоуровневую вложенность с помощью объединения макросов.
Давайте разберемся, как работают макросы Aura-Tab и Aura-Tab Group. Нам необходимо разместить макрос Aura-Tab Group, в котором будут размещены макросы Aura-Tab. Каждый Aura-Tab представляет собой таб для переключения между контентом, который вы разместите в рамку макроса. После сохранения мы получим одноуровневые формы с контентом.
![](https://habrastorage.org/getpro/habr/upload_files/3b6/e41/e48/3b6e41e48817f2eac306518c71d837e6.png)
![](https://habrastorage.org/getpro/habr/upload_files/99a/239/af8/99a239af8277fb7369a8e2ad8976d1c9.png)
Для добавления второго уровня вложенности нам потребуются макросы UI Tab и UI Tabs. Принцип работы макросов такой же, как у Aura.
![](https://habrastorage.org/getpro/habr/upload_files/c38/215/b32/c38215b32d9acd862b39039c193e8cc7.png)
Разместим макрос UI Tabs в рамке макроса Aura-Tab. В рамке UI Tabs разместим нужное количество табов UI Tab. Сохраняем и пользуемся.
![](https://habrastorage.org/getpro/habr/upload_files/3c3/c04/76c/3c3c0476cc2412fbe2ee215c102540cd.png)
С помощью объединения группы макросов нам удалось реализовать двухуровневый список табов. Данный способ отлично подходит для описания сложных объектов.
Динамическое объединение таблиц
В работе с требованиями, аналитики используют различные способы представления информации. Одним из популярных и доступных способов является табличное представление. Понимая данный факт, confluence предоставляет большой набор инструментов для работы с таблицами. В этот раз мы решим проблему динамического объединения таблиц. Наша задача создать таблицу, которая будет объединять несколько таблиц и предоставлять актуальные данные.
Допустим, у нас есть две таблицы, которые заполняются разными людьми из разных источников данных.
![](https://habrastorage.org/getpro/habr/upload_files/fbf/20e/492/fbf20e49254476ccdd7f6ccb1bc48cf8.png)
Для использования таблицы, нам необходимо разместить каждую таблицу в рамке макроса «Выборка таблицы». В настройках макроса нужно задать уникальное имя выборки.
![](https://habrastorage.org/getpro/habr/upload_files/030/8ce/06e/0308ce06e94f1c9d5c1ea05525fafb6d.png)
Далее создаем страницу и добавляем макрос объединения таблиц Table Transformer.
![](https://habrastorage.org/getpro/habr/upload_files/d36/b5f/864/d36b5f864139a29843f449db97b914d3.png)
Выбираем один из трех способов объединения, в нашем случае будет Lookup tables. Нажимаем кнопку вставить.
![](https://habrastorage.org/getpro/habr/upload_files/d71/7ba/584/d717ba5849649f1371bcd42fcf5f9be7.png)
В рамку макроса размещаем два макроса «Вставка выборки из таблицы». В настройках выборки ссылаемся на уникальное имя, которые мы указывали в макросе «Выборка из таблицы».
![](https://habrastorage.org/getpro/habr/upload_files/f8a/937/c70/f8a937c706d0ed75cb610a39aff52d3f.png)
![В рамку макроса размещаем два макроса «Вставка выборки из таблицы». В настройках выборки, ссылаемся на уникальное имя которые мы указывали в макросе «Выборка из таблицы». В рамку макроса размещаем два макроса «Вставка выборки из таблицы». В настройках выборки, ссылаемся на уникальное имя которые мы указывали в макросе «Выборка из таблицы».](https://habrastorage.org/getpro/habr/upload_files/729/acc/cee/729acccee7ecc229811f9fb00326a80a.png)
Возвращаемся в настройки макроса Table Transformer. И видим, что макрос самостоятельно определил ключ объединения таблиц (Паспорт).
![](https://habrastorage.org/getpro/habr/upload_files/a82/55a/6d1/a8255a6d1cb853a091b7596d24b9a6c4.png)
Результат после сохранения страницы:
![](https://habrastorage.org/getpro/habr/upload_files/3c5/fcb/67e/3c5fcb67ef07e326070c7c28f11293cb.png)
Таким образом, при изменении данных в исходных таблицах, данные в объединенной таблице будут обновляться. Для объединенной таблицы доступны стандартные функции фильтрации. В зависимости от потребностей, доступно кастомное объединение. Например, можно прописать SELECT * FROM T1 OUTER JOIN T2 ON T1.'Паспорт' = T2.'Паспорт' и получить такой же результат. T1 и T2 это соответственно первая и вторая таблица в рамке макроса. Отличная фича для экономии времени при работе с таблицами, главное не показывать свои «кастомные селекты» разработчикам sql.
Заключение
В данной статье описана лишь часть «необычных» объединений макросов. Не стоит забывать о гибкости и возможностях confluence. Попробуйте создать что-то новое в своей песочнице. Надеюсь данная статья поможет в написании реальных требований.