Skip to content

Commit f95e43a

Browse files
committed
feat: add file when the mimeType is not geoJSON
1 parent 6405299 commit f95e43a

File tree

13 files changed

+359
-63
lines changed

13 files changed

+359
-63
lines changed

src/common/ComplexInputs.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import {
2+
UploadNonLayerFile,
3+
GetLayerUrlFromId
4+
} from "../components/Layers/RemoteStorage";
5+
6+
export class Input {
7+
constructor(mimeType) {
8+
this.mimeType = mimeType;
9+
}
10+
11+
getData() {
12+
throw new Error("Non Implemented");
13+
}
14+
}
15+
16+
export class LayerInput extends Input {
17+
constructor(mimeType, layerId) {
18+
super(mimeType);
19+
this.layerId = layerId;
20+
}
21+
22+
getData() {
23+
return GetLayerUrlFromId(this.layerId);
24+
}
25+
}
26+
27+
export class FileInput extends Input {
28+
constructor(mimeType, file) {
29+
super(mimeType);
30+
this.file = file;
31+
}
32+
33+
getData() {
34+
return UploadNonLayerFile(this.file).then(GetLayerUrlFromId);
35+
}
36+
}

src/common/FileFormats.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export default {
2+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
3+
ext: ".xlsx",
4+
displayName: "Excel File",
5+
isLayer: false
6+
},
7+
"application/json": {
8+
ext: ".json",
9+
displayName: "Map Layer",
10+
isLayer: true
11+
},
12+
"application/vnd.geo+json": {
13+
ext: ".json",
14+
displayName: "Map Layer",
15+
isLayer: true
16+
}
17+
};

src/common/utils/wpsjs.js

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -113,35 +113,37 @@ export function ExecuteProcess(
113113
});
114114

115115
// Array of arrays of WPS inputs
116+
// Denote: Some of data is promises, some is literal
116117
const inputsByIdentifier = inputs.map(input =>
117118
input.values.map(value => {
118119
if (input.type === InputTypes.COMPLEX) {
119-
const format = input.formats.filter(f =>
120-
layerMimeTypeProdicate(f.mimeType)
121-
)[0];
122-
if (!format)
123-
throw new Error(`No valid input mimetype for input: ${input.id}`);
124-
return GenerateComplexInput(
125-
input.id,
126-
layerFromIdFetcher(value),
127-
format.mimeType,
128-
complexAsReference
120+
return Promise.resolve(value.getData()).then(data =>
121+
GenerateComplexInput(
122+
input.id,
123+
data,
124+
value.mimeType,
125+
complexAsReference
126+
)
129127
);
130128
} else return GenerateLiteralInput(input.id, value);
131129
})
132130
);
133131

134-
const flatInputs = Array.prototype.concat.apply([], inputsByIdentifier);
135-
136-
wpsInstance.execute(
137-
resolve,
138-
identifier,
139-
"document",
140-
"sync",
141-
false,
142-
flatInputs,
143-
outputs
132+
const flatInputsPromises = Array.prototype.concat.apply(
133+
[],
134+
inputsByIdentifier
144135
);
136+
Promise.all(flatInputsPromises).then(flatInputs => {
137+
wpsInstance.execute(
138+
resolve,
139+
identifier,
140+
"document",
141+
"sync",
142+
false,
143+
flatInputs,
144+
outputs
145+
);
146+
});
145147
}).then(response => {
146148
return resolveResponse(response, response => response.executeResponse);
147149
});

src/components/LayerInput/index.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/components/LayerInput/LayerInput.js renamed to src/components/LayerSelector/LayerSelector.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,40 @@ import React from "react";
22
import PropTypes from "prop-types";
33
import Select from "react-select";
44

