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

Always use diagram and image titles and keep natural sorting #642

Merged
merged 3 commits into from
Dec 12, 2024
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
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
package nl.avisi.structurizr.site.generatr.site.model

data class IndexEntry(val key: String, val title: String)

data class DiagramIndexViewModel(
val diagrams: List<DiagramViewModel> = emptyList(),
val images: List<ImageViewViewModel> = emptyList()) {
private val diagrams: List<DiagramViewModel> = emptyList(),
private val images: List<ImageViewViewModel> = emptyList()) {

val entries = diagrams.map { IndexEntry(it.key, it.indexTitle()) } +
images.map { IndexEntry(it.key, it.indexTitle()) }

val visible: Boolean = (diagrams.count() + images.count()) > 1

private fun DiagramViewModel.indexTitle() = if (description.isNullOrBlank()) title else "$title ($description)"
private fun ImageViewViewModel.indexTitle() = if (description.isNullOrBlank()) title else "$title ($description)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import com.structurizr.view.View

data class DiagramViewModel(
val key: String,
val name: String,
val title: String?,
val title: String,
val description: String?,
val svg: String?,
val diagramWidthInPixels: Int?,
Expand All @@ -28,8 +27,7 @@ data class DiagramViewModel(
val svg = svgFactory(key, pageViewModel.url)
return DiagramViewModel(
key,
name,
title,
title ?: name,
description,
svg,
extractDiagramWidthInPixels(svg),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import com.structurizr.view.ImageView

data class ImageViewViewModel(val imageView: ImageView) {
val key: String = imageView.key
val name: String = generateName()
val title: String = imageView.title
val title: String = imageView.title ?: generateName()
val description: String? = imageView.description
val content: String = imageView.content

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ class SoftwareSystemContainerComponentCodePageViewModel(generatorContext: Genera
override val url = url(container, component)
val images = generatorContext.workspace.views.imageViews
.filter { it.element == component }
.sortedBy { it.key }
.map { ImageViewViewModel(it) }

val visible = images.isNotEmpty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ class SoftwareSystemContainerComponentsPageViewModel(generatorContext: Generator
override val url = url(container)
val diagrams = generatorContext.workspace.views.componentViews
.filter { it.container == container }
.sortedBy { it.key }
.map { DiagramViewModel.forView(this, it, generatorContext.svgFactory) }
val images = generatorContext.workspace.views.imageViews
.filter { it.element == container }
.sortedBy { it.key }
.map { ImageViewViewModel(it) }

val hasProperties = container.includedProperties.isNotEmpty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ class SoftwareSystemContainerPageViewModel(generatorContext: GeneratorContext, s
SoftwareSystemPageViewModel(generatorContext, softwareSystem, Tab.CONTAINER) {
val diagrams = generatorContext.workspace.views.containerViews
.filter { it.softwareSystem == softwareSystem }
.sortedBy { it.key }
.map { DiagramViewModel.forView(this, it, generatorContext.svgFactory) }
val images = generatorContext.workspace.views.imageViews
.filter { it.element == softwareSystem }
.sortedBy { it.key }
.map { ImageViewViewModel(it) }
val visible = generatorContext.workspace.views.hasContainerViews(generatorContext.workspace, softwareSystem) || images.isNotEmpty()
val diagramIndex = DiagramIndexViewModel(diagrams, images)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ class SoftwareSystemContextPageViewModel(generatorContext: GeneratorContext, sof
SoftwareSystemPageViewModel(generatorContext, softwareSystem, Tab.SYSTEM_CONTEXT) {
val diagrams = generatorContext.workspace.views.systemContextViews
.filter { it.softwareSystem == softwareSystem }
.sortedBy { it.key }
.map { DiagramViewModel.forView(this, it, generatorContext.svgFactory) }
val visible = generatorContext.workspace.views.hasSystemContextViews(softwareSystem)
val diagramIndex = DiagramIndexViewModel(diagrams)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ class SoftwareSystemDeploymentPageViewModel(generatorContext: GeneratorContext,
SoftwareSystemPageViewModel(generatorContext, softwareSystem, Tab.DEPLOYMENT) {
val diagrams = generatorContext.workspace.views.deploymentViews
.filter { it.softwareSystem == softwareSystem }
.sortedBy { it.key }
.map { DiagramViewModel.forView(this, it, generatorContext.svgFactory) }
val visible = generatorContext.workspace.views.hasDeploymentViews(softwareSystem)
val diagramIndex = DiagramIndexViewModel(diagrams)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ class SoftwareSystemDynamicPageViewModel(generatorContext: GeneratorContext, sof
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)
val diagramIndex = DiagramIndexViewModel(diagrams)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fun FlowContent.diagram(viewModel: DiagramViewModel) {
figcaption {
a {
onClick = "openSvgModal('$dialogId', '$svgId')"
+viewModel.name
+viewModel.title
if (!viewModel.description.isNullOrBlank()) {
br
+viewModel.description
Expand All @@ -27,7 +27,7 @@ fun FlowContent.diagram(viewModel: DiagramViewModel) {
// TODO: no links in this SVG
rawHtml(viewModel.svg, svgId, "modal-box-content")
div(classes = "has-text-centered") {
+viewModel.name
+viewModel.title
+" ["
a(href = viewModel.svgLocation.relativeHref, target = "_blank") { +"svg" }
+"|"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,7 @@ fun FlowContent.diagramIndex(viewModel: DiagramIndexViewModel) {
+"Index:"
}
ul {
viewModel.diagrams.forEach {
li {
a(href = "#${it.key}") {
+(it.title ?: it.name)
}
}
}
viewModel.images.forEach {
viewModel.entries.forEach {
li {
a(href = "#${it.key}") {
+it.title
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ fun FlowContent.image(viewModel: ImageViewViewModel) {
figure {
style = "width: fit-content;"
attributes["id"] = viewModel.key

p(classes = "has-text-weight-bold") { +viewModel.title }
img { src = viewModel.content }
figcaption {
a {
onClick = "openModal('$dialogId')"
+viewModel.name
+viewModel.title
if (!viewModel.description.isNullOrBlank()) {
br
+viewModel.description
Expand All @@ -25,6 +25,6 @@ fun FlowContent.image(viewModel: ImageViewViewModel) {
}
modal(dialogId) {
img(classes = "modal-box-content modal-image") { src = viewModel.content }
div(classes = "has-text-centered") { +viewModel.name }
div(classes = "has-text-centered") { +viewModel.title }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package nl.avisi.structurizr.site.generatr.site.model

import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.isFalse
import assertk.assertions.isTrue
import kotlin.test.Test

class DiagramIndexViewModelTest : ViewModelTest() {
private val generatorContext = generatorContext()

@Test
fun `index without diagrams` () {
val viewModel = DiagramIndexViewModel(diagramViewModels())

assertThat(viewModel.entries).isEqualTo(listOf())
}

@Test
fun `index with diagram` () {
val softwareSystem = generatorContext.workspace.model.addSoftwareSystem("Software system")
generatorContext.workspace.views.createSystemContextView(softwareSystem, "system-1", "")
val viewModel = DiagramIndexViewModel(diagramViewModels())

assertThat(viewModel.entries).isEqualTo(listOf(IndexEntry("system-1", "Software system - System Context")))
}

@Test
fun `index with diagram with description` () {
val softwareSystem = generatorContext.workspace.model.addSoftwareSystem("Software system")
generatorContext.workspace.views.createSystemContextView(softwareSystem, "system-1", "Some description")
val viewModel = DiagramIndexViewModel(diagramViewModels())

assertThat(viewModel.entries).isEqualTo(listOf(IndexEntry("system-1", "Software system - System Context (Some description)")))
}

@Test
fun `index with exactly one diagram` () {
val softwareSystem = generatorContext.workspace.model.addSoftwareSystem("Software system")
generatorContext.workspace.views.createSystemContextView(softwareSystem, "system-1", "")
val viewModel = DiagramIndexViewModel(diagramViewModels())

assertThat(viewModel.visible).isFalse()
}

@Test
fun `index with diagram and image with description` () {
val softwareSystem = generatorContext.workspace.model.addSoftwareSystem("Software system")
generatorContext.workspace.views.createSystemContextView(softwareSystem, "system-1", "Some description")
generatorContext.workspace.views.createImageView(softwareSystem, "image-1")
val viewModel = DiagramIndexViewModel(diagramViewModels(), imageViewViewModels())

assertThat(viewModel.visible).isTrue()
assertThat(viewModel.entries).isEqualTo(listOf(
IndexEntry("system-1", "Software system - System Context (Some description)"),
IndexEntry("imageview-2", "Image View Title (Image View Description)")
))
}

private fun diagramViewModels() = generatorContext.workspace.views.systemContextViews
.map { DiagramViewModel.forView(this.pageViewModel(), it, generatorContext.svgFactory) }

private fun imageViewViewModels() = listOf(
ImageViewViewModel(createImageView(generatorContext.workspace, generatorContext.workspace.model.addSoftwareSystem("Software system2")))
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ class ImageViewViewModelTest : ViewModelTest() {

@Test
fun `image name for software system`() {
val imageView = ImageViewViewModel(createImageView(generatorContext.workspace, softwareSystem))
assertThat(imageView.name).isEqualTo("Software system 1 - Containers")
val imageView = ImageViewViewModel(createImageView(generatorContext.workspace, softwareSystem, title = null))
assertThat(imageView.title).isEqualTo("Software system 1 - Containers")
}

@Test
fun `image name for container`() {
val imageView = ImageViewViewModel(createImageView(generatorContext.workspace, container))
assertThat(imageView.name).isEqualTo("Software system 1 - Container 1 - Components")
val imageView = ImageViewViewModel(createImageView(generatorContext.workspace, container, title = null))
assertThat(imageView.title).isEqualTo("Software system 1 - Container 1 - Components")
}

@Test
fun `image name for component`() {
val imageView = ImageViewViewModel(createImageView(generatorContext.workspace, component))
assertThat(imageView.name).isEqualTo("Software system 1 - Container 1 - Component 1 - Code")
val imageView = ImageViewViewModel(createImageView(generatorContext.workspace, component, title = null))
assertThat(imageView.title).isEqualTo("Software system 1 - Container 1 - Component 1 - Code")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ class SoftwareSystemContainerComponentsPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"component-1-backend",
"Software system - Backend - Components",
null,
"Component view 1 - Backend",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand All @@ -83,7 +82,6 @@ class SoftwareSystemContainerComponentsPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"component-2-backend",
"Software system - Backend - Components",
null,
"Component view 2 - Backend",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand All @@ -99,7 +97,6 @@ class SoftwareSystemContainerComponentsPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"component-1-frontend",
"Software system - Frontend - Components",
null,
"Component view 1 - Frontend",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand All @@ -110,7 +107,6 @@ class SoftwareSystemContainerComponentsPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"component-2-frontend",
"Software system - Frontend - Components",
null,
"Component view 2 - Frontend",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class SoftwareSystemContainerPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"container-1",
"Software system - Containers",
null,
"Container view 1",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand All @@ -46,7 +45,6 @@ class SoftwareSystemContainerPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"container-2",
"Software system - Containers",
null,
"Container view 2",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class SoftwareSystemContextPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"context-1",
"Software system - System Context",
null,
"System context view 1",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand All @@ -34,7 +33,6 @@ class SoftwareSystemContextPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"context-2",
"Software system - System Context",
null,
"System context view 2",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ class SoftwareSystemDeploymentPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"deployment-1",
"Software system - Deployment - Default",
null,
"Deployment view 1",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand All @@ -43,7 +42,6 @@ class SoftwareSystemDeploymentPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"deployment-2",
"Software system - Deployment - Default",
null,
"Deployment view 2",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ class SoftwareSystemDynamicPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"backend-dynamic",
"Backend - Dynamic",
null,
"Dynamic view 1",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand All @@ -45,7 +44,6 @@ class SoftwareSystemDynamicPageViewModelTest : ViewModelTest() {
DiagramViewModel(
"frontend-dynamic",
"Frontend - Dynamic",
null,
"Dynamic view 2",
"""<svg viewBox="0 0 800 900"></svg>""",
800,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.prop
import com.structurizr.documentation.Format
import com.structurizr.documentation.Section
import com.structurizr.model.SoftwareSystem
import kotlin.test.Test

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ abstract class ViewModelTest {

protected fun createSection(content: String = "# Content") = Section(Format.Markdown, content)

protected fun createImageView(workspace: Workspace, element: Element, key:String = "imageview-${element.id}"): ImageView = workspace.views.createImageView(element, key).also {
protected fun createImageView(workspace: Workspace, element: Element, key: String = "imageview-${element.id}", title: String? = "Image View Title"): ImageView = workspace.views.createImageView(element, key).also {
it.description = "Image View Description"
it.title = "Image View Title"
it.title = title
it.contentType = "image/png"
it.content = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="
}
Expand Down
Loading