Skip to content

Commit

Permalink
Merge pull request #333 from qtzar/DynamicDiagrams
Browse files Browse the repository at this point in the history
Added support for Dynamic Diagrams
  • Loading branch information
jp7677 authored Oct 22, 2023
2 parents 8169d2c + 41aaca2 commit e9e3ac7
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,8 @@ fun ViewSet.hasContainerViews(softwareSystem: SoftwareSystem) =
fun ViewSet.hasComponentViews(softwareSystem: SoftwareSystem) =
componentViews.any { it.softwareSystem == softwareSystem }

fun ViewSet.hasDynamicViews(softwareSystem: SoftwareSystem) =
dynamicViews.any { it.softwareSystem == softwareSystem }

fun ViewSet.hasDeploymentViews(softwareSystem: SoftwareSystem) =
deploymentViews.any { it.softwareSystem == softwareSystem }
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ private fun generateHtmlFiles(context: GeneratorContext, branchDir: File) {
add { writeHtmlFile(branchDir, SoftwareSystemContextPageViewModel(context, it)) }
add { writeHtmlFile(branchDir, SoftwareSystemContainerPageViewModel(context, it)) }
add { writeHtmlFile(branchDir, SoftwareSystemComponentPageViewModel(context, it)) }
add { writeHtmlFile(branchDir, SoftwareSystemDynamicPageViewModel(context, it)) }
add { writeHtmlFile(branchDir, SoftwareSystemDeploymentPageViewModel(context, it)) }
add { writeHtmlFile(branchDir, SoftwareSystemDependenciesPageViewModel(context, it)) }
add { writeHtmlFile(branchDir, SoftwareSystemDecisionsPageViewModel(context, it)) }
Expand Down Expand Up @@ -186,6 +187,7 @@ private fun writeHtmlFile(exportDir: File, viewModel: PageViewModel) {
is SoftwareSystemContainerSectionPageViewModel -> softwareSystemContainerSectionPage(viewModel)
is SoftwareSystemContainerSectionsPageViewModel -> softwareSystemContainerSectionsPage(viewModel)
is SoftwareSystemComponentPageViewModel -> softwareSystemComponentPage(viewModel)
is SoftwareSystemDynamicPageViewModel -> softwareSystemDynamicPage(viewModel)
is SoftwareSystemDeploymentPageViewModel -> softwareSystemDeploymentPage(viewModel)
is SoftwareSystemDependenciesPageViewModel -> softwareSystemDependenciesPage(viewModel)
is SoftwareSystemDecisionPageViewModel -> softwareSystemDecisionPage(viewModel)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package nl.avisi.structurizr.site.generatr.site.model

import com.structurizr.model.SoftwareSystem
import nl.avisi.structurizr.site.generatr.hasDynamicViews
import nl.avisi.structurizr.site.generatr.site.GeneratorContext

class SoftwareSystemDynamicPageViewModel(generatorContext: GeneratorContext, softwareSystem: SoftwareSystem) :
SoftwareSystemPageViewModel(generatorContext, softwareSystem, Tab.DYNAMIC) {
val diagrams = generatorContext.workspace.views.dynamicViews
.filter { it.softwareSystem == softwareSystem }
.sortedBy { it.key }
.map { DiagramViewModel.forView(this, it, generatorContext.svgFactory) }
val visible = generatorContext.workspace.views.hasDynamicViews(softwareSystem)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ open class SoftwareSystemPageViewModel(
private val softwareSystem: SoftwareSystem,
tab: Tab
) : PageViewModel(generatorContext) {
enum class Tab { HOME, SYSTEM_CONTEXT, CONTAINER, COMPONENT, DEPLOYMENT, DEPENDENCIES, DECISIONS, SECTIONS }
enum class Tab { HOME, SYSTEM_CONTEXT, CONTAINER, COMPONENT, DYNAMIC, DEPLOYMENT, DEPENDENCIES, DECISIONS, SECTIONS }

inner class TabViewModel(val tab: Tab, exactLink: Boolean = true) {
val link = LinkViewModel(this@SoftwareSystemPageViewModel, title, url(softwareSystem, tab), exactLink)
Expand All @@ -20,6 +20,7 @@ open class SoftwareSystemPageViewModel(
Tab.SYSTEM_CONTEXT -> "Context views"
Tab.CONTAINER -> "Container views"
Tab.COMPONENT -> "Component views"
Tab.DYNAMIC -> "Dynamic views"
Tab.DEPLOYMENT -> "Deployment views"
Tab.DEPENDENCIES -> "Dependencies"
Tab.DECISIONS -> "Decisions"
Expand All @@ -33,6 +34,7 @@ open class SoftwareSystemPageViewModel(
Tab.SYSTEM_CONTEXT -> generatorContext.workspace.views.hasSystemContextViews(softwareSystem)
Tab.CONTAINER -> generatorContext.workspace.views.hasContainerViews(softwareSystem)
Tab.COMPONENT -> generatorContext.workspace.views.hasComponentViews(softwareSystem)
Tab.DYNAMIC -> generatorContext.workspace.views.hasDynamicViews(softwareSystem)
Tab.DEPLOYMENT -> generatorContext.workspace.views.hasDeploymentViews(softwareSystem)
Tab.DECISIONS -> softwareSystem.hasDecisions() or softwareSystem.hasContainerDecisions()
Tab.SECTIONS -> softwareSystem.hasDocumentationSections() or softwareSystem.hasContainerDocumentationSections()
Expand All @@ -47,6 +49,7 @@ open class SoftwareSystemPageViewModel(
TabViewModel(Tab.SYSTEM_CONTEXT),
TabViewModel(Tab.CONTAINER),
TabViewModel(Tab.COMPONENT),
TabViewModel(Tab.DYNAMIC),
TabViewModel(Tab.DEPLOYMENT),
TabViewModel(Tab.DEPENDENCIES),
TabViewModel(Tab.DECISIONS, exactLink = false),
Expand All @@ -63,6 +66,7 @@ open class SoftwareSystemPageViewModel(
Tab.SYSTEM_CONTEXT -> "$home/context"
Tab.CONTAINER -> "$home/container"
Tab.COMPONENT -> "$home/component"
Tab.DYNAMIC -> "$home/dynamic"
Tab.DEPLOYMENT -> "$home/deployment"
Tab.DEPENDENCIES -> "$home/dependencies"
Tab.DECISIONS -> "$home/decisions"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package nl.avisi.structurizr.site.generatr.site.views

import kotlinx.html.HTML
import nl.avisi.structurizr.site.generatr.site.model.SoftwareSystemDynamicPageViewModel

fun HTML.softwareSystemDynamicPage(viewModel: SoftwareSystemDynamicPageViewModel) {
if (viewModel.visible)
softwareSystemPage(viewModel) {
viewModel.diagrams.forEach {
diagram(it)
}
}
else
redirectUpPage()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package nl.avisi.structurizr.site.generatr.site.model

import assertk.assertThat
import assertk.assertions.containsExactly
import assertk.assertions.isEqualTo
import assertk.assertions.isFalse
import com.structurizr.model.SoftwareSystem
import kotlin.test.Test

class SoftwareSystemDynamicPageViewModelTest : ViewModelTest() {
private val generatorContext = generatorContext()
private val softwareSystem: SoftwareSystem = generatorContext.workspace.model
.addSoftwareSystem("Software system").also {
val backend = it.addContainer("Backend")
val frontend = it.addContainer("Frontend")
generatorContext.workspace.views.createDynamicView(backend, "backend-dynamic", "Dynamic view 1")
generatorContext.workspace.views.createDynamicView(frontend, "frontend-dynamic", "Dynamic view 2")
}

@Test
fun `active tab`() {
val viewModel = SoftwareSystemDynamicPageViewModel(generatorContext, softwareSystem)

assertThat(viewModel.tabs.single { it.link.active }.tab)
.isEqualTo(SoftwareSystemPageViewModel.Tab.DYNAMIC)
}

@Test
fun `diagrams sorted by key`() {
val viewModel = SoftwareSystemDynamicPageViewModel(generatorContext, softwareSystem)

assertThat(viewModel.diagrams).containsExactly(
DiagramViewModel(
"backend-dynamic",
"Backend - Dynamic",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
ImageViewModel(viewModel, "/svg/backend-dynamic.svg"),
ImageViewModel(viewModel, "/png/backend-dynamic.png"),
ImageViewModel(viewModel, "/puml/backend-dynamic.puml")
),
DiagramViewModel(
"frontend-dynamic",
"Frontend - Dynamic",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
ImageViewModel(viewModel, "/svg/frontend-dynamic.svg"),
ImageViewModel(viewModel, "/png/frontend-dynamic.png"),
ImageViewModel(viewModel, "/puml/frontend-dynamic.puml")
)
)
}

@Test
fun `hidden view`() {
val viewModel = SoftwareSystemDynamicPageViewModel(
generatorContext,
generatorContext.workspace.model.addSoftwareSystem("Software system 2")
)

assertThat(viewModel.visible).isFalse()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class SoftwareSystemPageViewModelTest : ViewModelTest() {
Tab.SYSTEM_CONTEXT,
Tab.CONTAINER,
Tab.COMPONENT,
Tab.DYNAMIC,
Tab.DEPLOYMENT,
Tab.DEPENDENCIES,
Tab.DECISIONS,
Expand All @@ -72,6 +73,7 @@ class SoftwareSystemPageViewModelTest : ViewModelTest() {
"Context views",
"Container views",
"Component views",
"Dynamic views",
"Deployment views",
"Dependencies",
"Decisions",
Expand Down Expand Up @@ -146,6 +148,18 @@ class SoftwareSystemPageViewModelTest : ViewModelTest() {
assertThat(getTab(viewModel, Tab.COMPONENT).visible).isTrue()
}

@Test
fun `dynamic views tab only visible when dynamic diagrams available`() {
val generatorContext = generatorContext()
val softwareSystem = generatorContext.workspace.model.addSoftwareSystem("Some software system")
val container = softwareSystem.addContainer("Backend")
val viewModel = SoftwareSystemPageViewModel(generatorContext, softwareSystem, Tab.HOME)

assertThat(getTab(viewModel, Tab.DYNAMIC).visible).isFalse()
generatorContext.workspace.views.createDynamicView(container, "component", "description")
assertThat(getTab(viewModel, Tab.DYNAMIC).visible).isTrue()
}

@Test
fun `deployment views tab only visible when deployment diagrams available`() {
val generatorContext = generatorContext()
Expand Down

0 comments on commit e9e3ac7

Please sign in to comment.