Skip to content

Commit be59d77

Browse files
committed
Add file preview
1 parent 4793c85 commit be59d77

File tree

7 files changed

+145
-11
lines changed

7 files changed

+145
-11
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
import { Message, Card, WarningIcon } from 'oskari-ui';
4+
import { ErrorBoundary } from 'oskari-ui/util';
5+
6+
const MAX_COLUMNS = 4;
7+
8+
const ParseHeaderRow = ({ fileContents }) => {
9+
if (!fileContents.headers) {
10+
return null;
11+
}
12+
const headerLineCount = fileContents.headerLines.length;
13+
let previewHeaders = fileContents.headers;
14+
if (fileContents.headers.length > MAX_COLUMNS) {
15+
previewHeaders = fileContents.headers.slice(0, MAX_COLUMNS);
16+
}
17+
return (
18+
<thead>
19+
<tr>
20+
{ previewHeaders.map(h => (<th key={h}>{ h }</th>)) }
21+
</tr>
22+
{ headerLineCount > 1 && <tr>
23+
<HasMoreCell colSpan={ previewHeaders.length }>
24+
+ {headerLineCount - 1} <Message messageKey='fileSettings.rows' />
25+
</HasMoreCell>
26+
</tr>}
27+
</thead>)
28+
}
29+
30+
const PreviewCellStyle = styled.td`
31+
text-align: center;
32+
&.invalid {
33+
box-shadow: inset 0 0 2px 2px rgba(255,50,0,0.4);
34+
padding: 8px;
35+
}
36+
`;
37+
38+
const HasMoreCell = styled.td`
39+
text-align: right !important;
40+
`;
41+
42+
const PreviewCell = ({ data }) => {
43+
const parseable = !!parseFloat(data, 10);
44+
return (<PreviewCellStyle className={parseable ? 'valid' : 'invalid'}>{data} { !parseable && <WarningIcon/>}</PreviewCellStyle>);
45+
};
46+
47+
const ParseDataRow = ({ fileContents }) => {
48+
if (!fileContents.data) {
49+
return null;
50+
}
51+
// only show max 2 rows and 4 columns of data
52+
let previewData = fileContents.data;
53+
const dataCount = previewData.length;
54+
if (previewData.length > 2) {
55+
previewData = previewData.slice(0,2);
56+
}
57+
let colCountOriginal = previewData[0].length;
58+
let colCount = colCountOriginal;
59+
if (colCount > MAX_COLUMNS) {
60+
previewData = previewData.map(data => data.slice(0, MAX_COLUMNS));
61+
colCount = MAX_COLUMNS;
62+
}
63+
const previewRows = previewData.map(data => (
64+
<tr>
65+
{ data.map(cell => (<PreviewCell data={ cell } />)) }
66+
</tr>
67+
));
68+
let extraMessages = [];
69+
if (dataCount > 2 ) {
70+
extraMessages.push(<React.Fragment>{dataCount - 2} <Message messageKey='fileSettings.rows' /></React.Fragment>);
71+
}
72+
if (colCountOriginal > colCount ) {
73+
if (extraMessages.length) {
74+
extraMessages.push(' / ');
75+
}
76+
extraMessages.push(<React.Fragment>{colCountOriginal - colCount} <Message messageKey='fileSettings.columns' /></React.Fragment>);
77+
}
78+
if (extraMessages.length) {
79+
previewRows.push(<tr>
80+
<HasMoreCell colSpan={ colCount }>
81+
+ {extraMessages}
82+
</HasMoreCell>
83+
</tr>);
84+
}
85+
return previewRows;
86+
}
87+
88+
export const FilePreview = ({ fileContents }) => {
89+
if (!fileContents) {
90+
return null;
91+
}
92+
93+
return (
94+
<ErrorBoundary hide={true}>
95+
<Card title={<Message messageKey='fileSettings.previewTitle' />} size="small">
96+
<table>
97+
<ParseHeaderRow fileContents={fileContents} />
98+
<tbody>
99+
<ParseDataRow fileContents={fileContents} />
100+
</tbody>
101+
</table>
102+
</Card>
103+
</ErrorBoundary>);
104+
};

