Skip to content

Commit d1e7942

Browse files
committed
WIP #352 - Work towards redesigning the view mode
Includes a lot of work on making the features view responsive. The redesign means that horizontal space has been saved on quite a few elements, so that the page works better on handheld browsers.
1 parent 66a83d9 commit d1e7942

7 files changed

Lines changed: 143 additions & 102 deletions

File tree

CSF.Screenplay.JsonToHtmlReport.Template/src/css/content.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@
3535
}
3636
@media screen and (max-width: 900px) {
3737
h3 {
38-
font-size: 1.1em;
38+
font-size: 1.3em;
3939
line-height: 1.3em;
4040
font-weight: normal;
4141
}
4242
h4 {
43-
font-size: 1.05em;
43+
font-size: 1.1em;
4444
line-height: 1.3em;
4545
font-weight: normal;
4646
}

CSF.Screenplay.JsonToHtmlReport.Template/src/css/features.css

Lines changed: 71 additions & 71 deletions
Large diffs are not rendered by default.

CSF.Screenplay.JsonToHtmlReport.Template/src/js/ReportWriter/FeatureElementCreator.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getScenarioElementCreator } from './ScenarioElementCreator';
22
import { getElementById } from '../getElementById';
3+
import { getNameHtml } from './getNameHtml';
34