5-
class LayerInput extends React.Component {
5+
class LayerSelector extends React.Component {
66
constructor(props) {
77
super(props);
88

99
this.handleSelect = this.handleSelect.bind(this);
1010
}
1111

1212
handleSelect({ value }) {
13-
this.props.onSelect(value, this.props.id);
13+
this.props.onSelect(value);
1414
}
1515

1616
render() {
1717
const { layers, className } = this.props;
18-
const layerId = this.props.value;
18+
const layerInput = this.props.value;
1919
const selectableLayers = layers.map(layer => ({
2020
value: layer.id,
2121
label: layer.displayName
2222
}));
23+
24+
const selectedLayer = layerInput ? selectableLayers.filter(l => l.value === layerInput.layerId) : null
25+
2326
return (
2427
<Select
2528
className={className}
26-
value={selectableLayers.filter(l => l.value === layerId)}
29+
value={selectedLayer}
2730
onChange={this.handleSelect}
2831
options={selectableLayers}
2932
/>
3033
);
3134
}
3235
}
3336

34-
LayerInput.propTypes = {
37+
LayerSelector.propTypes = {
3538
onSelect: PropTypes.func
3639
};
3740

38-
export default LayerInput;
41+
export default LayerSelector;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './LayerSelector';

src/components/Layers/RemoteStorage.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ export function UploadFromUrl(url) {
1515
.then(res => res.data.id);
1616
}
1717

18+
export function UploadNonLayerFile(file) {
19+
const formData = new FormData();
20+
formData.append("file", file);
21+
return axios
22+
.post(`${layerServerPath}/api/uploadNonLayer`, formData, {
23+
headers: {
24+
"Content-Type": "multipart/form-data"
25+
}
26+
})
27+
.then(res => res.data.id);
28+
}
29+
1830
export function UploadFromFiles(element) {
1931
const formData = new FormData();
2032

@@ -28,6 +40,5 @@ export function UploadFromFiles(element) {
2840
"Content-Type": "multipart/form-data"
2941
}
3042
})
31-
.then(res => res.data.ids)
32-
;
43+
.then(res => res.data.ids);
3344
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import React from "react";
2+
import MimetypeDropdown from "./MimetypeDropdown";
3+
import LayerSelector from "../LayerSelector";
4+
import FileFormats from "../../common/FileFormats";
5+
import { LayerInput, FileInput } from "../../common/ComplexInputs";
6+
7+
export default class ComplexInput extends React.Component {
8+
setFormat = ({ mimeType }) => {
9+
if (mimeType !== this.state.currentMimeType) {
10+
this.changeValue(null);
11+
}
12+
this.setState({ currentMimeType: mimeType });
13+
};
14+
15+
state = {
16+
currentMimeType: null
17+
};
18+
19+
// in case the input has changed (for example: other process loaded) we will take the new input first format.
20+
// will set the first format in initializing too.
21+
static getDerivedStateFromProps(props, state) {
22+
const { currentMimeType } = state;
23+
const format = props.formInput.formats.filter(
24+
({ mimeType }) => mimeType === currentMimeType
25+
)[0];
26+
27+
if (!format) {
28+
return { currentMimeType: props.formInput.formats[0].mimeType };
29+
} else {
30+
return null;
31+
}
32+
}
33+
34+
changeValue(value) {
35+
this.props.onChange(value ? [value] : [], this.props.index);
36+
}
37+
38+
onLayerChange = layerId => {
39+
this.changeValue(new LayerInput(this.state.currentMimeType, layerId));
40+
};
41+
onFileChange = e => {
42+
this.changeValue(
43+
new FileInput(this.state.currentMimeType, e.target.files[0])
44+
);
45+
};
46+
47+
onInputFileRef = element => {
48+
this.inputFileRef = element;
49+
};
50+
51+
render() {
52+
const { layers, index, formInput } = this.props;
53+
const { currentMimeType } = this.state;
54+
const isLayer =
55+
FileFormats.hasOwnProperty(currentMimeType) &&
56+
FileFormats[currentMimeType].isLayer;
57+
return (
58+
<div>
59+
<MimetypeDropdown
60+
index={index}
61+
onChange={this.setFormat}
62+
options={formInput.formats}
63+
/>
64+
{isLayer ? (
65+
<LayerSelector
66+
className="layer-select"
67+
layers={layers}
68+
key={index}
69+
value={formInput.values[0]}
70+
onSelect={this.onLayerChange}
71+
/>
72+
) : (
73+
<input
74+
onChange={this.onFileChange}
75+
ref={this.onInputFileRef}
76+
type="file"
77+
name="file"
78+
/>
79+
)}
80+
</div>
81+
);
82+
}
83+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
.mimetype-menu .arrow {
2+
width: 0;
3+
height: 0;
4+
border-left: 5px solid transparent;
5+
border-right: 5px solid transparent;
6+
border-top: 4px solid #000;
7+
display: inline-block;
8+
}
9+
10+
.mimetype-menu.active .arrow {
11+
border-bottom: 5px solid black;
12+
border-top: none;
13+
}
14+
15+
.mimetype-menu {
16+
outline: none;
17+
display: inline-block;
18+
position: relative;
19+
}
20+
21+
.mimetype-menu .mimetype-menu-button {
22+
position: relative;
23+
display: inline-block;
24+
border: 1px solid rgba(0, 0, 0, 0);
25+
border-radius: 5px;
26+
padding: 0 5px;
27+
}
28+
.mimetype-menu.active .mimetype-menu-button {
29+
position: relative;
30+
display: inline-block;
31+
border: 1px solid rgba(0, 0, 0, 0);
32+
border-bottom-left-radius: 0px;
33+
border-bottom-right-radius: 0px;
34+
padding: 0 5px;
35+
cursor: pointer;
36+
}
37+
38+
.mimetype-menu .mimetype-menu-button:hover {
39+
box-shadow: #bbb 0px 2px 2px;
40+
border: 1px solid #ccc;
41+
}
42+
43+
.mimetype-menu.active .mimetype-menu-button {
44+
box-shadow: initial !important;
45+
border: 1px solid #ccc;
46+
border-bottom: 1px solid white;
47+
z-index: 11;
48+
}
49+
50+
.mimetype-menu .mimetype-menu-content {
51+
display: none;
52+
position: absolute;
53+
z-index: 10;
54+
background-color: white;
55+
padding: 3px;
56+
border: 1px solid #ddd;
57+
border-radius: 6px;
58+
border-top-left-radius: 0;
59+
width: 170px;
60+
top: calc(100% - 1px);
61+
}
62+
.mimetype-menu.active .mimetype-menu-content {
63+
display: block;
64+
}
65+
66+
67+
.mimetype-menu .mimetype-menu-item{
68+
cursor: pointer;
69+
transition: background-color 0.25s ease;
70+
}
71+
.mimetype-menu .mimetype-menu-item:hover{
72+
background-color: #e0e0e0;
73+
}

0 commit comments

Comments
 (0)