diff --git a/src/css/structurizr-diagram.css b/src/css/structurizr-diagram.css index f20cbe6..d777647 100644 --- a/src/css/structurizr-diagram.css +++ b/src/css/structurizr-diagram.css @@ -5,6 +5,21 @@ border-style: none; } +details.thumbnailGroup > summary:first-of-type { + display: list-item; + counter-increment: list-item 0; + list-style: inside disclosure-closed; +} +details.thumbnailGroup[open] > summary:first-of-type { + list-style-type: disclosure-open; +} + +details.thumbnailGroup summary { + display: block; + unicode-bidi: isolate; + text-transform: capitalize; +} + .diagramThumbnail { cursor: pointer; margin: 0 0 40px 0; diff --git a/src/jsp/diagrams.jsp b/src/jsp/diagrams.jsp index 383df45..f6c055e 100644 --- a/src/jsp/diagrams.jsp +++ b/src/jsp/diagrams.jsp @@ -588,33 +588,63 @@ function initThumbnails() { var html = ''; var index = 1; - views.forEach(function(view) { - viewKeys.push(view.key); - var id = 'diagram' + index; - var title = structurizr.util.escapeHtml(structurizr.ui.getTitleForView(view)); - html += '
'; + // determine view group based on view property viewGroup if present + const viewGroups = views.reduce((acc, view) => { + const viewGroup = (view.properties?.viewGroup ?? 'default').toLowerCase(); + if (!acc[viewGroup]) { + acc[viewGroup] = []; + } + acc[viewGroup].push(view); + return acc; + }, { default: []}); + + function _renderViews(views) { + views.forEach(function(view) { + viewKeys.push(view.key); + var id = 'diagram' + index; + var title = structurizr.util.escapeHtml(structurizr.ui.getTitleForView(view)); + + html += '
'; + + if (view.type === structurizr.constants.IMAGE_VIEW_TYPE) { + html += '
'; + } else { + + + html += ' '; + + + html += '
'; +
+
+ } - if (view.type === structurizr.constants.IMAGE_VIEW_TYPE) { - html += '
'; - } else { - - - html += ' '; - - - html += '
'; -
-
- } + html += '
'; + html += title; + html += '
#' + structurizr.util.escapeHtml(view.key) + ''; + html += '
'; - html += '
'; - html += title; - html += '
#' + structurizr.util.escapeHtml(view.key) + ''; - html += '
'; + index++; + }); + } - index++; - }); + // if only a single viewGroup is present, render the views directly + // this happends if no view has the custom property viewGroup set + if (Object.keys(viewGroups).length === 1) { + _renderViews(views); + } else { + Object.entries(viewGroups).forEach(([keyGroup, _views]) => { + html += '
'; + html += '' + keyGroup + ''; + html += '
'; + + _renderViews(_views); + + html += '
'; + html += '
'; + }) + } $('#diagramNavigation').append(html);