45
export class FeatureElementCreator {
56
constructor(featureTemplate, scenarioElementCreator) {
@@ -13,13 +14,11 @@ export class FeatureElementCreator {
1314

1415
if(hasFailures) featureElement.firstElementChild.classList.add('Failures');
1516

16-
featureElement.querySelector('.featureName').textContent = feature.feature
17-
? feature.feature.Name
18-
: 'No Feature name';
17+
featureElement.querySelector('.featureName').replaceChildren(getNameHtml(feature.feature));
1918
featureElement.querySelector('.featureName').addEventListener('click', ev => ev.currentTarget.parentElement.classList.toggle('collapsed'));
2019

2120
const featureIdentifierElement = featureElement.querySelector('.featureIdentifier');
22-
if (feature.feature && !feature.feature.IsGeneratedId)
21+
if (feature.feature && !feature.feature.IsGeneratedId && feature.feature.Name != feature.feature.Id)
2322
featureIdentifierElement.textContent = feature.feature.Id;
2423
else
2524
featureIdentifierElement.remove();
@@ -31,6 +30,7 @@ export class FeatureElementCreator {
3130
}
3231
return featureElement;
3332
}
33+
3434
}
3535

3636
export function getFeatureElementCreator() {

CSF.Screenplay.JsonToHtmlReport.Template/src/js/ReportWriter/ReportableElementCreator.js

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ export class ReportableElementCreator {
1010
createReportableElement(reportable, litebox) {
1111
const reportableElement = this.templateElement.content.cloneNode(true);
1212

13-
this.#setupReportableType(reportableElement, reportable);
14-
setContentOrRemove(reportableElement, reportable, '.phase', r => r.Phase, r => r.Phase);
13+
this.#setupReportableKind(reportableElement, reportable);
14+
reportableElement.querySelector('.phase').textContent = reportable.Phase;
1515
setContentOrRemove(reportableElement, reportable, '.report', r => r.Report, r => r.Report);
16+
if(reportable.Phase && reportable.Report) {
17+
reportableElement.querySelector('.report').classList.add('hasPhase');
18+
reportableElement.querySelector('.report').classList.add(`phase_${reportable.Phase}`);
19+
}
1620
setContentOrRemove(reportableElement, reportable, '.exception', r => r.Exception && !r.ExceptionIsBubbling, r => r.Exception);
1721
this.#setupResult(reportableElement, reportable);
1822
this.#setupPerformableType(reportableElement, reportable);
@@ -22,28 +26,27 @@ export class ReportableElementCreator {
2226
return reportableElement;
2327
}
2428

25-
#setupReportableType(reportableElement, reportable) {
26-
const typeElement = reportableElement.querySelector('.type');
27-
typeElement.classList.add(reportable.Kind);
28-
switch (reportable.Kind) {
29+
#setupReportableKind(reportableElement, reportable) {
30+
const infoElement = reportableElement.querySelector('.reportableInfo');
31+
infoElement.classList.add(reportable.Kind);
32+
reportableElement.querySelector('.kind').textContent = this.#getHumanReadableKind(reportable.Kind);
33+
}
34+
35+
#getHumanReadableKind(kind) {
36+
switch (kind) {
2937
case 'ActorCreatedReport':
30-
typeElement.setAttribute('title', 'Actor created');
31-
break;
38+
return 'Actor created';
3239
case 'ActorGainedAbilityReport':
33-
typeElement.setAttribute('title', 'Actor gained ability');
34-
break;
40+
return 'Actor gained ability';
3541
case 'ActorSpotlitReport':
36-
typeElement.setAttribute('title', 'Actor put into the spotlight');
37-
break;
42+
return 'Actor put into the spotlight';
3843
case 'SpotlightTurnedOffReport':
39-
typeElement.setAttribute('title', 'Spotlight turned off');
40-
break;
44+
return 'Spotlight turned off';
4145
case 'PerformableReport':
42-
typeElement.setAttribute('title', 'Actor executed a performable');
43-
break;
46+
return 'Actor executed a performable';
47+
default:
48+
return kind;
4449
}
45-
46-
reportableElement.querySelector('.type i').textContent = reportable.Kind;
4750
}
4851

4952
#setupResult(reportableElement, reportable) {
@@ -55,9 +58,12 @@ export class ReportableElementCreator {
5558
}
5659

5760
#setupPerformableType(reportableElement, reportable) {
58-
const performableTypeElement = reportableElement.querySelector('.performableType');
59-
if (reportable.Type) performableTypeElement.querySelector('i').textContent = reportable.Type;
60-
else performableTypeElement.remove()
61+
const performableTypeElement = reportableElement.querySelector('.dotnetType');
62+
if (reportable.Type) performableTypeElement.textContent = reportable.Type;
63+
else {
64+
performableTypeElement.textContent = 'Not applicable';
65+
performableTypeElement.classList.add('notApplicable');
66+
}
6167
}
6268

6369
#setupAssets(reportableElement, reportable, litebox) {

CSF.Screenplay.JsonToHtmlReport.Template/src/js/ReportWriter/ScenarioElementCreator.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { getReportableElementCreator } from './ReportableElementCreator';
22
import { setContentOrRemove } from './setContentOrRemove';
33
import { getElementById } from '../getElementById';
4+
import { getNameHtml } from './getNameHtml';
45

56
export class ScenarioElementCreator {
67
constructor(scenarioTemplate, reportableElementCreator) {
@@ -14,10 +15,10 @@ export class ScenarioElementCreator {
1415
if(scenario.performance.Outcome == 'Failed')
1516
scenarioElement.firstElementChild.classList.add('Failed');
1617

17-
scenarioElement.querySelector('.scenarioName').textContent = scenario.scenario.Name;
18+
scenarioElement.querySelector('.scenarioName').replaceChildren(getNameHtml(scenario.scenario));
1819
scenarioElement.querySelector('.scenarioName').addEventListener('click', ev => ev.currentTarget.parentElement.classList.toggle('collapsed'));
1920

20-
setContentOrRemove(scenarioElement, scenario.scenario, '.scenarioIdentifier', s => !s.IsGeneratedId, s => s.Id);
21+
setContentOrRemove(scenarioElement, scenario.scenario, '.scenarioIdentifier', s => !s.IsGeneratedId && s.Name != s.Id, s => s.Id);
2122

2223
const reportablesElement = scenarioElement.querySelector('.reportableList');
2324
for (const reportable of scenario.performance.Reportables) {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const dotnetNamespaceQualifiedNameMatcher = /^\w+(?:\.\w+)+$/i;
2+
3+
export const getNameHtml = (featureOrScenario) => {
4+
const name = featureOrScenario ? featureOrScenario.Name : 'No name';
5+
if(!looksLikeDotnetNamespaceQualifiedName(name))
6+
return document.createTextNode(name);
7+
const nameParts = name.split('.');
8+
return document.createTextNode(nameParts.reduce((acc, next, idx) => idx == 0 ? acc + next : acc + '.\u00ad' + next, ''));
9+
}
10+
11+
const looksLikeDotnetNamespaceQualifiedName = (name) => dotnetNamespaceQualifiedNameMatcher.test(name);

CSF.Screenplay.JsonToHtmlReport.Template/src/template.html

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,34 @@ <h4 class="scenarioName" title="Scenario name; click to expand/collapse">Scenari
7373
</template>
7474
<template id="reportableTemplate">
7575
<li class="collapsed">
76-
<span class="type"><i>Reportable type name</i></span><span class="phase">Given</span><span class="report">Report text</span>
76+
<div class="report">Report text</div>
7777
<div class="result">Result</div>
7878
<code class="exception">Exception</code>
7979
<aside>
80-
<span class="performableType"><i>Performable .NET type name</i></span>
80+
<div class="reportableInfo">
81+
<div>
82+
<table>
83+
<colgroup>
84+
<col class="property">
85+
<col class="value">
86+
</colgroup>
87+
<tbody>
88+
<tr>
89+
<th>Kind</th>
90+
<td class="kind">ActorCreatedReport</td>
91+
</tr>
92+
<tr>
93+
<th>Phase</th>
94+
<td class="phase">Given</td>
95+
</tr>
96+
<tr>
97+
<th>.NET type</th>
98+
<td class="dotnetType">Not applicable</td>
99+
</tr>
100+
</tbody>
101+
</table>
102+
</div>
103+
</div>
81104
<div class="assets" title="Assets produced from this performable"><ul></ul></div>
82105
</aside>
83106
<ol class="reportableList collapsible"></ol>

0 commit comments

Comments
 (0)