bundles/paikkatietoikkuna/coordinatetransformation/components/FileSettings.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import styled from 'styled-components';
33
import { Message, Checkbox } from 'oskari-ui';
44
import { FileInput } from 'oskari-ui/components/FileInput';
55
import { LabeledSelect, LabeledInput } from './LabeledFields';
6+
import { FilePreview } from './FilePreview';
67
import { InfoIcon } from 'oskari-ui/components/icons';
78
import { SEPARATORS, DECIMAL, DEGREE } from '../constants';
89
import { isDegreeSystem } from '../helper';
@@ -56,7 +57,7 @@ const CheckboxOption = ({id, checked, onChange, controller}) => (
5657
const SelectOption = ({id, value, onChange, controller}) =>
5758
<LabeledSelect localize mandatory label={`fileSettings.options.${id}`} info={id} value={value} options={OPTIONS.options[id]} onChange={value => onChange(id, value)} controller={controller}/>
5859

59-
export const ImportFile = ({ import: values, inputSrs, files, controller }) => {
60+
export const ImportFile = ({ import: values, inputSrs, files, fileContents, controller }) => {
6061
const onChange = (key, value) => controller.setFileSetting('import', key, value);
6162
return (
6263
<Content>
@@ -65,6 +66,7 @@ export const ImportFile = ({ import: values, inputSrs, files, controller }) => {
6566
{ showDegreeUnit(inputSrs) && <SelectOption id='unit' controller={controller} onChange={onChange} value={values.unit}/> }
6667
{ OPTIONS.importSelect.map(id => <SelectOption key={id} id={id} controller={controller} onChange={onChange} value={values[id]}/>)}
6768
{ OPTIONS.importCheckbox.map(id => <CheckboxOption key={id} id={id} controller={controller} onChange={onChange} checked={values[id]}/>)}
69+
<FilePreview fileContents={fileContents} />
6870
</Content>
6971
);
7072
};

bundles/paikkatietoikkuna/coordinatetransformation/handler/FileParser.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { SEPARATORS } from '../constants';
33
export const parseFile = (file) => {
44
return new Promise((resolve, reject) => {
55
if (!file || typeof file.text !== 'function') {
6-
reject(new Error('Not able to parse file'));
6+
reject(new Error('Unable to parse file'));
77
}
88
let lines = [];
99
file.text().then(content => {
@@ -31,6 +31,7 @@ export const parseFileContents = (lines = [], delimiter = ';', headerLineCount =
3131
line.split(delimiter)
3232
.map(cell => cell.trim())
3333
.map(cell => decimalSeparator === ',' ? cell.replace(',', '.') : cell)
34+
// TODO: detect non decimal cells?
3435
);
3536

3637
return {
@@ -44,6 +45,12 @@ export const parseFileContents = (lines = [], delimiter = ';', headerLineCount =
4445
};
4546
};
4647

48+
const interpretFileContents = (lines = []) => {
49+
const delimiter = detectDelimiter(lines[0]);
50+
const headerLineCount = countHeaders(lines, delimiter);
51+
return parseFileContents(lines, delimiter, headerLineCount);
52+
};
53+
4754
const detectDecimalSeparator = (line = '', delimiter = ';') => {
4855
if (!line.trim() || delimiter === ',') {
4956
return '.';
@@ -54,12 +61,6 @@ const detectDecimalSeparator = (line = '', delimiter = ';') => {
5461
return '.';
5562
};
5663

57-
const interpretFileContents = (lines = []) => {
58-
const delimiter = detectDelimiter(lines[0]);
59-
const headerLineCount = countHeaders(lines, delimiter);
60-
return parseFileContents(lines, delimiter, headerLineCount);
61-
};
62-
6364
const detectDelimiter = (line) => {
6465
// comma as last as it very well be the decimal separator as well
6566
const delimiters = [';', '\t', '|', ' ', ','];

bundles/paikkatietoikkuna/coordinatetransformation/handler/ViewHandler.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { showInfoPopup } from '../view/InfoPopup';
33
import { showFilePopup } from '../view/FilePopup';
44
import { showConfirmPopup } from '../view/ConfirmPopup';
55
import { showMapSelectPopup, showMapPreviewPopup } from '../view/MapPopup';
6-
import { SOURCE, MAP, WATCH_JOB, WATCH_URL, TRANSFORM, FILE_DEFAULTS } from '../constants';
6+
import { SOURCE, MAP, WATCH_JOB, WATCH_URL, TRANSFORM, FILE_DEFAULTS, SEPARATORS } from '../constants';
77
import { stateToPTIArray, loadFile, validateTransform, validateFileSettings, parseCoordinateValue, is3DSystem } from '../helper';
88
import { parseFile, parseFileContents } from './FileParser';
99

@@ -127,6 +127,12 @@ class UIHandler extends StateHandler {
127127
}
128128

129129
setFiles (files = []) {
130+
if (files.length === 0) {
131+
this.updateState({
132+
files: [],
133+
fileContents: undefined
134+
});
135+
}
130136
if (files.length !== 1) {
131137
return;
132138
}
@@ -149,9 +155,21 @@ class UIHandler extends StateHandler {
149155
}
150156

151157
setFileSetting (type, key, value) {
152-
// TODO: parseFileContents() based on the new selection
153158
const settings = this.getState()[type];
154-
this.updateState({ [type]: { ...settings, [key]: value } });
159+
const newTypeState = {
160+
[type]: {
161+
...settings,
162+
[key]: value
163+
}
164+
}
165+
const { fileContents } = this.getState();
166+
if (fileContents) {
167+
// parseFileContents() to update parsing based on the new selection
168+
let coordSeparator = SEPARATORS.coordinateSeparator.find(sep => sep.value === newTypeState.import.coordinateSeparator)?.char;
169+
newTypeState.fileContents = parseFileContents(fileContents.lines, coordSeparator, newTypeState.import.headerLineCount)
170+
}
171+
172+
this.updateState(newTypeState);
155173
}
156174
// TODO: refactor
157175
setImport (key, value) {

bundles/paikkatietoikkuna/coordinatetransformation/resources/locale/en.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ Oskari.registerLocalization(
182182
"close": "Close"
183183
},
184184
"fileSettings": {
185+
"rows": "rows",
186+
"columns": "columns",
187+
"previewTitle": "Preview",
185188
"options": {
186189
"decimalSeparator": "Decimal separator",
187190
"coordinateSeparator": "Field separator",

bundles/paikkatietoikkuna/coordinatetransformation/resources/locale/fi.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ Oskari.registerLocalization(
189189
"close": "Sulje"
190190
},
191191
"fileSettings": {
192+
"rows": "riviä",
193+
"columns": "saraketta",
194+
"previewTitle": "Esikatselu",
192195
"options": {
193196
"decimalSeparator": "Desimaalierotin",
194197
"coordinateSeparator": "Sarake-erotin",

bundles/paikkatietoikkuna/coordinatetransformation/resources/locale/sv.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ Oskari.registerLocalization(
182182
"close": "Stäng"
183183
},
184184
"fileSettings": {
185+
"rows": "rader",
186+
"columns": "fält",
187+
"previewTitle": "Förhandsvy",
185188
"options": {
186189
"decimalSeparator": "Skiljetecken för decimaler",
187190
"coordinateSeparator": "Skiljetecken för fält",

0 commit comments

Comments
 (0)