diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/DecisionsTableViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/DecisionsTableViewModel.kt index 0193193a..c9ce8cdf 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/DecisionsTableViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/DecisionsTableViewModel.kt @@ -7,7 +7,7 @@ import nl.avisi.structurizr.site.generatr.site.formatDate fun PageViewModel.createDecisionsTableViewModel(decisions: Collection, hrefFactory: (Decision) -> String) = TableViewModel.create { - headerRow(headerCell("ID"), headerCell("Date"), headerCell("Status"), headerCell("Title")) + headerRow(headerCellWithIndex("ID"), headerCell("Date"), headerCell("Status"), headerCell("Title")) decisions .sortedBy { it.id.toInt() } .forEach { diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PropertiesTableViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PropertiesTableViewModel.kt index 97c5f21a..d3673bff 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PropertiesTableViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/PropertiesTableViewModel.kt @@ -4,7 +4,7 @@ import com.structurizr.util.Url fun createPropertiesTableViewModel(properties: Map) = TableViewModel.create { - headerRow(headerCell("Name"), headerCell("Value")) + headerRow(headerCellWithName("Name"), headerCell("Value")) properties .toSortedMap() .forEach { (name, value) -> diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SectionsTableViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SectionsTableViewModel.kt index 8c473859..a5997735 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SectionsTableViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SectionsTableViewModel.kt @@ -7,7 +7,7 @@ import nl.avisi.structurizr.site.generatr.hasSections fun PageViewModel.createSectionsTableViewModel(sections: Collection
, dropFirst: Boolean = true, hrefFactory: (Section) -> String) = TableViewModel.create { - headerRow(headerCell("#"), headerCell("Title")) + headerRow(headerCellWithIndex("#"), headerCell("Title")) sections .sortedBy { it.order } .drop(if (dropFirst) 1 else 0) diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemDependenciesPageViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemDependenciesPageViewModel.kt index 8da8c365..2e836eef 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemDependenciesPageViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemDependenciesPageViewModel.kt @@ -37,8 +37,8 @@ class SoftwareSystemDependenciesPageViewModel( private fun TableViewModel.TableViewInitializerContext.header() { headerRow( - headerCell("System"), - headerCell("Description"), + headerCellWithName("System"), + headerCellWithDescription("Description"), headerCell("Technology") ) } diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemsPageViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemsPageViewModel.kt index 93dec43f..320af039 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemsPageViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemsPageViewModel.kt @@ -7,7 +7,7 @@ class SoftwareSystemsPageViewModel(generatorContext: GeneratorContext) : PageVie override val pageSubTitle = "Software Systems" val softwareSystemsTable: TableViewModel = TableViewModel.create { - headerRow(headerCell("Name"), headerCell("Description")) + headerRow(headerCellWithName("Name"), headerCell("Description")) generatorContext.workspace.model.softwareSystems .sortedBy { it.name.lowercase() } diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/TableViewModel.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/TableViewModel.kt index efbfac15..4ef1341a 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/TableViewModel.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/model/TableViewModel.kt @@ -1,5 +1,12 @@ package nl.avisi.structurizr.site.generatr.site.model +enum class CellWidth { + UNSPECIFIED, + ONE_TENTH, + ONE_FOURTH, + TWO_FOURTH, +} + data class TableViewModel(val headerRows: List, val bodyRows: List) { sealed interface CellViewModel { val isHeader: Boolean @@ -10,12 +17,12 @@ data class TableViewModel(val headerRows: List, val bodyRows: List override val isHeader: Boolean, val greyText: Boolean = false, val boldText: Boolean = false, - val oneTenthWidth: Boolean = false + val width: CellWidth = CellWidth.UNSPECIFIED ) : CellViewModel { override fun toString() = if (isHeader) "headerCell($title, greyText=$greyText)" else - "cell($title, greyText=$greyText, boldText=$boldText, oneTenthWidth=$oneTenthWidth)" + "cell($title, greyText=$greyText, boldText=$boldText, width=${width.name})" } data class LinkCellViewModel(val link: LinkViewModel, override val isHeader: Boolean) : CellViewModel { @@ -47,16 +54,21 @@ data class TableViewModel(val headerRows: List, val bodyRows: List } fun headerCell(title: String, greyText: Boolean = false) = TextCellViewModel(title, true, greyText) + fun headerCellWithIndex(title: String): TextCellViewModel = + TextCellViewModel(title, isHeader = true, width = CellWidth.ONE_TENTH) + fun headerCellWithName(title: String): TextCellViewModel = + TextCellViewModel(title, isHeader = true, width = CellWidth.ONE_FOURTH) + fun headerCellWithDescription(title: String): TextCellViewModel = + TextCellViewModel(title, isHeader = true, width = CellWidth.TWO_FOURTH) + fun headerCellWithLink(pageViewModel: PageViewModel, title: String, href: String) = LinkCellViewModel(LinkViewModel(pageViewModel, title, href), true) fun cell(title: String): TextCellViewModel = TextCellViewModel(title, false) fun cellWithIndex(title: String): TextCellViewModel = - TextCellViewModel(title, false, greyText = false, boldText = true, oneTenthWidth = true) - + TextCellViewModel(title, false, greyText = false, boldText = true) fun cellWithLink(pageViewModel: PageViewModel, title: String, href: String) = LinkCellViewModel(LinkViewModel(pageViewModel, title, href), false) - fun cellWithExternalLink(title: String, href: String) = ExternalLinkCellViewModel(ExternalLinkViewModel(title, href), false) } diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Table.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Table.kt index 21e24a1e..192bd34a 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Table.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/views/Table.kt @@ -2,6 +2,7 @@ package nl.avisi.structurizr.site.generatr.site.views import kotlinx.html.* import nl.avisi.structurizr.site.generatr.site.model.TableViewModel +import nl.avisi.structurizr.site.generatr.site.model.CellWidth fun FlowContent.table(viewModel: TableViewModel) { table (classes = "table is-fullwidth") { @@ -36,19 +37,23 @@ private fun TBODY.row(viewModel: TableViewModel.RowViewModel) { private fun TR.cell(viewModel: TableViewModel.CellViewModel) { when (viewModel) { - is TableViewModel.TextCellViewModel -> + is TableViewModel.TextCellViewModel -> { + val classes = when (viewModel.width) { + CellWidth.UNSPECIFIED -> null + CellWidth.ONE_TENTH -> "is-one-tenth" + CellWidth.ONE_FOURTH -> "is-one-fourth" + CellWidth.TWO_FOURTH -> "is-two-fourth" + } + if (viewModel.isHeader && viewModel.greyText) - th { span(classes = "has-text-grey") { +viewModel.title } } + th(classes = classes) { span(classes = "has-text-grey") { +viewModel.title } } else if (viewModel.isHeader) - th { +viewModel.title } - else if (viewModel.boldText && viewModel.oneTenthWidth) - td(classes = "is-one-tenth") { span(classes = "has-text-weight-bold") { +viewModel.title } } + th(classes = classes) { +viewModel.title } else if (viewModel.boldText) - td { span(classes = "has-text-weight-bold") { +viewModel.title } } - else if (viewModel.oneTenthWidth) - td(classes = "is-one-tenth") { +viewModel.title } + td(classes = classes) { span(classes = "has-text-weight-bold") { +viewModel.title } } else - td { +viewModel.title } + td(classes = classes) { +viewModel.title } + } is TableViewModel.LinkCellViewModel -> if (viewModel.isHeader) th { link(viewModel.link) } diff --git a/src/main/resources/assets/css/style.css b/src/main/resources/assets/css/style.css index e50d09d7..b6e6a5fe 100644 --- a/src/main/resources/assets/css/style.css +++ b/src/main/resources/assets/css/style.css @@ -22,6 +22,14 @@ width: 10%; } +.is-one-fourth { + width: 25%; +} + +.is-two-fourth { + width: 50%; +} + svg a:hover { opacity: 90%; } diff --git a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/DecisionsTableViewModelTest.kt b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/DecisionsTableViewModelTest.kt index 337193fa..9fd373ff 100644 --- a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/DecisionsTableViewModelTest.kt +++ b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/DecisionsTableViewModelTest.kt @@ -44,6 +44,6 @@ class DecisionsTableViewModelTest : ViewModelTest() { } private fun TableViewModel.TableViewInitializerContext.decisionsTableHeaderRow() { - headerRow(headerCell("ID"), headerCell("Date"), headerCell("Status"), headerCell("Title")) + headerRow(headerCellWithIndex("ID"), headerCell("Date"), headerCell("Status"), headerCell("Title")) } } diff --git a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/PropertiesTableViewModelTest.kt b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/PropertiesTableViewModelTest.kt index 9133a25e..7ba345d3 100644 --- a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/PropertiesTableViewModelTest.kt +++ b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/PropertiesTableViewModelTest.kt @@ -56,6 +56,6 @@ class PropertiesTableViewModelTest : ViewModelTest() { } private fun TableViewModel.TableViewInitializerContext.propertiesTableHeaderRow() { - headerRow(headerCell("Name"), headerCell("Value")) + headerRow(headerCellWithName("Name"), headerCell("Value")) } } diff --git a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemDependenciesPageViewModelTest.kt b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemDependenciesPageViewModelTest.kt index cb70cfc2..0b84865e 100644 --- a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemDependenciesPageViewModelTest.kt +++ b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemDependenciesPageViewModelTest.kt @@ -122,8 +122,8 @@ class SoftwareSystemDependenciesPageViewModelTest : ViewModelTest() { private fun TableViewModel.TableViewInitializerContext.dependenciesTableHeader() { headerRow( - headerCell("System"), - headerCell("Description"), + headerCellWithName("System"), + headerCellWithDescription("Description"), headerCell("Technology"), ) } diff --git a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemsPageViewModelTest.kt b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemsPageViewModelTest.kt index be0c730c..7deb57d7 100644 --- a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemsPageViewModelTest.kt +++ b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/SoftwareSystemsPageViewModelTest.kt @@ -29,7 +29,7 @@ class SoftwareSystemsPageViewModelTest : ViewModelTest() { assertThat(viewModel.softwareSystemsTable).isEqualTo( TableViewModel.create { - headerRow(headerCell("Name"), headerCell("Description")) + headerRow(headerCellWithName("Name"), headerCell("Description")) bodyRow( headerCellWithLink( viewModel, system1.name, SoftwareSystemPageViewModel.url( diff --git a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/TableViewModelTest.kt b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/TableViewModelTest.kt index f60caa07..3eb8b04d 100644 --- a/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/TableViewModelTest.kt +++ b/src/test/kotlin/nl/avisi/structurizr/site/generatr/site/model/TableViewModelTest.kt @@ -1,7 +1,6 @@ package nl.avisi.structurizr.site.generatr.site.model import assertk.assertThat -import assertk.assertions.containsAll import assertk.assertions.containsAtLeast import kotlin.test.Test @@ -28,6 +27,51 @@ class TableViewModelTest : ViewModelTest() { ) } + @Test + fun `header row with index`() { + val viewModel = TableViewModel.create { + headerRow(headerCellWithIndex("1")) + } + + assertThat(viewModel.headerRows).containsAtLeast( + TableViewModel.RowViewModel( + listOf( + TableViewModel.TextCellViewModel("1", isHeader = true, width = CellWidth.ONE_TENTH) + ) + ) + ) + } + + @Test + fun `header row with name`() { + val viewModel = TableViewModel.create { + headerRow(headerCellWithName("Name")) + } + + assertThat(viewModel.headerRows).containsAtLeast( + TableViewModel.RowViewModel( + listOf( + TableViewModel.TextCellViewModel("Name", isHeader = true, width = CellWidth.ONE_FOURTH) + ) + ) + ) + } + + @Test + fun `header row with description`() { + val viewModel = TableViewModel.create { + headerRow(headerCellWithDescription("Description")) + } + + assertThat(viewModel.headerRows).containsAtLeast( + TableViewModel.RowViewModel( + listOf( + TableViewModel.TextCellViewModel("Description", isHeader = true, width = CellWidth.TWO_FOURTH) + ) + ) + ) + } + @Test fun `header cell with grey text`() { val viewModel = TableViewModel.create { @@ -127,8 +171,7 @@ class TableViewModelTest : ViewModelTest() { "1", isHeader = false, greyText = false, - boldText = true, - oneTenthWidth = true + boldText = true ) ) )