Skip to content

Commit fd3f25d

Browse files
committed
Produce Reports with some prompts
Does not fully resolve this feature but does go a long way into producing better reports. #65 Fixes #195
1 parent dcc8f89 commit fd3f25d

File tree

20 files changed

+757
-130
lines changed

20 files changed

+757
-130
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ The following is a list of test statistics for the project by date and commit
103103
| 2023-01-04 | [359948b](https://github.com/stamp-web/stamp-web-aurelia/commit/359948b689f088ec8c8554044cab96c24ffe1a77) | 107 | 18.80% |
104104
| 2023-09-21 | [4412730](https://github.com/stamp-web/stamp-web-aurelia/commit/441273055dc1af57257aba29f929923799563325) | 123 | 20.27% |
105105
| 2023-10-08 | [054cb00](https://github.com/stamp-web/stamp-web-aurelia/commit/054cb004b15133867f98c10276397a1f2a1f88be) | 134 | 20.68% |
106+
| 2023-11-01 | | 160 | 22.38% |
106107

107108
## Optimizing for Browsers
108109

resources/locales/en/stamp-web.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,13 @@
7878
"description": "Description",
7979
"details-title": "Details",
8080
"filtering-catalogue": "Filtering Catalogue",
81+
"generate-report": "Generate Report",
8182
"grade": "Grade",
8283
"grade-select": "Select grade",
8384
"hide": "close",
8485
"issue": "Year of Issue",
86+
"includeCountries": "Include Countries",
87+
"includeNotes": "Include Notes",
8588
"name": "Name",
8689
"modify-existing": "Modify existing values",
8790
"modifyTimestamp": "Modified",
@@ -100,7 +103,8 @@
100103
"seller-select": "Select a seller",
101104
"stamp-collection": "Stamp collection",
102105
"stamp-collection-select": "Select a stamp collection",
103-
"switchToCreate-hint": "Switch to create stamp"
106+
"switchToCreate-hint": "Switch to create stamp",
107+
"update-image-paths": "Update image paths"
104108
},
105109
"filters": {
106110
"filter": "Filter",
@@ -138,6 +142,7 @@
138142
"nameRequired": "Name is required",
139143
"numberRequired": "Number is required",
140144
"numberInvalid": "Number exceeds the 25 character limit",
145+
"stampCollectionRequired": "Stamp Collection is required",
141146
"resolveErrors": "Resolve issues to continue",
142147
"valueInvalid": "Value is not a number"
143148
},
@@ -211,6 +216,17 @@
211216
"paging-toolbar": {
212217
"page": "Page"
213218
},
219+
"reports": {
220+
"name": "Report Title",
221+
"action": "Generate",
222+
"condition": "Condition",
223+
"country": "Country",
224+
"defaultTitle": "Filtered Stamps",
225+
"description": "Description",
226+
"notes": "Notes",
227+
"number": "Number",
228+
"value": "Cat. Value"
229+
},
214230
"footer-statistics": {
215231
"catalogue-value": "Report on catalogue value",
216232
"purchased": "Report on price paid",

src/events/event-managed.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export const EventNames = {
3636
create: 'create',
3737
manageEntity: 'manage-entity',
3838
entityDelete: 'entity-delete',
39+
generateReport: 'generate-report',
3940
selectEntity: 'select-entity',
4041
entityFilter: 'entity-filter',
4142
loadingStarted: 'loading-started',

src/reports/report-helper.js

Lines changed: 110 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import {LogManager} from 'aurelia-framework';
1717
import {Condition, CurrencyCode} from '../util/common-models';
1818
import {asCurrencyValueConverter} from '../resources/value-converters/as-currency-formatted';
19-
19+
import {I18N} from 'aurelia-i18n';
2020
import * as reportStyles from './report-styles.json';
2121

2222
import _ from 'lodash';
@@ -25,14 +25,69 @@ const logger = LogManager.getLogger('report-helper');
2525

2626
export class ReportHelper {
2727

28+
countries = [];
29+
2830
static inject() {
29-
return [ReportValueConverter];
31+
return [ReportValueConverter, I18N];
3032
}
3133

32-
constructor(reportValueConverter) {
34+
constructor(reportValueConverter, i18next) {
3335
this.converter = reportValueConverter;
36+
this.i18next = i18next;
3437
}
3538

39+
buildReport(stamps, countries, reportValue, options) {
40+
let reportModel = _.get(options, 'model', {});
41+
let title = _.get(reportModel, 'title', this.i18next.tr('reports.defaultTitle'));
42+
let includeCountries = _.get(reportModel, 'includeCountries', false);
43+
let includeNotes = _.get(reportModel, 'includeNotes', false);
44+
45+
let columns = [
46+
{name: ' ', type: 'issues', value: 'stampOwnerships[0]'},
47+
{name: this.i18next.tr('reports.number'), type: 'catalogueNumber', value: 'activeCatalogueNumber.number'},
48+
{name: this.i18next.tr('reports.description'), type: 'text', value: 'rate', additional: ['description'], width: '*'},
49+
{name: this.i18next.tr('reports.condition'), type: 'condition', value: 'activeCatalogueNumber.condition'},
50+
{
51+
name: this.i18next.tr('reports.value'),
52+
type: 'currencyValue',
53+
value: 'activeCatalogueNumber.value',
54+
additional: ['activeCatalogueNumber.code']
55+
}
56+
];
57+
if(includeCountries) {
58+
columns.splice(1,0, {name: this.i18next.tr('reports.country'), type: 'country', value: 'countryRef'});
59+
}
60+
if(includeNotes) {
61+
let index = includeCountries ? 4 : 3;
62+
columns.splice(index,0, {name: this.i18next.tr('reports.notes'), type: 'notes', value: 'stampOwnerships[0]', width: '*'});
63+
}
64+
65+
let tmodel = this.generateTableModel(stamps, countries,{
66+
cols: columns
67+
});
68+
let styles = this.getStandardStyleDefinition();
69+
let opts = {
70+
content: []
71+
};
72+
73+
opts.content.push(this.generateText(`Report: ${title}`, 'header'));
74+
opts.content.push(this.generateText(`Total number of stamps: ${stamps.length}`, 'text'));
75+
opts.content.push(this.generateText(`Total value: ${reportValue}`, 'text'));
76+
opts.content.push({
77+
table: tmodel, style: 'table', layout: {
78+
hLineColor: (i, node) => {
79+
return '#aaa';
80+
},
81+
vLineColor: (i, node) => {
82+
return '#aaa';
83+
}
84+
}
85+
});
86+
opts.styles = styles;
87+
return opts;
88+
}
89+
90+
3691
getStandardStyleDefinition() {
3792
return reportStyles;
3893
}
@@ -44,48 +99,69 @@ export class ReportHelper {
4499
};
45100
}
46101

47-
generateTableModel(stamps, config) {
102+
generateTableModel(stamps, countries, config) {
48103
let model = {
49-
body: []
104+
body: [],
105+
widths: []
50106
};
51107
if (!_.isEmpty(config.cols)) {
52108
let tr = [];
109+
53110
_.forEach(config.cols, col => {
54111
tr.push({ text: col.name || col.type, style: 'tableHeader'});
112+
model.widths.push(col.width || 'auto');
55113
});
56114
model.headerRows = 1;
57-
model.widths = ['auto', '*', 'auto', 'auto'];
58115
model.body.push(tr);
59-
}
60116

61-
_.forEach(stamps, stamp => {
62-
let row = [];
63-
_.forEach(config.cols, col => {
64-
let val = _.get(stamp, col.value);
65-
switch (col.type) {
66-
case 'catalogueNumber':
67-
row.push(val);
68-
break;
69-
case 'condition':
70-
row.push(this.converter.fromCondition(val));
71-
break;
72-
case 'currencyValue':
73-
let currencyCode = _.get(stamp, col.code, 'EUR');
74-
let v = this.converter.fromCurrencyValue(val, currencyCode);
75-
row.push(v);
76-
break;
77-
case 'text':
78-
_.forEach(col.additional, a => {
79-
val += ' ' + _.get(stamp, a, '');
80-
});
81-
row.push(val);
82-
break;
83-
}
117+
_.forEach(stamps, stamp => {
118+
let row = [];
119+
_.forEach(config.cols, col => {
120+
row.push(this.generateTableCellValue(stamp, col, countries));
121+
});
122+
model.body.push(row);
84123
});
85-
model.body.push(row);
86-
});
124+
}
87125
return model;
88126
}
127+
128+
generateTableCellValue(stamp, col, countries) {
129+
let val = _.get(stamp, col.value);
130+
let result = '';
131+
switch (col.type) {
132+
case 'catalogueNumber':
133+
result = val;
134+
break;
135+
case 'condition':
136+
result = this.converter.fromCondition(val);
137+
break;
138+
case 'currencyValue':
139+
let currencyCode = _.get(stamp, col.code, CurrencyCode.USD.key);
140+
result = this.converter.fromCurrencyValue(val, currencyCode);
141+
break;
142+
case 'country':
143+
let c = _.find(countries, {id: val});
144+
result = c ? c.name : '';
145+
break;
146+
case 'issues':
147+
if (val && val.deception > 0) {
148+
result = '\u0394';
149+
} else if (val && val.defects > 0) {
150+
result = '\u00D7';
151+
}
152+
break;
153+
case 'notes':
154+
result = (val && val.notes) ? val.notes : '';
155+
break;
156+
case 'text':
157+
_.forEach(col.additional, a => {
158+
val += ' ' + _.get(stamp, a, '');
159+
});
160+
result = val;
161+
break;
162+
}
163+
return result;
164+
}
89165
}
90166

91167
export class ReportValueConverter {
@@ -108,7 +184,7 @@ export class ReportValueConverter {
108184
let value = '';
109185
switch (condition) {
110186
case Condition.MINT.ordinal:
111-
case Condition.MINT_HH:
187+
case Condition.MINT_HH.ordinal:
112188
value = '*';
113189
break;
114190
case Condition.MINT_NH.ordinal:
@@ -119,7 +195,7 @@ export class ReportValueConverter {
119195
break;
120196
case Condition.USED.ordinal:
121197
case Condition.CTO.ordinal:
122-
value = 'u';
198+
value = 'u'; // '\u00f8';
123199
break;
124200
case Condition.MANUSCRIPT.ordinal:
125201
value = '~';

src/resources/elements/editor-dialog.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<div class="messaging" show.bind="errorMsg !== ''">
1414
<i class="sw-icon-attention" ></i> ${errorMsg}
1515
</div>
16-
<button type="button" class="btn btn-primary editor-save" tabindex="5000" click.delegate="save()" disabled.bind="!valid">${'actions.save'|t}</button>
16+
<button type="button" class="btn btn-primary editor-save" tabindex="5000" click.delegate="save()" disabled.bind="!valid">${saveText}</button>
1717
<button type="button" class="btn btn-secondary editor-cancel" tabindex="5050" data-bs-dismiss="modal">${'actions.cancel'|t}</button>
1818
</div>
1919
</div>

src/resources/elements/editor-dialog.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,13 @@ import {EventNames, EventManaged} from '../../events/event-managed';
2424
@bindable('content')
2525
@bindable('title')
2626
@bindable('icon')
27+
@bindable('saveText')
28+
2729
export class EditorDialog extends EventManaged {
2830

2931
static inject = [EventAggregator, I18N];
3032

33+
@bindable publishEvent = EventNames.save;
3134
errorMsg = '';
3235
subscriptions = [];
3336
valid = true;
@@ -37,6 +40,7 @@ export class EditorDialog extends EventManaged {
3740
this.i18n = i18n;
3841
this.eventBus = eventBus;
3942
this.setupSubscriptions();
43+
this.saveText = this.saveText || this.i18n.tr('actions.save');
4044
}
4145

4246
modelChanged() {
@@ -67,7 +71,7 @@ export class EditorDialog extends EventManaged {
6771
}
6872

6973
save() {
70-
this.eventBus.publish(EventNames.save, {model: this.model, aspects: this.aspects});
74+
this.eventBus.publish(this.publishEvent, {model: this.model, aspects: this.aspects});
7175

7276
}
7377
}

src/resources/elements/editor-dialog.scss

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ editor-dialog {
2121
background-color: $theme-appbar-bg;
2222
color: $theme-appbar-color;
2323
display: flex;
24-
25-
padding: $theme-padding-base;
24+
padding: 0;
2625
}
2726
}
2827

@@ -34,8 +33,15 @@ editor-dialog {
3433
font-size: $theme-font-size-sm;
3534
}
3635

37-
.checkbox {
36+
.checkbox, input[type='checkbox'] {
3837
height: 1.6rem;
38+
margin-right: $theme-margin-thin;
39+
}
40+
41+
label {
42+
align-items: start;
43+
padding-top: $theme-padding-thin + $theme-padding-thinner;
44+
display: flex;
3945
}
4046
}
4147

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<template>
2+
<require from="../../value-converters/empty-text"></require>
3+
<form>
4+
<div class="form-group row">
5+
<label for="report-name" class="col-sm-3">${'reports.name'|t}</label>
6+
<div class="col-sm-9">
7+
<input id="report-name" tabindex="10" class="form-control" type="text" value.bind="model.title | emptyText">
8+
</div>
9+
</div>
10+
<div class="form-group row">
11+
<span class="col-sm-3"></span>
12+
<label class="col-sm-9">
13+
<input type="checkbox" tabindex="90" checked.bind="model.includeCountries">
14+
<span>${'editor.includeCountries'|t}</span>
15+
</label>
16+
</div>
17+
<div class="form-group row">
18+
<span class="col-sm-3"></span>
19+
<label class="col-sm-9">
20+
<input type="checkbox" tabindex="90" checked.bind="model.includeNotes">
21+
<span>${'editor.includeNotes'|t}</span>
22+
</label>
23+
</div>
24+
</form>
25+
</template>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
Copyright 2023 Jason Drake
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
import _ from 'lodash';
17+
import {EventNames} from "../../../events/event-managed";
18+
import {inject} from "aurelia-framework";
19+
20+
@inject()
21+
export class ReportBuilder {
22+
23+
model;
24+
25+
activate(options) {
26+
this.model = options;
27+
}
28+
29+
save() {
30+
this.eventBus.publish(EventNames.generateReport, {model: this.model});
31+
}
32+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "../../../theme/_semantic.scss";

0 commit comments

Comments
 (0)