Skip to content

Commit

Permalink
feat: allow for selecting different model-check baseline bundle in lo…
Browse files Browse the repository at this point in the history
…cal dev mode (#246)

Fixes #244
  • Loading branch information
chrispcampbell authored Sep 27, 2022
1 parent a1988e2 commit 6425eb8
Show file tree
Hide file tree
Showing 28 changed files with 506 additions and 56 deletions.
1 change: 1 addition & 0 deletions examples/hello-world/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
baselines
sde-prep
1 change: 1 addition & 0 deletions examples/hello-world/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"scripts": {
"build": "sde bundle",
"dev": "sde dev",
"save-baseline": "sde-check baseline --save",
"serve": "sirv ./sde-prep/check-report"
},
"dependencies": {
Expand Down
4 changes: 3 additions & 1 deletion examples/sample-check-app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ if (suiteSummaryJson) {
const checkOptions = getConfigOptions(baselineBundle() as Bundle, currentBundle() as Bundle)

// Initialize the root Svelte component
const appShell = initAppShell(checkOptions, suiteSummary)
const appShell = initAppShell(checkOptions, {
suiteSummary
})

export default appShell
1 change: 1 addition & 0 deletions examples/template-default/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
baselines
sde-prep
*.vdf
*.vdfx
Expand Down
2 changes: 1 addition & 1 deletion examples/template-default/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"build": "sde bundle",
"dev": "sde dev",
"start": "sde dev"
"save-baseline": "sde-check baseline --save"
},
"workspaces": [
"packages/core",
Expand Down
1 change: 1 addition & 0 deletions examples/template-minimal/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
baselines
sde-prep
3 changes: 2 additions & 1 deletion examples/template-minimal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"type": "module",
"scripts": {
"build": "sde bundle",
"dev": "sde dev"
"dev": "sde dev",
"save-baseline": "sde-check baseline --save"
},
"dependencies": {
"@sdeverywhere/build": "^0.2.0",
Expand Down
36 changes: 36 additions & 0 deletions packages/check-ui-shell/src/_shared/stores.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2022 Climate Interactive / New Venture Fund

import type { Writable } from 'svelte/store'
import { writable } from 'svelte/store'

/**
* Return a Svelte writable store that is backed by local storage.
*/
export function localStorageWritableBoolean(key: string, defaultValue: boolean): Writable<boolean> {
const initialStringValue = localStorage.getItem(key)
let initialValue: boolean
if (initialStringValue !== undefined) {
initialValue = initialStringValue === '1'
} else {
initialValue = defaultValue
}

let currentValue = initialValue
const { subscribe, set } = writable(initialValue)

const _set = (newValue: boolean) => {
currentValue = newValue
localStorage.setItem(key, newValue ? '1' : '0')
set(newValue)
}

const _update = (updater: (value: boolean) => boolean) => {
_set(updater(currentValue))
}

return {
subscribe,
set: _set,
update: _update
}
}
26 changes: 19 additions & 7 deletions packages/check-ui-shell/src/app-init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import { initAppModel } from './model/app-model'
import { default as AppShell } from './app-shell.svelte'
import { AppViewModel } from './app-vm'

export function initAppShell(
configOptions: ConfigOptions,
suiteSummary?: SuiteSummary,
containerId = 'app-shell-container'
): AppShell {
export interface AppShellOptions {
suiteSummary?: SuiteSummary
containerId?: string
bundleNames?: string[]
}

export function initAppShell(configOptions: ConfigOptions, appShellOptions?: AppShellOptions): AppShell {
// Initialize the root Svelte component
const containerId = appShellOptions?.containerId || 'app-shell-container'
const appShell = new AppShell({
target: document.getElementById(containerId),
props: {
Expand All @@ -23,8 +26,17 @@ export function initAppShell(
// Initialize the app model asynchronously
initAppModel(configOptions)
.then(appModel => {
// Create the app view model and update the AppShell component
const appViewModel = new AppViewModel(appModel, suiteSummary)
// Create the app view model
const appViewModel = new AppViewModel(appModel, appShellOptions?.suiteSummary)

if (appShellOptions?.bundleNames) {
// Set the list of available bundle names
// TODO: Pass these to AppViewModel constructor instead of setting them here
appViewModel.headerViewModel.bundleNamesL.set(appShellOptions.bundleNames)
appViewModel.headerViewModel.bundleNamesR.set(appShellOptions.bundleNames)
}

// Update the AppShell component
appShell.$set({
appViewModel
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export function row(
rowClass: string,
status: CheckStatus,
content: string,
graphBoxViewModel?: CheckSummaryGraphBoxViewModel
graphBoxViewModel?: CheckSummaryGraphBoxViewModel,
graphVisible = false
): CheckSummaryRowViewModel {
const whitespace = '&ensp;'.repeat(2 + indent * 4)
const statusChar = charForStatus(status)
Expand All @@ -42,6 +43,6 @@ export function row(
status,
span,
graphBoxViewModel,
graphVisible: writable(false)
graphVisible: writable(graphVisible)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export function createCheckSummaryTestViewModel(
dataCoordinator: CheckDataCoordinator,
test: CheckTestReport
): CheckSummaryTestViewModel {
let expandedFirstGraph = false

const rows: CheckSummaryRowViewModel[] = []
const testRow = row(0, 'test', test.status, test.name)
for (const scenario of test.scenarios) {
Expand All @@ -32,15 +34,30 @@ export function createCheckSummaryTestViewModel(
rows.push(row(2, 'dataset', dataset.status, datasetMessage(dataset, bold)))
for (const predicate of dataset.predicates) {
let graphBoxViewModel: CheckSummaryGraphBoxViewModel
let graphVisible = false
if (scenario.checkScenario.scenario && dataset.checkDataset.datasetKey) {
graphBoxViewModel = new CheckSummaryGraphBoxViewModel(
dataCoordinator,
scenario.checkScenario.scenario,
dataset.checkDataset.datasetKey,
predicate
)
if (!expandedFirstGraph && predicate.result.status === 'failed') {
// Expand the graph for the first failing check
expandedFirstGraph = true
graphVisible = true
}
}
rows.push(row(3, 'predicate', predicate.result.status, predicateMessage(predicate, bold), graphBoxViewModel))
rows.push(
row(
3,
'predicate',
predicate.result.status,
predicateMessage(predicate, bold),
graphBoxViewModel,
graphVisible
)
)
}
}
}
Expand Down
14 changes: 13 additions & 1 deletion packages/check-ui-shell/src/components/header/header-vm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
import type { Writable } from 'svelte/store'
import { writable } from 'svelte/store'
import type { CompareConfig } from '@sdeverywhere/check-core'
import { localStorageWritableBoolean } from '../../_shared/stores'

export interface HeaderViewModel {
nameL?: string
nameR?: string
bundleNamesL: Writable<string[]>
bundleNamesR: Writable<string[]>
thresholds?: string[]
simplifyScenarios?: Writable<boolean>
}
Expand All @@ -15,7 +18,12 @@ export function createHeaderViewModel(
compareConfig: CompareConfig | undefined,
includeSimplifyScenarios: boolean
): HeaderViewModel {
const simplifyScenarios: Writable<boolean> = includeSimplifyScenarios ? writable(true) : undefined
let simplifyScenarios: Writable<boolean>
if (includeSimplifyScenarios) {
simplifyScenarios = localStorageWritableBoolean('sde-check-simplify-scenarios', true)
} else {
simplifyScenarios = undefined
}

// Only include the comparison-related header elements if the compare
// config is defined
Expand All @@ -31,11 +39,15 @@ export function createHeaderViewModel(
return {
nameL: compareConfig.bundleL.name,
nameR: compareConfig.bundleR.name,
bundleNamesL: writable([compareConfig.bundleL.name]),
bundleNamesR: writable([compareConfig.bundleR.name]),
thresholds: thresholdStrings,
simplifyScenarios
}
} else {
return {
bundleNamesL: writable([]),
bundleNamesR: writable([]),
simplifyScenarios
}
}
Expand Down
13 changes: 13 additions & 0 deletions packages/check-ui-shell/src/components/header/header.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//- Copyright (c) 2021-2022 Climate Interactive / New Venture Fund
//- Note: These mixins are kept in an external pug file to work around a
//- Svelte issue related to `each` and TypeScript, see:
//- https://github.com/sveltejs/svelte-preprocess/issues/207
mixin optionsL
+each(`$bundleNamesL as name`)
option(selected!='{name === viewModel.nameL}') { name }

mixin optionsR
+each(`$bundleNamesR as name`)
option(selected!='{name === viewModel.nameR}') { name }
54 changes: 51 additions & 3 deletions packages/check-ui-shell/src/components/header/header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,33 @@ import type { HeaderViewModel } from './header-vm'
export let viewModel: HeaderViewModel
const simplifyScenarios = viewModel.simplifyScenarios
const thresholds = viewModel.thresholds
const bundleNamesL = viewModel.bundleNamesL
const bundleNamesR = viewModel.bundleNamesR
const dispatch = createEventDispatcher()
function onHome() {
dispatch('command', { cmd: 'show-summary' })
}
function onSelectBundle(kind: string, name: string): void {
const changeEvent = new CustomEvent('sde-check-bundle', {
detail: {
kind,
name
}
})
document.dispatchEvent(changeEvent)
}
function onSelectBundleL(e: Event) {
onSelectBundle('left', (e.target as HTMLSelectElement).value)
}
function onSelectBundleR(e: Event) {
onSelectBundle('right', (e.target as HTMLSelectElement).value)
}
</script>


Expand All @@ -26,6 +46,8 @@ function onHome() {
<!-- TEMPLATE -->
<template lang='pug'>

include header.pug

.header-container
.header-content
.header-group
Expand All @@ -35,12 +57,20 @@ function onHome() {
.header-group
input.checkbox(type='checkbox' name='simplify-toggle' bind:checked!='{$simplifyScenarios}')
label(for='simplify-toggle') Simplify Scenarios
+if('viewModel.nameL')
+if('viewModel.nameL || $bundleNamesL.length > 1')
.spacer-fixed
.header-group
.label Comparing:
.label.dataset-color-0 {viewModel.nameL}
.label.dataset-color-1 {viewModel.nameR}
+if('$bundleNamesL.length > 1')
select.selector.dataset-color-0(on:change!='{onSelectBundleL}')
+optionsL
+else
.label.dataset-color-0 {viewModel.nameL}
+if('$bundleNamesR.length > 1')
select.selector.dataset-color-1(on:change!='{onSelectBundleR}')
+optionsR
+else
.label.dataset-color-1 {viewModel.nameR}
.spacer-fixed
.header-group
.label Thresholds:
Expand Down Expand Up @@ -91,6 +121,24 @@ function onHome() {
.label:not(:last-child)
margin-right: 1rem
select
margin-right: 1rem
font-family: Roboto, sans-serif
font-size: 1em
// XXX: Remove browser-provided background, but preserve arrow; based on:
// https://stackoverflow.com/a/57510283
-webkit-appearance: none
-moz-appearance: none
appearance: none
padding: .2rem 1.6rem .2rem .4rem
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23555'><polygon points='0,0 100,0 50,60'/></svg>") no-repeat
background-size: .8rem
background-position: calc(100% - .4rem) 70%
background-repeat: no-repeat
background-color: #353535
border: none
border-radius: .4rem
.line
min-height: 1px
margin-bottom: 1rem
Expand Down
14 changes: 11 additions & 3 deletions packages/check-ui-shell/src/components/stats/stats-table-vm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ export function createStatsTableViewModel(
return n === 0 ? '' : `${signed(n, 1)}%`
}

function pctChange(s0: number, s1: number): number {
if (s0 !== 0) {
return ((s1 - s0) / s0) * 100
} else {
return 0
}
}

const modelSpecL = compareConfig.bundleL.model.modelSpec
const modelSpecR = compareConfig.bundleR.model.modelSpec

Expand All @@ -38,17 +46,17 @@ export function createStatsTableViewModel(
const modelSizeL = modelSpecL.modelSizeInBytes
const modelSizeR = modelSpecR.modelSizeInBytes
const modelSizeChange = modelSizeR - modelSizeL
const modelSizePctChange = ((modelSizeR - modelSizeL) / modelSizeL) * 100
const modelSizePctChange = pctChange(modelSizeL, modelSizeR)

const dataSizeL = modelSpecL.dataSizeInBytes
const dataSizeR = modelSpecR.dataSizeInBytes
const dataSizeChange = dataSizeR - dataSizeL
const dataSizePctChange = ((dataSizeR - dataSizeL) / dataSizeL) * 100
const dataSizePctChange = pctChange(dataSizeL, dataSizeR)

const avgTimeL = perfReportL.avgTime || 0
const avgTimeR = perfReportR.avgTime || 0
const avgTimeChange = avgTimeR - avgTimeL
const avgTimePctChange = avgTimeL > 0 ? ((avgTimeR - avgTimeL) / avgTimeL) * 100 : 0
const avgTimePctChange = pctChange(avgTimeL, avgTimeR)

const minTimeL = perfReportL.minTime
const minTimeR = perfReportR.minTime
Expand Down
4 changes: 2 additions & 2 deletions packages/check-ui-shell/src/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ sub {
*/

:root {
--dataset-0: deepskyblue;
--dataset-1: crimson;
--dataset-0: crimson;
--dataset-1: deepskyblue;
--bucket-0: green;
--bucket-1: orange;
--bucket-2: orangered;
Expand Down
12 changes: 7 additions & 5 deletions packages/check-ui-shell/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import type { ConfigOptions, SuiteSummary } from '@sdeverywhere/check-core'

export function initAppShell(
configOptions: ConfigOptions,
suiteSummary?: SuiteSummary,
containerId = 'app-shell-container'
): unknown
export interface AppShellOptions {
suiteSummary?: SuiteSummary
containerId?: string
bundleNames?: string[]
}

export function initAppShell(configOptions: ConfigOptions, appShellOptions?: AppShellOptions): unknown
Loading

0 comments on commit 6425eb8

Please sign in to comment.