Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hide software system not attached to group in menu #340

Merged
merged 3 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions docs/example/workspace.dsl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ workspace "Big Bank plc" "This is an example workspace to illustrate the key fea
model {
customer = person "Personal Banking Customer" "A customer of the bank, with personal bank accounts." "Customer"

acquirer = softwaresystem "Acquirer" "Facilitates PIN transactions for merchants."
acquirer = softwaresystem "Acquirer" "Facilitates PIN transactions for merchants." "External System"

enterprise "Big Bank plc" {
supportStaff = person "Customer Service Staff" "Customer service staff within the bank." "Bank Staff" {
Expand Down Expand Up @@ -158,15 +158,18 @@ workspace "Big Bank plc" "This is an example workspace to illustrate the key fea
views {
properties {
"c4plantuml.elementProperties" "true"
"c4plantuml.tags" "true"
"generatr.style.colors.primary" "#485fc7"
"generatr.style.colors.secondary" "#ffffff"
"generatr.style.faviconPath" "site/favicon.ico"
"generatr.style.logoPath" "site/logo.png"

// Absolute URL's like "https://example.com/custom.css" are also supported
"generatr.style.customStylesheet" "site/custom.css"
//"generatr.style.customStylesheet" "https://example.com/custom.css"

"generatr.svglink.target" "_self"

// full list of available "generatr.markdown.flexmark.extensions"
// Full list of available "generatr.markdown.flexmark.extensions"
// "Abbreviation,Admonition,AnchorLink,Aside,Attributes,Autolink,Definition,Emoji,EnumeratedReference,Footnotes,GfmIssues,GfmStrikethroughSubscript,GfmTaskList,GfmUsers,GitLab,Ins,Macros,MediaTags,ResizableImage,Superscript,Tables,TableOfContents,SimulatedTableOfContents,Typographic,WikiLinks,XWikiMacro,YAMLFrontMatter,YouTubeLink"
// see https://github.com/vsch/flexmark-java/wiki/Extensions
// ATTENTION:
Expand Down Expand Up @@ -255,15 +258,18 @@ workspace "Big Bank plc" "This is an example workspace to illustrate the key fea
shape Person
}
element "Customer" {
background #08427b
background #686868
}
element "Bank Staff" {
background #999999
background #08427B
}
element "Software System" {
background #1168bd
color #ffffff
}
element "External System" {
background #686868
}
element "Existing System" {
background #999999
color #ffffff
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,28 @@ class MenuViewModel(generatorContext: GeneratorContext, private val pageViewMode
createMenuItem(it.name, SoftwareSystemPageViewModel.url(it, SoftwareSystemPageViewModel.Tab.HOME), false)
}

private val groupSeparator = generatorContext.workspace.model.properties["structurizr.groupSeparator"]

private val softwareSystemPaths = generatorContext.workspace.model.includedSoftwareSystems
.filter { it.group != null }
.map { it.group + groupSeparator + it.name }
.sortedBy { it.lowercase() }

private fun createMenuItem(title: String, href: String, exact: Boolean = true) =
LinkViewModel(pageViewModel, title, href, exact)

fun softwareSystemNodes(): MenuNodeViewModel {
data class MutableMenuNode(val name: String, val children: MutableList<MutableMenuNode>) {
fun toMenuNode(): MenuNodeViewModel = MenuNodeViewModel(name, children.map { it.toMenuNode() })
}
if (groupSeparator == null)
throw IllegalStateException("Property structurizr.groupSeparator not defined for model") // This is also validated earlier by structurizr when parsing the model

val rootNode = MutableMenuNode("", mutableListOf())

softwareSystemPaths.forEach { path ->
var currentNode = rootNode
path.split(delimiter).forEach { part ->
path.split(groupSeparator).forEach { part ->
val existingNode = currentNode.children.find { it.name == part }
currentNode = if (existingNode == null) {
val newNode = MutableMenuNode(part, mutableListOf())
Expand All @@ -51,10 +60,4 @@ class MenuViewModel(generatorContext: GeneratorContext, private val pageViewMode

return rootNode.toMenuNode()
}

private val softwareSystemPaths = generatorContext.workspace.model.includedSoftwareSystems
.map { it.group + "/" + it.name }
.sortedBy { it.lowercase() }

private val delimiter = '/'
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package nl.avisi.structurizr.site.generatr.site.views

import kotlinx.html.*
import nl.avisi.structurizr.site.generatr.site.GeneratorContext
import nl.avisi.structurizr.site.generatr.site.model.LinkViewModel
import nl.avisi.structurizr.site.generatr.site.model.MenuNodeViewModel
import nl.avisi.structurizr.site.generatr.site.model.MenuViewModel

fun DIV.menu(viewModel: MenuViewModel, nestGroups:Boolean) {
fun DIV.menu(viewModel: MenuViewModel, nestGroups: Boolean) {
aside(classes = "menu p-3") {
generalSection(viewModel.generalItems)
softwareSystemsSection(viewModel, nestGroups)
Expand All @@ -18,10 +17,10 @@ private fun ASIDE.generalSection(items: List<LinkViewModel>) {
menuItemLinks(items)
}

private fun ASIDE.softwareSystemsSection(viewModel: MenuViewModel, nestGroups:Boolean) {
private fun ASIDE.softwareSystemsSection(viewModel: MenuViewModel, nestGroups: Boolean) {
p(classes = "menu-label") { +"Software systems" }
if(nestGroups){
ul(classes = "listree menu-list has-site-branding"){
if (nestGroups) {
ul(classes = "listree menu-list has-site-branding") {
buildHtmlTree(viewModel.softwareSystemNodes(), viewModel).invoke(this)
}
} else {
Expand Down Expand Up @@ -49,21 +48,14 @@ private fun buildHtmlTree(node: MenuNodeViewModel, viewModel: MenuViewModel): UL
}
}

if (node.name.isNotEmpty() && node.children.isNotEmpty()) {
if (node.name.isNotEmpty() && node.children.isNotEmpty()) {
li {
if(node.name == "null"){
div(classes = "listree-submenu-heading") {
+"No Group"
}
} else {
div(classes = "listree-submenu-heading") {
+node.name
}
div(classes = "listree-submenu-heading") {
+node.name
}

ul(classes = "listree-submenu-items") {
for (child in node.children) {
buildHtmlTree(child,viewModel).invoke(this)
buildHtmlTree(child, viewModel).invoke(this)
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions src/main/resources/assets/css/treeview.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@ ul.listree {
ul.listree-submenu-items {
list-style: none;
white-space: nowrap;
padding-left: 10px
padding-left: 10px;
}

div.listree-submenu-heading.collapsed:before {
content: "\25B6";
margin-right: 4px
display: inline-block;
min-width: 20px;
}

div.listree-submenu-heading.expanded:before {
content: "\25BC";
margin-right: 4px
display: inline-block;
min-width: 20px;
}

.scrollable-menu {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ class MenuViewModelTest : ViewModelTest() {
@Test
fun `show nested groups in software systems list`() {
val generatorContext = generatorContext(branches = listOf("main", "branch-2"), currentBranch = "main")
generatorContext.workspace.views.configuration.addProperty("generatr.site.nestGroups","true")
generatorContext.workspace.views.configuration.addProperty("generatr.site.nestGroups", "true")
generatorContext.workspace.model.addProperty("structurizr.groupSeparator", "/")
generatorContext.workspace.model.addSoftwareSystem("System 1").group = "Group 1"
generatorContext.workspace.model.addSoftwareSystem("System 2").group = "Group 1"
generatorContext.workspace.model.addSoftwareSystem("System 3").group = "Group 2"
Expand Down
Loading