react-ui-basics 0.0.182 → 0.0.184
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DatePicker.js +5 -2
- package/DatePicker.js.map +1 -1
- package/HttpTools.d.ts +35 -0
- package/HttpTools.js +222 -0
- package/HttpTools.js.map +1 -0
- package/bundle.css +1158 -1158
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/src/DatePicker.tsx +5 -2
- package/src/HttpTools.ts +257 -0
- package/src/index.js +2 -0
package/index.js
CHANGED
|
@@ -23,6 +23,8 @@ export { default as Dropzone } from './Dropzone.js';
|
|
|
23
23
|
export { default as FilteredList } from './FilteredList.js';
|
|
24
24
|
export { default as FloatingActionButton } from './FloatingActionButton.js';
|
|
25
25
|
export { default as FormUploadProgress } from './FormUploadProgress.js';
|
|
26
|
+
import * as HttpTools from './HttpTools.js';
|
|
27
|
+
export { HttpTools };
|
|
26
28
|
export { default as ImageGallery, ImageGalleryContainer } from './ImageGallery.js';
|
|
27
29
|
export { default as MaterialIcon } from './MaterialIcon.js';
|
|
28
30
|
export { default as Modal } from './Modal.js';
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
CHANGED
package/src/DatePicker.tsx
CHANGED
|
@@ -79,14 +79,17 @@ class DatePicker extends React.Component<DatePickerProps, DatePickerState> {
|
|
|
79
79
|
const open = !!this.props.open
|
|
80
80
|
this.setState({
|
|
81
81
|
focused: open
|
|
82
|
-
}
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
if (!this.state.focused && !!prevState.focused) {
|
|
85
|
+
orNoop(this.props.onClose)()
|
|
83
86
|
}
|
|
84
87
|
};
|
|
85
88
|
|
|
86
89
|
componentDidMount() {
|
|
87
90
|
document.addEventListener('mousedown', this.listener = (e) => {
|
|
88
91
|
if (this.state.focused && !this.el.contains(e.target))
|
|
89
|
-
this.setState({focused: false}
|
|
92
|
+
this.setState({focused: false});
|
|
90
93
|
})
|
|
91
94
|
};
|
|
92
95
|
|
package/src/HttpTools.ts
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import {orNoop} from "./Tools";
|
|
2
|
+
|
|
3
|
+
const CONTENT_TYPE_APPLICATION_JSON = 'application/json';
|
|
4
|
+
|
|
5
|
+
const toKeyValue = (key, value) => key && (encodeURIComponent(key) + '=' + encodeURIComponent(value !== null && typeof value === 'object' ? JSON.stringify(value) : value));
|
|
6
|
+
|
|
7
|
+
export const toRequestParams = (params) => (params && Object.keys(params).map(key => {
|
|
8
|
+
const value = params[key];
|
|
9
|
+
if (Array.isArray(value))
|
|
10
|
+
return value.map(it => toKeyValue(key, it)).join('&')
|
|
11
|
+
else
|
|
12
|
+
return toKeyValue(key, value);
|
|
13
|
+
}).join('&')) || '';
|
|
14
|
+
|
|
15
|
+
export type Method = 'GET' | 'DELETE' | 'POST' | 'PUT'
|
|
16
|
+
|
|
17
|
+
export class FetchOptions {
|
|
18
|
+
method?: Method = 'GET'
|
|
19
|
+
headers?: ({ [name: string]: string })
|
|
20
|
+
params?: ({ [name: string]: any }) | FormData | Blob
|
|
21
|
+
multipart?: boolean = false
|
|
22
|
+
async?: boolean = true
|
|
23
|
+
withCredentials?: boolean = true
|
|
24
|
+
timeout?: number
|
|
25
|
+
onTimeout?: ((ev: ProgressEvent) => any)
|
|
26
|
+
onSuccess?: ((t: any) => void)
|
|
27
|
+
onError?: ((e: any, status: number) => void)
|
|
28
|
+
onProgress?: ((ev: ProgressEvent) => any)
|
|
29
|
+
provideCancel?: ((cancelFunction: () => void) => void)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const DEFAULT_OPTIONS = new FetchOptions()
|
|
33
|
+
|
|
34
|
+
export const fetch = <T>(url, options: FetchOptions = DEFAULT_OPTIONS) => {
|
|
35
|
+
const method = options.method || 'GET'
|
|
36
|
+
const params = options.params || {};
|
|
37
|
+
if (method === 'GET' || method === 'DELETE') {
|
|
38
|
+
const serializedData = toRequestParams(params);
|
|
39
|
+
if (serializedData)
|
|
40
|
+
url = url + "?" + serializedData;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const headers = {
|
|
44
|
+
'Accept': CONTENT_TYPE_APPLICATION_JSON,
|
|
45
|
+
...(options.headers || {})
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
let body: FormData | string | Blob
|
|
49
|
+
|
|
50
|
+
if (method === 'POST' || method === 'PUT') {
|
|
51
|
+
if (options.multipart) {
|
|
52
|
+
let formData;
|
|
53
|
+
if (params instanceof FormData) {
|
|
54
|
+
formData = params;
|
|
55
|
+
} else {
|
|
56
|
+
formData = new FormData();
|
|
57
|
+
Object.keys(params).forEach(name => {
|
|
58
|
+
let value = params[name];
|
|
59
|
+
if (Array.isArray(value)) {
|
|
60
|
+
value.forEach(it => formData.append(name, it))
|
|
61
|
+
} else if (value != null)
|
|
62
|
+
formData.append(name, value);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
body = formData;
|
|
66
|
+
} else if (params instanceof Blob || params instanceof FormData) {
|
|
67
|
+
body = params;
|
|
68
|
+
} else {
|
|
69
|
+
headers['Content-Type'] = CONTENT_TYPE_APPLICATION_JSON;
|
|
70
|
+
body = JSON.stringify(params || {}, (key, value) => {
|
|
71
|
+
if (value !== null)
|
|
72
|
+
return value
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let makeRequest = (success, error) => {
|
|
78
|
+
const request = new XMLHttpRequest();
|
|
79
|
+
|
|
80
|
+
const data = body;
|
|
81
|
+
|
|
82
|
+
if (!!(options.withCredentials === void 0 ? true : options.withCredentials))
|
|
83
|
+
request.withCredentials = true;
|
|
84
|
+
|
|
85
|
+
const async = !!(options.async === void 0 ? true : options.async);
|
|
86
|
+
request.open(method, url, async);
|
|
87
|
+
|
|
88
|
+
Object.keys(headers).forEach(key =>
|
|
89
|
+
request.setRequestHeader(key, headers[key])
|
|
90
|
+
);
|
|
91
|
+
const onError = orNoop(error);
|
|
92
|
+
|
|
93
|
+
if (options.timeout && async) {
|
|
94
|
+
request.timeout = options.timeout;
|
|
95
|
+
request.ontimeout = (e) => (options.onTimeout || onError)(e);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const onProgress = options.onProgress;
|
|
99
|
+
if (onProgress) {
|
|
100
|
+
request.upload.onprogress = e => {
|
|
101
|
+
if (e.lengthComputable)
|
|
102
|
+
onProgress(e);
|
|
103
|
+
};
|
|
104
|
+
request.onprogress = onProgress;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
request.onload = () => {
|
|
108
|
+
const responseText = request.responseText;
|
|
109
|
+
const status = request.status;
|
|
110
|
+
if (status >= 200 && status < 400) {
|
|
111
|
+
try {
|
|
112
|
+
orNoop(success)(JSON.parse(responseText || "{}"));
|
|
113
|
+
} catch (e) {
|
|
114
|
+
const message = `Unexpected exception while processing response for ${method} ${url}, status: ${status}, response: '${responseText}', exception:`;
|
|
115
|
+
console.log(message, e)
|
|
116
|
+
onError(new FetchError(message, status, responseText))
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
const message = `Not ok response for ${method} ${url}, status: ${status}, response: '${responseText}'`;
|
|
120
|
+
console.log(message);
|
|
121
|
+
onError(new FetchError(message, status, responseText))
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
request.onerror = onError;
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
if (method === 'POST') {
|
|
129
|
+
if (typeof data === 'string' || data instanceof Blob || data instanceof FormData)
|
|
130
|
+
request.send(data);
|
|
131
|
+
else
|
|
132
|
+
request.send(toRequestParams(data));
|
|
133
|
+
} else
|
|
134
|
+
request.send();
|
|
135
|
+
} catch (e) {
|
|
136
|
+
onError(e);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (options.provideCancel) {
|
|
140
|
+
options.provideCancel(() => request.abort());
|
|
141
|
+
}
|
|
142
|
+
return request
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// if (!window.Promise)
|
|
146
|
+
// return makeRequest(options.onSuccess, options.onError);
|
|
147
|
+
|
|
148
|
+
return new Promise<T>((resolve, reject) => {
|
|
149
|
+
const success = data => (options.onSuccess || resolve)(data);
|
|
150
|
+
const error = (e, status) => (options.onError || reject)(e, status);
|
|
151
|
+
makeRequest(success, error);
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
class FetchError extends Error {
|
|
156
|
+
status: number;
|
|
157
|
+
responseText?: string;
|
|
158
|
+
|
|
159
|
+
constructor(message, status: number, responseText?: string) {
|
|
160
|
+
super(message);
|
|
161
|
+
this.status = status;
|
|
162
|
+
this.responseText = responseText;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
export type Params = { [id: string]: any };
|
|
168
|
+
export type UrlRenderer = (params: Params) => string;
|
|
169
|
+
|
|
170
|
+
const variablePatter = /\{(\w+)\}/g;
|
|
171
|
+
export const createUrlRenderer = (template: string, deleteVars: boolean = false): UrlRenderer => {
|
|
172
|
+
let parts = [];
|
|
173
|
+
let variables = [];
|
|
174
|
+
|
|
175
|
+
let find;
|
|
176
|
+
let prevIndex = 0;
|
|
177
|
+
while ((find = variablePatter.exec(template)) !== null) {
|
|
178
|
+
variables.push(find[1]);
|
|
179
|
+
parts.push(template.substring(prevIndex, find.index));
|
|
180
|
+
prevIndex = find.index + find[0].length;
|
|
181
|
+
}
|
|
182
|
+
if (prevIndex === 0)
|
|
183
|
+
return () => template;
|
|
184
|
+
|
|
185
|
+
parts.push(template.substring(prevIndex, template.length));
|
|
186
|
+
|
|
187
|
+
const m = parts;
|
|
188
|
+
const v = variables;
|
|
189
|
+
return function (params: any) {
|
|
190
|
+
const length = Math.max(m.length, v.length);
|
|
191
|
+
let s = '';
|
|
192
|
+
for (let i = 0; i < length; i++) {
|
|
193
|
+
if (m[i] !== null)
|
|
194
|
+
s += m[i];
|
|
195
|
+
let param = params[v[i]];
|
|
196
|
+
if (params && v[i] !== null && param != null) {
|
|
197
|
+
s += encodeURIComponent(param);
|
|
198
|
+
if (deleteVars)
|
|
199
|
+
delete params[v[i]]
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return s;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const lazy = <T extends Function>(f: ((...any) => T), ...args): any => {
|
|
207
|
+
let result: T;
|
|
208
|
+
return function (): any {
|
|
209
|
+
if (!result)
|
|
210
|
+
result = f.apply(null, args) as T
|
|
211
|
+
|
|
212
|
+
return result.apply(null, arguments)
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
let baseurl = window.location.origin
|
|
217
|
+
export const setBaseUrl = url => baseurl = url
|
|
218
|
+
|
|
219
|
+
export const createGET = <R>(template: string) => {
|
|
220
|
+
let urlMaker: (UrlRenderer) = lazy(createUrlRenderer, template, true);
|
|
221
|
+
return async (params?: Params,) => fetch<R>(`${baseurl}${urlMaker(params)}`, {params});
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
export const createPOST = <R, P extends Params>(template: string) => {
|
|
226
|
+
let urlMaker: (UrlRenderer) = lazy(createUrlRenderer, template);
|
|
227
|
+
return async (params?: P,) => fetch<R>(`${baseurl}${urlMaker(params)}`, {params, method: "POST"});
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
const createBinaryPOST = <R>(template: string) => {
|
|
231
|
+
let urlMaker: (UrlRenderer) = lazy(createUrlRenderer, template, true);
|
|
232
|
+
return async (pathVariables: Params, options: FetchOptions) => {
|
|
233
|
+
let url = `${baseurl}${urlMaker(pathVariables)}`;
|
|
234
|
+
if (Object.keys(pathVariables).length > 0) {
|
|
235
|
+
url += '?' + toRequestParams(pathVariables)
|
|
236
|
+
}
|
|
237
|
+
return fetch<R>(url, options);
|
|
238
|
+
};
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
export const createDELETE = <R>(template: string) => {
|
|
242
|
+
let urlMaker: (UrlRenderer) = lazy(createUrlRenderer, template, true);
|
|
243
|
+
return async (params?: Params,) => fetch<R>(`${baseurl}${urlMaker(params)}`, {params, method: "DELETE"});
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
export interface MultipartOptions {
|
|
247
|
+
onProgress?: ((ev: ProgressEvent) => any)
|
|
248
|
+
provideCancel?: ((cancelFunction: () => void) => void)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export const createMultipart = <R>(template: string) => {
|
|
252
|
+
let urlMaker: (UrlRenderer) = lazy(createUrlRenderer, template);
|
|
253
|
+
return async (params: any, options?: MultipartOptions) => {
|
|
254
|
+
let url = `${baseurl}${urlMaker(params)}`;
|
|
255
|
+
return fetch<R>(url, {params, method: "POST", multipart: true, ...options});
|
|
256
|
+
};
|
|
257
|
+
};
|
package/src/index.js
CHANGED
|
@@ -21,6 +21,7 @@ import Dropzone from "./Dropzone";
|
|
|
21
21
|
import FilteredList from "./FilteredList";
|
|
22
22
|
import FloatingActionButton from "./FloatingActionButton";
|
|
23
23
|
import FormUploadProgress from "./FormUploadProgress";
|
|
24
|
+
import * as HttpTools from "./HttpTools";
|
|
24
25
|
import ImageGallery from "./ImageGallery";
|
|
25
26
|
import {ImageGalleryContainer} from "./ImageGallery";
|
|
26
27
|
import MaterialIcon from "./MaterialIcon";
|
|
@@ -63,6 +64,7 @@ export {
|
|
|
63
64
|
FilteredList,
|
|
64
65
|
FloatingActionButton,
|
|
65
66
|
FormUploadProgress,
|
|
67
|
+
HttpTools,
|
|
66
68
|
ImageGallery,
|
|
67
69
|
ImageGalleryContainer,
|
|
68
70
|
MaterialIcon,
|