@colisweb/rescript-toolkit 2.15.0 → 2.16.0
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/package.json +1 -1
- package/src/decoders/Toolkit__Decoders.res +171 -289
- package/src/utils/Toolkit__Utils.res +1 -0
- package/src/utils/Toolkit__Utils_Regex.res +7 -0
- package/src/utils/Toolkit__Utils_UnitMeasure.res +206 -27
- package/src/vendors/BsDateFns.res +17 -0
- package/src/vendors/ReactBigCalendar.res +11 -3
package/package.json
CHANGED
|
@@ -121,27 +121,27 @@ module type EnumConfig = {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
module Enum = (Config: EnumConfig) => {
|
|
124
|
-
|
|
124
|
+
%%private(
|
|
125
|
+
let encoder = value => value->Config.enumToJs->Decco.stringToJson
|
|
125
126
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
|
127
|
+
let decoder = json =>
|
|
128
|
+
switch Decco.stringFromJson(json) {
|
|
129
|
+
| Ok(value) =>
|
|
130
|
+
switch Config.enumFromJs(value) {
|
|
131
|
+
| None => Decco.error(~path="", "Invalid enum " ++ value, json)
|
|
132
|
+
| Some(value) => Ok(value)
|
|
133
|
+
}
|
|
134
|
+
| Error(_) as error => error
|
|
134
135
|
}
|
|
135
|
-
| Error(_) as error => error
|
|
136
|
-
}
|
|
137
136
|
|
|
138
|
-
|
|
137
|
+
let codec = (encoder, decoder)
|
|
138
|
+
)
|
|
139
139
|
|
|
140
140
|
let toString = v => v->Config.enumToJs
|
|
141
141
|
let fromString = v => v->Config.enumFromJs
|
|
142
142
|
|
|
143
143
|
@decco
|
|
144
|
-
type t = @decco.codec(codec) enum
|
|
144
|
+
type t = @decco.codec(codec) Config.enum
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
module Option = {
|
|
@@ -161,337 +161,219 @@ module Option = {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
module UnitMeasure = {
|
|
164
|
-
module
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
module type MakeConfig = {
|
|
165
|
+
type t
|
|
166
|
+
let toString: t => string
|
|
167
|
+
let toValue: t => float
|
|
168
|
+
let display: (t, ~digits: int=?, unit) => string
|
|
168
169
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
| Belt.Result.Ok(v) =>
|
|
172
|
-
let valueUnitArray = v->Js.String2.split(" ")
|
|
173
|
-
switch (
|
|
174
|
-
valueUnitArray[0]->Belt.Option.flatMap(Belt.Float.fromString),
|
|
175
|
-
valueUnitArray[1],
|
|
176
|
-
) {
|
|
177
|
-
| (Some(v), Some("mm")) => #mm(v)->Ok
|
|
178
|
-
| (Some(v), Some("cm")) => #cm(v)->Ok
|
|
179
|
-
| (Some(v), Some("dm")) => #dm(v)->Ok
|
|
180
|
-
| (Some(v), Some("km")) => #km(v)->Ok
|
|
181
|
-
| (None, _) => Decco.error("unhandled no value", json)
|
|
182
|
-
| (_, None) => Decco.error("unhandled no unit", json)
|
|
183
|
-
| (_, Some(_)) => Decco.error("unhandled dimension unit", json)
|
|
184
|
-
}
|
|
185
|
-
| Belt.Result.Error(_) as err => err
|
|
186
|
-
}
|
|
170
|
+
let wrapValue: float => t
|
|
171
|
+
}
|
|
187
172
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
let toString = Toolkit__Utils_UnitMeasure.Dimension.toString
|
|
173
|
+
module Make = (C: MakeConfig) => {
|
|
174
|
+
type dimension = C.t
|
|
191
175
|
|
|
192
|
-
|
|
193
|
-
type t = @decco.codec(codec) Toolkit__Utils_UnitMeasure.Dimension.t
|
|
194
|
-
}
|
|
176
|
+
let encoder: Decco.encoder<C.t> = value => value->C.toString->Decco.stringToJson
|
|
195
177
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
178
|
+
let decoder: Decco.decoder<C.t> = json =>
|
|
179
|
+
switch Decco.floatFromJson(json) {
|
|
180
|
+
| Ok(v) => v->C.wrapValue->Ok
|
|
181
|
+
| Error(_) as err => err
|
|
182
|
+
}
|
|
201
183
|
|
|
202
|
-
|
|
203
|
-
value->Toolkit__Utils_UnitMeasure.Dimension.toString()->Decco.stringToJson
|
|
184
|
+
let codec: Decco.codec<dimension> = (encoder, decoder)
|
|
204
185
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
186
|
+
let toValue = C.toValue
|
|
187
|
+
let display = C.display
|
|
188
|
+
let toString = C.toString
|
|
208
189
|
|
|
209
|
-
|
|
210
|
-
|
|
190
|
+
@decco
|
|
191
|
+
type t = @decco.codec(codec) C.t
|
|
192
|
+
}
|
|
211
193
|
|
|
212
|
-
|
|
194
|
+
module type MakeWithUnitConfig = {
|
|
195
|
+
type t
|
|
196
|
+
let toString: t => string
|
|
197
|
+
let toValue: t => float
|
|
198
|
+
let display: (t, ~digits: int=?, unit) => string
|
|
213
199
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
200
|
+
type unitEnum
|
|
201
|
+
let unitEnum_decode: Js.Json.t => result<unitEnum, Decco.decodeError>
|
|
202
|
+
let unitEnum_encode: unitEnum => Js.Json.t
|
|
217
203
|
|
|
218
|
-
|
|
219
|
-
let convert = Toolkit__Utils_UnitMeasure.Dimension.makeMm
|
|
220
|
-
})
|
|
221
|
-
module Cm = Make({
|
|
222
|
-
let convert = Toolkit__Utils_UnitMeasure.Dimension.makeCm
|
|
223
|
-
})
|
|
224
|
-
module Dm = Make({
|
|
225
|
-
let convert = Toolkit__Utils_UnitMeasure.Dimension.makeDm
|
|
226
|
-
})
|
|
227
|
-
module Km = Make({
|
|
228
|
-
let convert = Toolkit__Utils_UnitMeasure.Dimension.makeKm
|
|
229
|
-
})
|
|
230
|
-
}
|
|
204
|
+
let wrapValue: (unitEnum, float) => t
|
|
231
205
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
let encoder: Decco.encoder<Toolkit__Utils_UnitMeasure.Weight.t> = value =>
|
|
235
|
-
value->Toolkit__Utils_UnitMeasure.Weight.display()->Decco.stringToJson
|
|
206
|
+
let errorPrefix: string
|
|
207
|
+
}
|
|
236
208
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
switch (
|
|
242
|
-
valueUnitArray[0]->Belt.Option.flatMap(Belt.Float.fromString),
|
|
243
|
-
valueUnitArray[1],
|
|
244
|
-
) {
|
|
245
|
-
| (Some(v), Some("g")) => #g(v)->Ok
|
|
246
|
-
| (Some(v), Some("kg")) => #kg(v)->Ok
|
|
247
|
-
| (None, _) => Decco.error("unhandled no value", json)
|
|
248
|
-
| (_, None) => Decco.error("unhandled no unit", json)
|
|
249
|
-
| (_, Some(_)) => Decco.error("unhandled weight unit", json)
|
|
250
|
-
}
|
|
209
|
+
module MakeWithUnit = (Config: MakeWithUnitConfig) => {
|
|
210
|
+
let decodeFromString = (string: string) => {
|
|
211
|
+
// match a positive int or float followed by it's unit (capturing int/float in group1 and unit in group2)
|
|
212
|
+
let regexp = %re("/^(\d+(?:\.\d*)?)\s*(\D*)$/")
|
|
251
213
|
|
|
252
|
-
|
|
253
|
-
|
|
214
|
+
// regexpCaptures: [match , captureGroup1, captureGroup2]
|
|
215
|
+
let regexpCaptures =
|
|
216
|
+
Js.Re.exec_(regexp, string)->Belt.Option.map(r =>
|
|
217
|
+
r->Js.Re.captures->Array.map(Js.Nullable.toOption)
|
|
218
|
+
)
|
|
254
219
|
|
|
255
|
-
let
|
|
220
|
+
let jsonString = string->Js.Json.string
|
|
256
221
|
|
|
257
|
-
|
|
258
|
-
type t = @decco.codec(codec) Toolkit__Utils_UnitMeasure.Weight.t
|
|
259
|
-
}
|
|
222
|
+
let errorPrefix = Config.errorPrefix
|
|
260
223
|
|
|
261
|
-
|
|
262
|
-
|
|
224
|
+
switch regexpCaptures {
|
|
225
|
+
| None => Decco.error(`${errorPrefix} unhandled format`, jsonString)
|
|
226
|
+
| Some([None, _value, _unit]) => Decco.error(`${errorPrefix} unhandled format`, jsonString)
|
|
227
|
+
| Some([_match, _value, None]) => Decco.error(`${errorPrefix} unhandled no unit`, jsonString)
|
|
228
|
+
| Some([_match, None, _unit]) => Decco.error(`${errorPrefix} unhandled no value`, jsonString)
|
|
229
|
+
| Some([Some(_match), Some(value), Some(unit)]) => {
|
|
230
|
+
let value = value->Js.Float.fromString
|
|
231
|
+
switch unit->Js.Json.string->Config.unitEnum_decode {
|
|
232
|
+
| Ok(unit) => Config.wrapValue(unit, value)->Ok
|
|
233
|
+
| Error(_) => Decco.error(`${errorPrefix} unhandled unit '${unit}'`, jsonString)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
| Some(_) => Decco.error(`${errorPrefix} regex capture group error`, jsonString)
|
|
237
|
+
}
|
|
263
238
|
}
|
|
264
239
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
let decoder: Decco.decoder<Toolkit__Utils_UnitMeasure.Weight.t> = json =>
|
|
272
|
-
switch Decco.floatFromJson(json) {
|
|
273
|
-
| Ok(v) => v->C.convert->Ok
|
|
240
|
+
%%private(
|
|
241
|
+
let encoder: Decco.encoder<Config.t> = value => value->Config.toString->Decco.stringToJson
|
|
242
|
+
let decoder: Decco.decoder<Config.t> = json =>
|
|
243
|
+
switch Decco.stringFromJson(json) {
|
|
244
|
+
| Ok(v) => v->decodeFromString
|
|
274
245
|
| Error(_) as err => err
|
|
275
246
|
}
|
|
247
|
+
let codec: Decco.codec<Config.t> = (encoder, decoder)
|
|
248
|
+
)
|
|
276
249
|
|
|
277
|
-
|
|
250
|
+
let toValue = Config.toValue
|
|
251
|
+
let toString = Config.toString
|
|
252
|
+
let display = Config.display
|
|
278
253
|
|
|
279
|
-
|
|
280
|
-
|
|
254
|
+
@decco
|
|
255
|
+
type t = @decco.codec(codec) Config.t
|
|
256
|
+
}
|
|
281
257
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
258
|
+
module Dimension = {
|
|
259
|
+
module Config = Toolkit__Utils_UnitMeasure.Dimension
|
|
285
260
|
|
|
286
|
-
module
|
|
287
|
-
|
|
261
|
+
module WithUnit = MakeWithUnit({
|
|
262
|
+
include Config
|
|
263
|
+
let errorPrefix = "Dimension with unit"
|
|
288
264
|
})
|
|
289
|
-
|
|
290
|
-
|
|
265
|
+
|
|
266
|
+
module Mm = Make({
|
|
267
|
+
include Config
|
|
268
|
+
let wrapValue = Config.wrapValue(#mm)
|
|
269
|
+
})
|
|
270
|
+
module Cm = Make({
|
|
271
|
+
include Config
|
|
272
|
+
let wrapValue = Config.wrapValue(#cm)
|
|
273
|
+
})
|
|
274
|
+
module Dm = Make({
|
|
275
|
+
include Config
|
|
276
|
+
let wrapValue = Config.wrapValue(#dm)
|
|
277
|
+
})
|
|
278
|
+
module M = Make({
|
|
279
|
+
include Config
|
|
280
|
+
let wrapValue = Config.wrapValue(#m)
|
|
281
|
+
})
|
|
282
|
+
module Km = Make({
|
|
283
|
+
include Config
|
|
284
|
+
let wrapValue = Config.wrapValue(#km)
|
|
291
285
|
})
|
|
292
286
|
}
|
|
293
287
|
|
|
294
|
-
module
|
|
295
|
-
module
|
|
296
|
-
let encoder: Decco.encoder<Toolkit__Utils_UnitMeasure.Time.t> = value =>
|
|
297
|
-
switch value {
|
|
298
|
-
| #min(v) => Js.Json.string(v->Js.Float.toString ++ " min")
|
|
299
|
-
| #h(v) => Js.Json.string(v->Js.Float.toString ++ " h")
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
let decoder: Decco.decoder<Toolkit__Utils_UnitMeasure.Time.t> = json =>
|
|
303
|
-
switch Decco.stringFromJson(json) {
|
|
304
|
-
| Ok(v) =>
|
|
305
|
-
let valueUnitArray = v->Js.String2.split(" ")
|
|
306
|
-
switch (
|
|
307
|
-
valueUnitArray[0]->Belt.Option.flatMap(Belt.Float.fromString),
|
|
308
|
-
valueUnitArray[1],
|
|
309
|
-
) {
|
|
310
|
-
| (Some(v), Some("min")) => #min(v)->Ok
|
|
311
|
-
| (Some(v), Some("h")) => #h(v)->Ok
|
|
312
|
-
| (None, _) => Decco.error("unhandled no value", json)
|
|
313
|
-
| (_, None) => Decco.error("unhandled no unit", json)
|
|
314
|
-
| (_, Some(_)) => Decco.error("unhandled time unit", json)
|
|
315
|
-
}
|
|
288
|
+
module Volume = {
|
|
289
|
+
module Config = Toolkit__Utils_UnitMeasure.Volume
|
|
316
290
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
@decco
|
|
323
|
-
type t = @decco.codec(codec) Toolkit__Utils_UnitMeasure.Time.t
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
module type TimeConfig = {
|
|
327
|
-
let convert: float => Toolkit__Utils_UnitMeasure.Time.t
|
|
328
|
-
}
|
|
291
|
+
module WithUnit = MakeWithUnit({
|
|
292
|
+
include Config
|
|
293
|
+
let errorPrefix = "Volume with unit"
|
|
294
|
+
})
|
|
329
295
|
|
|
330
|
-
module
|
|
331
|
-
|
|
296
|
+
module M3 = Make({
|
|
297
|
+
include Config
|
|
298
|
+
let wrapValue = Config.wrapValue(#m3)
|
|
299
|
+
})
|
|
300
|
+
}
|
|
332
301
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
| #min(v) => Js.Json.string(v->Js.Float.toString ++ " min")
|
|
336
|
-
| #h(v) => Js.Json.string(v->Js.Float.toString ++ " h")
|
|
337
|
-
}
|
|
302
|
+
module Weight = {
|
|
303
|
+
module Config = Toolkit__Utils_UnitMeasure.Weight
|
|
338
304
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
305
|
+
module WithUnit = MakeWithUnit({
|
|
306
|
+
include Config
|
|
307
|
+
let errorPrefix = "Weight with unit"
|
|
308
|
+
})
|
|
344
309
|
|
|
345
|
-
|
|
310
|
+
module G = Make({
|
|
311
|
+
include Config
|
|
312
|
+
let wrapValue = Config.wrapValue(#g)
|
|
313
|
+
})
|
|
314
|
+
module Kg = Make({
|
|
315
|
+
include Config
|
|
316
|
+
let wrapValue = Config.wrapValue(#kg)
|
|
317
|
+
})
|
|
318
|
+
}
|
|
346
319
|
|
|
347
|
-
|
|
348
|
-
|
|
320
|
+
module Time = {
|
|
321
|
+
module Config = Toolkit__Utils_UnitMeasure.Time
|
|
349
322
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
323
|
+
module WithUnit = MakeWithUnit({
|
|
324
|
+
include Config
|
|
325
|
+
let errorPrefix = "Time with unit"
|
|
326
|
+
})
|
|
353
327
|
|
|
354
328
|
module Min = Make({
|
|
355
|
-
|
|
329
|
+
include Config
|
|
330
|
+
let wrapValue = Config.wrapValue(#min)
|
|
356
331
|
})
|
|
357
332
|
module H = Make({
|
|
358
|
-
|
|
333
|
+
include Config
|
|
334
|
+
let wrapValue = Config.wrapValue(#h)
|
|
359
335
|
})
|
|
360
336
|
}
|
|
361
337
|
|
|
362
338
|
module Currency = {
|
|
363
|
-
module
|
|
364
|
-
let encoder: Decco.encoder<Toolkit__Utils_UnitMeasure.Currency.t> = value =>
|
|
365
|
-
switch value {
|
|
366
|
-
| #EUR(v) => Js.Json.string(v->Js.Float.toString ++ " EUR")
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
let decoder: Decco.decoder<Toolkit__Utils_UnitMeasure.Currency.t> = json =>
|
|
370
|
-
switch Decco.stringFromJson(json) {
|
|
371
|
-
| Ok(v) =>
|
|
372
|
-
let valueUnitArray = v->Js.String2.split(" ")
|
|
373
|
-
switch (
|
|
374
|
-
valueUnitArray[0]->Belt.Option.flatMap(Belt.Float.fromString),
|
|
375
|
-
valueUnitArray[1],
|
|
376
|
-
) {
|
|
377
|
-
| (Some(v), Some("EUR")) => #EUR(v)->Ok
|
|
378
|
-
| (None, _) => Decco.error("unhandled no value", json)
|
|
379
|
-
| (_, None) => Decco.error("unhandled no unit", json)
|
|
380
|
-
| (_, Some(_)) => Decco.error("unhandled currency unit", json)
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
| Error(_) as err => err
|
|
384
|
-
}
|
|
339
|
+
module Config = Toolkit__Utils_UnitMeasure.Currency
|
|
385
340
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
module type CurrencyConfig = {
|
|
393
|
-
let convert: float => Toolkit__Utils_UnitMeasure.Currency.t
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
module Make = (C: CurrencyConfig) => {
|
|
397
|
-
type currency = Toolkit__Utils_UnitMeasure.Currency.t
|
|
398
|
-
|
|
399
|
-
let encoder: Decco.encoder<Toolkit__Utils_UnitMeasure.Currency.t> = value =>
|
|
400
|
-
switch value {
|
|
401
|
-
| #EUR(v) => Js.Json.string(v->Js.Float.toString ++ " EUR")
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
let decoder: Decco.decoder<Toolkit__Utils_UnitMeasure.Currency.t> = json =>
|
|
405
|
-
switch Decco.floatFromJson(json) {
|
|
406
|
-
| Ok(v) => v->C.convert->Ok
|
|
407
|
-
| Error(_) as err => err
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
let codec: Decco.codec<currency> = (encoder, decoder)
|
|
411
|
-
|
|
412
|
-
let toValue = Toolkit__Utils_UnitMeasure.Currency.toValue
|
|
413
|
-
let display = Toolkit__Utils_UnitMeasure.Currency.toString
|
|
414
|
-
|
|
415
|
-
@decco
|
|
416
|
-
type t = @decco.codec(codec) Toolkit__Utils_UnitMeasure.Currency.t
|
|
417
|
-
}
|
|
341
|
+
module WithUnit = MakeWithUnit({
|
|
342
|
+
include Config
|
|
343
|
+
let errorPrefix = "Curency with unit"
|
|
344
|
+
})
|
|
418
345
|
|
|
419
346
|
module EUR = Make({
|
|
420
|
-
|
|
347
|
+
include Config
|
|
348
|
+
let wrapValue = Config.wrapValue(#EUR)
|
|
421
349
|
})
|
|
422
350
|
}
|
|
423
351
|
|
|
424
352
|
module CompositeUnits = {
|
|
425
353
|
module CurrencyPerDistance = {
|
|
426
|
-
module
|
|
427
|
-
let encoder: Decco.encoder<
|
|
428
|
-
Toolkit__Utils_UnitMeasure.CompositeUnits.CurrencyPerDistance.t,
|
|
429
|
-
> = value =>
|
|
430
|
-
switch value {
|
|
431
|
-
| #EUR_km(v) => Js.Json.string(v->Js.Float.toString ++ " EUR/km")
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
let decoder: Decco.decoder<
|
|
435
|
-
Toolkit__Utils_UnitMeasure.CompositeUnits.CurrencyPerDistance.t,
|
|
436
|
-
> = json =>
|
|
437
|
-
switch Decco.stringFromJson(json) {
|
|
438
|
-
| Ok(v) =>
|
|
439
|
-
let valueUnitArray = v->Js.String2.split(" ")
|
|
440
|
-
switch (
|
|
441
|
-
valueUnitArray[0]->Belt.Option.flatMap(Belt.Float.fromString),
|
|
442
|
-
valueUnitArray[1],
|
|
443
|
-
) {
|
|
444
|
-
| (Some(v), Some("EUR/km")) => #EUR_km(v)->Ok
|
|
445
|
-
| (None, _) => Decco.error("unhandled no value", json)
|
|
446
|
-
| (_, None) => Decco.error("unhandled no unit", json)
|
|
447
|
-
| (_, Some(_)) => Decco.error("unhandled currencyPerDistance unit", json)
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
| Error(_) as err => err
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
let codec: Decco.codec<Toolkit__Utils_UnitMeasure.CompositeUnits.CurrencyPerDistance.t> = (
|
|
454
|
-
encoder,
|
|
455
|
-
decoder,
|
|
456
|
-
)
|
|
354
|
+
module Config = Toolkit__Utils_UnitMeasure.CompositeUnits.CurrencyPerDistance
|
|
457
355
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
module type CurrencyPerDistanceConfig = {
|
|
463
|
-
let convert: float => Toolkit__Utils_UnitMeasure.CompositeUnits.CurrencyPerDistance.t
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
module Make = (C: CurrencyPerDistanceConfig) => {
|
|
467
|
-
type currencyPerDistance = Toolkit__Utils_UnitMeasure.CompositeUnits.CurrencyPerDistance.t
|
|
468
|
-
|
|
469
|
-
let encoder: Decco.encoder<
|
|
470
|
-
Toolkit__Utils_UnitMeasure.CompositeUnits.CurrencyPerDistance.t,
|
|
471
|
-
> = value =>
|
|
472
|
-
switch value {
|
|
473
|
-
| #EUR_km(v) => Js.Json.string(v->Js.Float.toString ++ " EUR/km")
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
let decoder: Decco.decoder<
|
|
477
|
-
Toolkit__Utils_UnitMeasure.CompositeUnits.CurrencyPerDistance.t,
|
|
478
|
-
> = json =>
|
|
479
|
-
switch Decco.floatFromJson(json) {
|
|
480
|
-
| Ok(v) => v->C.convert->Ok
|
|
481
|
-
| Error(_) as err => err
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
let codec: Decco.codec<currencyPerDistance> = (encoder, decoder)
|
|
356
|
+
module WithUnit = MakeWithUnit({
|
|
357
|
+
include Config
|
|
358
|
+
let errorPrefix = "Curency per distance with unit"
|
|
359
|
+
})
|
|
485
360
|
|
|
486
|
-
|
|
487
|
-
|
|
361
|
+
module EUR_km = Make({
|
|
362
|
+
include Config
|
|
363
|
+
let wrapValue = Config.wrapValue(#EUR_km)
|
|
364
|
+
})
|
|
365
|
+
}
|
|
366
|
+
module CurrencyPerTime = {
|
|
367
|
+
module Config = Toolkit__Utils_UnitMeasure.CompositeUnits.CurrencyPerTime
|
|
488
368
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
369
|
+
module WithUnit = MakeWithUnit({
|
|
370
|
+
include Config
|
|
371
|
+
let errorPrefix = "Curency per time with unit"
|
|
372
|
+
})
|
|
492
373
|
|
|
493
|
-
module
|
|
494
|
-
|
|
374
|
+
module EUR_h = Make({
|
|
375
|
+
include Config
|
|
376
|
+
let wrapValue = Config.wrapValue(#EUR_h)
|
|
495
377
|
})
|
|
496
378
|
}
|
|
497
379
|
}
|
|
@@ -1,6 +1,49 @@
|
|
|
1
|
+
module type UnitConfig = {
|
|
2
|
+
type unitEnum
|
|
3
|
+
let unitEnumToJs: unitEnum => string
|
|
4
|
+
let unitEnumFromJs: string => option<unitEnum>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
module Unit = (Config: UnitConfig) => {
|
|
8
|
+
%%private(
|
|
9
|
+
let encoder = value => value->Config.unitEnumToJs->Decco.stringToJson
|
|
10
|
+
|
|
11
|
+
let decoder = json =>
|
|
12
|
+
switch Decco.stringFromJson(json) {
|
|
13
|
+
| Ok(value) =>
|
|
14
|
+
switch Config.unitEnumFromJs(value) {
|
|
15
|
+
| None => Decco.error(~path="", "Invalid unitEnum " ++ value, json)
|
|
16
|
+
| Some(value) => Ok(value)
|
|
17
|
+
}
|
|
18
|
+
| Error(_) as error => error
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let codec = (encoder, decoder)
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
@decco
|
|
25
|
+
type unitEnum = @decco.codec(codec) Config.unitEnum
|
|
26
|
+
|
|
27
|
+
let unitEnumToString = v => v->Config.unitEnumToJs
|
|
28
|
+
let unitEnumFromString = v => v->Config.unitEnumFromJs
|
|
29
|
+
}
|
|
30
|
+
|
|
1
31
|
module Weight = {
|
|
32
|
+
include Unit({
|
|
33
|
+
@deriving(jsConverter)
|
|
34
|
+
type unitEnum = [#g | #kg]
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
@decco
|
|
2
38
|
type t = [#g(float) | #kg(float)]
|
|
3
39
|
|
|
40
|
+
let wrapValue = (unit, value) => {
|
|
41
|
+
switch unit {
|
|
42
|
+
| #g => #g(value)
|
|
43
|
+
| #kg => #kg(value)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
4
47
|
let toValue = value =>
|
|
5
48
|
switch value {
|
|
6
49
|
| #g(v)
|
|
@@ -12,23 +55,40 @@ module Weight = {
|
|
|
12
55
|
| #g(v) => v->Js.Float.toFixedWithPrecision(~digits) ++ " g"
|
|
13
56
|
| #kg(v) => v->Js.Float.toFixedWithPrecision(~digits) ++ " kg"
|
|
14
57
|
}
|
|
58
|
+
let toString = value =>
|
|
59
|
+
switch value {
|
|
60
|
+
| #g(v) => v->Float.toString ++ " g"
|
|
61
|
+
| #kg(v) => v->Float.toString ++ " kg"
|
|
62
|
+
}
|
|
15
63
|
|
|
16
64
|
let makeG = (value: float) => #g(value)
|
|
17
65
|
let makeKg = (value: float) => #kg(value)
|
|
18
66
|
}
|
|
19
67
|
|
|
20
68
|
module Time = {
|
|
69
|
+
include Unit({
|
|
70
|
+
@deriving(jsConverter)
|
|
71
|
+
type unitEnum = [#min | #h]
|
|
72
|
+
})
|
|
73
|
+
|
|
21
74
|
type t = [#min(float) | #h(float)]
|
|
22
75
|
|
|
76
|
+
let wrapValue = (unit, value) => {
|
|
77
|
+
switch unit {
|
|
78
|
+
| #min => #min(value)
|
|
79
|
+
| #h => #h(value)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
23
83
|
let toValue = value =>
|
|
24
84
|
switch value {
|
|
25
85
|
| #min(v)
|
|
26
86
|
| #h(v) => v
|
|
27
87
|
}
|
|
28
88
|
|
|
29
|
-
|
|
30
|
-
let display = (value, ~separator=#units, ()) => {
|
|
89
|
+
let display = (value, ~digits as _=2, ()) => {
|
|
31
90
|
let _initialDate = Js.Date.make()
|
|
91
|
+
|
|
32
92
|
let duration = switch value {
|
|
33
93
|
| #min(v) =>
|
|
34
94
|
BsDateFns.intervalToDuration(
|
|
@@ -43,32 +103,35 @@ module Time = {
|
|
|
43
103
|
)
|
|
44
104
|
}
|
|
45
105
|
|
|
46
|
-
let mainSeparator = {
|
|
47
|
-
switch separator {
|
|
48
|
-
| #units => " h "
|
|
49
|
-
| #colon => ":"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
let secondarySeparator = {
|
|
53
|
-
switch separator {
|
|
54
|
-
| #units => " min"
|
|
55
|
-
| #colon => ""
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
106
|
switch (duration.hours, duration.minutes) {
|
|
60
|
-
| (Some(h), Some(min)) =>
|
|
61
|
-
`${h->Int.toString}${
|
|
107
|
+
| (Some(h), Some(min)) if min->Int.toString->String.length === 1 =>
|
|
108
|
+
`${h->Int.toString} : 0${min->Int.toString}`
|
|
109
|
+
| (Some(h), Some(min)) => `${h->Int.toString} : ${min->Int.toString}`
|
|
62
110
|
| (Some(h), _) => `${h->Int.toString} h`
|
|
63
111
|
| (_, Some(min)) => `${min->Int.toString} min`
|
|
64
112
|
| _ => ""
|
|
65
113
|
}
|
|
66
114
|
}
|
|
67
|
-
|
|
68
|
-
let
|
|
115
|
+
|
|
116
|
+
let toString = value =>
|
|
117
|
+
switch value {
|
|
118
|
+
| #min(v) => v->Float.toString ++ " min"
|
|
119
|
+
| #h(v) => v->Float.toString ++ " h"
|
|
120
|
+
}
|
|
69
121
|
}
|
|
70
122
|
|
|
71
123
|
module Dimension = {
|
|
124
|
+
include Unit({
|
|
125
|
+
@deriving(jsConverter)
|
|
126
|
+
type unitEnum = [
|
|
127
|
+
| #mm
|
|
128
|
+
| #cm
|
|
129
|
+
| #dm
|
|
130
|
+
| #m
|
|
131
|
+
| #km
|
|
132
|
+
]
|
|
133
|
+
})
|
|
134
|
+
|
|
72
135
|
type t = [
|
|
73
136
|
| #mm(float)
|
|
74
137
|
| #cm(float)
|
|
@@ -77,6 +140,15 @@ module Dimension = {
|
|
|
77
140
|
| #km(float)
|
|
78
141
|
]
|
|
79
142
|
|
|
143
|
+
let wrapValue = (unit: unitEnum, value: float): t =>
|
|
144
|
+
switch unit {
|
|
145
|
+
| #mm => #mm(value)
|
|
146
|
+
| #cm => #cm(value)
|
|
147
|
+
| #dm => #dm(value)
|
|
148
|
+
| #m => #m(value)
|
|
149
|
+
| #km => #km(value)
|
|
150
|
+
}
|
|
151
|
+
|
|
80
152
|
let toValue = value =>
|
|
81
153
|
switch value {
|
|
82
154
|
| #mm(v)
|
|
@@ -86,7 +158,7 @@ module Dimension = {
|
|
|
86
158
|
| #km(v) => v
|
|
87
159
|
}
|
|
88
160
|
|
|
89
|
-
let
|
|
161
|
+
let display = (value, ~digits=2, ()) => {
|
|
90
162
|
open Js.Float
|
|
91
163
|
switch value {
|
|
92
164
|
| #mm(v) => v->toFixedWithPrecision(~digits) ++ " mm"
|
|
@@ -97,18 +169,70 @@ module Dimension = {
|
|
|
97
169
|
}
|
|
98
170
|
}
|
|
99
171
|
|
|
100
|
-
let
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
172
|
+
let toString = value => {
|
|
173
|
+
switch value {
|
|
174
|
+
| #mm(v) => v->Float.toString ++ " mm"
|
|
175
|
+
| #cm(v) => v->Float.toString ++ " cm"
|
|
176
|
+
| #dm(v) => v->Float.toString ++ " dm"
|
|
177
|
+
| #m(v) => v->Float.toString ++ " m"
|
|
178
|
+
| #km(v) => v->Float.toString ++ " km"
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
module Volume = {
|
|
184
|
+
include Unit({
|
|
185
|
+
@deriving(jsConverter)
|
|
186
|
+
type unitEnum = [
|
|
187
|
+
| @as(`m³`) #m3
|
|
188
|
+
]
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
type t = [
|
|
192
|
+
| #m3(float)
|
|
193
|
+
]
|
|
194
|
+
|
|
195
|
+
let wrapValue = (unit: unitEnum, value: float): t =>
|
|
196
|
+
switch unit {
|
|
197
|
+
| #m3 => #m3(value)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
let toValue = value =>
|
|
201
|
+
switch value {
|
|
202
|
+
| #m3(value) => value
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
let display = (value, ~digits=2, ()) => {
|
|
206
|
+
open Js.Float
|
|
207
|
+
switch value {
|
|
208
|
+
| #m3(v) => v->toFixedWithPrecision(~digits) ++ ` m³`
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
let toString = value => {
|
|
213
|
+
switch value {
|
|
214
|
+
| #m3(v) => v->Float.toString ++ ` m³`
|
|
215
|
+
}
|
|
216
|
+
}
|
|
105
217
|
}
|
|
106
218
|
|
|
107
219
|
module Currency = {
|
|
220
|
+
include Unit({
|
|
221
|
+
@deriving(jsConverter)
|
|
222
|
+
type unitEnum = [
|
|
223
|
+
| #EUR
|
|
224
|
+
]
|
|
225
|
+
})
|
|
226
|
+
|
|
108
227
|
type t = [
|
|
109
228
|
| #EUR(float)
|
|
110
229
|
]
|
|
111
230
|
|
|
231
|
+
let wrapValue = (unit: unitEnum, value: float): t =>
|
|
232
|
+
switch unit {
|
|
233
|
+
| #EUR => #EUR(value)
|
|
234
|
+
}
|
|
235
|
+
|
|
112
236
|
let toValue = value =>
|
|
113
237
|
switch value {
|
|
114
238
|
| #EUR(v) => v
|
|
@@ -120,15 +244,31 @@ module Currency = {
|
|
|
120
244
|
}
|
|
121
245
|
}
|
|
122
246
|
|
|
123
|
-
let
|
|
247
|
+
let display = (value, ~digits=2, ()) => {
|
|
248
|
+
switch value {
|
|
249
|
+
| #EUR(v) => v->Js.Float.toFixedWithPrecision(~digits) ++ " EUR"
|
|
250
|
+
}
|
|
251
|
+
}
|
|
124
252
|
}
|
|
125
253
|
|
|
126
254
|
module CompositeUnits = {
|
|
127
255
|
module CurrencyPerDistance = {
|
|
256
|
+
include Unit({
|
|
257
|
+
@deriving(jsConverter)
|
|
258
|
+
type unitEnum = [
|
|
259
|
+
| @as("EUR/km") #EUR_km
|
|
260
|
+
]
|
|
261
|
+
})
|
|
262
|
+
|
|
128
263
|
type t = [
|
|
129
264
|
| #EUR_km(float)
|
|
130
265
|
]
|
|
131
266
|
|
|
267
|
+
let wrapValue = (unit: unitEnum, value: float): t =>
|
|
268
|
+
switch unit {
|
|
269
|
+
| #EUR_km => #EUR_km(value)
|
|
270
|
+
}
|
|
271
|
+
|
|
132
272
|
let toValue = value =>
|
|
133
273
|
switch value {
|
|
134
274
|
| #EUR_km(v) => v
|
|
@@ -140,6 +280,45 @@ module CompositeUnits = {
|
|
|
140
280
|
}
|
|
141
281
|
}
|
|
142
282
|
|
|
143
|
-
let
|
|
283
|
+
let display = (value, ~digits=2, ()) => {
|
|
284
|
+
switch value {
|
|
285
|
+
| #EUR_km(v) => v->Js.Float.toFixedWithPrecision(~digits) ++ " EUR/km"
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
module CurrencyPerTime = {
|
|
291
|
+
include Unit({
|
|
292
|
+
@deriving(jsConverter)
|
|
293
|
+
type unitEnum = [
|
|
294
|
+
| @as("EUR/h") #EUR_h
|
|
295
|
+
]
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
type t = [
|
|
299
|
+
| #EUR_h(float)
|
|
300
|
+
]
|
|
301
|
+
|
|
302
|
+
let wrapValue = (unit: unitEnum, value: float): t =>
|
|
303
|
+
switch unit {
|
|
304
|
+
| #EUR_h => #EUR_h(value)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
let toValue = value =>
|
|
308
|
+
switch value {
|
|
309
|
+
| #EUR_h(v) => v
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
let toString = value => {
|
|
313
|
+
switch value {
|
|
314
|
+
| #EUR_h(v) => v->Float.toString ++ " EUR/h"
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
let display = (value, ~digits=2, ()) => {
|
|
319
|
+
switch value {
|
|
320
|
+
| #EUR_h(v) => v->Js.Float.toFixedWithPrecision(~digits) ++ " EUR/h"
|
|
321
|
+
}
|
|
322
|
+
}
|
|
144
323
|
}
|
|
145
324
|
}
|
|
@@ -130,6 +130,8 @@ external getWeekNumber: (Js.Date.t, startOfWeekOptions) => int = "getWeek"
|
|
|
130
130
|
|
|
131
131
|
@module("date-fns")
|
|
132
132
|
external getDay: Js.Date.t => int = "getDay"
|
|
133
|
+
@module("date-fns")
|
|
134
|
+
external getHours: Js.Date.t => int = "getHours"
|
|
133
135
|
|
|
134
136
|
@module("date-fns")
|
|
135
137
|
external parse: string => Js.Date.t = "parse"
|
|
@@ -146,3 +148,18 @@ external nextFriday: Js.Date.t => Js.Date.t = "nextFriday"
|
|
|
146
148
|
external nextSaturday: Js.Date.t => Js.Date.t = "nextSaturday"
|
|
147
149
|
@module("date-fns")
|
|
148
150
|
external nextSunday: Js.Date.t => Js.Date.t = "nextSunday"
|
|
151
|
+
|
|
152
|
+
@module("date-fns")
|
|
153
|
+
external isMonday: Js.Date.t => bool = "isMonday"
|
|
154
|
+
@module("date-fns")
|
|
155
|
+
external isTuesday: Js.Date.t => bool = "isTuesday"
|
|
156
|
+
@module("date-fns")
|
|
157
|
+
external isWednesday: Js.Date.t => bool = "isWednesday"
|
|
158
|
+
@module("date-fns")
|
|
159
|
+
external isThursday: Js.Date.t => bool = "isThursday"
|
|
160
|
+
@module("date-fns")
|
|
161
|
+
external isFriday: Js.Date.t => bool = "isFriday"
|
|
162
|
+
@module("date-fns")
|
|
163
|
+
external isSaturday: Js.Date.t => bool = "isSaturday"
|
|
164
|
+
@module("date-fns")
|
|
165
|
+
external isSunday: Js.Date.t => bool = "isSunday"
|
|
@@ -2,7 +2,7 @@ type event<'a> = {
|
|
|
2
2
|
title: string,
|
|
3
3
|
start: Js.Date.t,
|
|
4
4
|
end: Js.Date.t,
|
|
5
|
-
resource:
|
|
5
|
+
resource: 'a,
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
type view = [
|
|
@@ -14,7 +14,7 @@ type view = [
|
|
|
14
14
|
]
|
|
15
15
|
|
|
16
16
|
type eventProp<'a> = {
|
|
17
|
-
resource:
|
|
17
|
+
resource: 'a,
|
|
18
18
|
start: Js.Date.t,
|
|
19
19
|
end: Js.Date.t,
|
|
20
20
|
isSelected: bool,
|
|
@@ -30,6 +30,11 @@ external makeEventClassStyle: (
|
|
|
30
30
|
unit,
|
|
31
31
|
) => eventClassStyle = ""
|
|
32
32
|
|
|
33
|
+
type timeSlot = {
|
|
34
|
+
start: Js.Date.t,
|
|
35
|
+
end: Js.Date.t,
|
|
36
|
+
}
|
|
37
|
+
|
|
33
38
|
@module("react-big-calendar") @react.component
|
|
34
39
|
external make: (
|
|
35
40
|
~localizer: 'a,
|
|
@@ -37,17 +42,20 @@ external make: (
|
|
|
37
42
|
~defaultView: view=?,
|
|
38
43
|
~views: array<view>=?,
|
|
39
44
|
~culture: string=?,
|
|
45
|
+
~toolbar: bool=?,
|
|
46
|
+
~selectable: bool=?,
|
|
40
47
|
~timeslots: int=?,
|
|
41
48
|
~min: Js.Date.t=?,
|
|
42
49
|
~max: Js.Date.t=?,
|
|
43
50
|
~step: int=?,
|
|
44
51
|
~components: 'z=?,
|
|
45
|
-
~eventPropGetter: eventProp<'b> => eventClassStyle
|
|
52
|
+
~eventPropGetter: eventProp<'b> => eventClassStyle=?,
|
|
46
53
|
~messages: Js.t<'message>=?,
|
|
47
54
|
~formats: Js.t<'formats>=?,
|
|
48
55
|
~onSelectEvent: event<'b> => unit=?,
|
|
49
56
|
~onView: view => unit=?,
|
|
50
57
|
~onNavigate: Js.Date.t => unit=?,
|
|
58
|
+
~onSelectSlot: timeSlot => unit=?,
|
|
51
59
|
) => React.element = "Calendar"
|
|
52
60
|
|
|
53
61
|
type calendarLocalizer
|