Skip to content

Commit

Permalink
Merge pull request #382 from melexis/description-in-matrix
Browse files Browse the repository at this point in the history
item-matrix: Show item content
  • Loading branch information
Letme authored Jul 31, 2024
2 parents 0b16f07 + bf8a10c commit 3fd420b
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 7 deletions.
5 changes: 5 additions & 0 deletions doc/_static/css/extra.css
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,8 @@
.rst-content ul.bonsai li>ul {
margin-bottom: 0 !important;
}

/* Don't add exclamation point icon in admonition bar of items */
.rst-content div.item p.admonition-title:before {
content: None !important;
}
3 changes: 3 additions & 0 deletions doc/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,9 @@ limitations in doing so:
Normally the *longtable* class is used when the number of rows is greater than 30 which allows long tables to
span multiple pages. By setting *class* to *longtable* manually, you can force the use of this environment.

In HTML, when you right-click a row, the content of all internal items in the row are fetched and displayed.
Successive right-clicks toggle the visibility of the items' content.

Link targets via intermediate items (advanced)
==============================================

Expand Down
30 changes: 28 additions & 2 deletions mlx/traceability/assets/traceability.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ $(document).ready(function () {
'white-space': 'pre' // prevents adding newlines
});
$(this).hover(
function() {
function () {
// entering hover state
caption.show();
var captionRight = caption.offset().left + caption.outerWidth();
Expand All @@ -48,14 +48,40 @@ $(document).ready(function () {
// lines up the caption behind the item ID
caption.css('transform', 'translate(0.3rem, -3px)');
}
}, function() {
}, function () {
// leaving hover state
caption.css('transform', 'none'); // resets the transformations
caption.hide();
}
);
});

$('table > tbody > tr[class^=item-group-]').each(function (i) {
$(this).on("contextmenu",
function (event) {
event.preventDefault()
var groupName = /item-group-\d+/.exec($(this).attr('class'))[0];
$(this).parent().find(`tr.${groupName} > td > p.item-link`).each(function (j) {
const cell = $(this).parent();
const maxWidth = Math.max(cell.width(), ($("div.rst-content").width() / 2));
cell.css("maxWidth", maxWidth);
const content = $(this).children('div.content').first();
if (content.length) {
content.toggle();
} else {
var link = $(this).children('a').first();
var container = $('<div>', { class: 'content' });
var paragraph = $(this)
container.load(link.attr('href').replace('#', ' #content-'), function () {
container.find('*').css("width", "inherit");
paragraph.append(container);
});
}
});
}
);
});

$('p.admonition-title').each(function (i) {
$(this).children('a').first().denyPermalinkStyling($(this));
});
Expand Down
6 changes: 6 additions & 0 deletions mlx/traceability/directives/item_matrix_directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ def _postprocess_tbody(self, tbody):
def _set_rowspan(tbody, indexes):
""" Sets the 'rowspan' attribute of cells that should span multiple rows to avoid duplication
Also groups all rows that belong to a single source item by assigning them to the same CSS class.
Args:
tbody (nodes.tbody): Table body
indexes (iterable): Range object with indexes of columns to take into account
Expand All @@ -241,10 +243,12 @@ def _set_rowspan(tbody, indexes):
prev_row = None
cells_to_remove = {}
original_cells = {idx: None for idx in indexes}
group_class_nr = 0
for row_idx, row in enumerate(tbody):
cells_to_remove[row_idx] = []
if prev_row is None:
prev_row = row
row['classes'].append(f'item-group-{group_class_nr}')
continue

for col_idx, cell in original_cells.items():
Expand All @@ -255,11 +259,13 @@ def _set_rowspan(tbody, indexes):
cells_to_remove[row_idx].append(col_idx)
elif col_idx == 0: # new source so reset and move on to next row
original_cells = {idx: None for idx in indexes}
group_class_nr += 1
break
else:
original_cells[col_idx] = None

prev_row = row
row['classes'].append(f'item-group-{group_class_nr}')
return cells_to_remove

@staticmethod
Expand Down
7 changes: 5 additions & 2 deletions mlx/traceability/traceable_base_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ def __init__(self, name, state=None):
self.lineno = None
self.node = None
self._content = None
self.content_node = nodes.block_quote()
self.content_node = nodes.container()
self.content_node['ids'].append(f'content-{self.identifier}')
self._state = state
if state is not None:
state.document.ids[f'content-{self.identifier}'] = self.content_node

@staticmethod
def to_id(identifier):
Expand Down Expand Up @@ -89,7 +92,7 @@ def content(self, content):
template = ViewList(source=self.docname, parent_offset=self.lineno)
for idx, line in enumerate(content.split('\n')):
template.append(line, self.docname, idx)
self.content_node = nodes.block_quote() # reset
self.content_node.children = [] # reset
nested_parse_with_titles(self._state, template, self.content_node)

def clear_state(self):
Expand Down
1 change: 1 addition & 0 deletions mlx/traceability/traceable_base_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def make_internal_item_ref(self, app, item_id):
link_item = item_info
notification_item = None
p_node = nodes.paragraph()
p_node['classes'].append('item-link')

# Only create link when target item (or notification item) exists, warn otherwise (in html and terminal)
if item_info.is_placeholder:
Expand Down
5 changes: 2 additions & 3 deletions tests/test_traceable_base_class.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from unittest import TestCase

from docutils import nodes

from mlx.traceability import traceable_base_class as dut


Expand All @@ -20,7 +18,8 @@ def test_init(self):
self.assertIsNone(item.node)
self.assertIsNone(item.caption)
self.assertIsNone(item.content)
self.assertEqual(str(nodes.block_quote()), str(item.content_node))
self.assertEqual("<container ids=\"['content-some-random$name\\'with<\"weird@symbols']\"/>",
str(item.content_node))

def test_to_dict(self):
txt = 'some description, with\n newlines and other stuff'
Expand Down

0 comments on commit 3fd420b

Please sign in to comment.