@colisweb/rescript-toolkit 2.31.1 → 2.33.1
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/bsconfig.json
CHANGED
|
@@ -34,7 +34,11 @@
|
|
|
34
34
|
"rescript-react-update",
|
|
35
35
|
"restorative"
|
|
36
36
|
],
|
|
37
|
-
"ppx-flags": [
|
|
37
|
+
"ppx-flags": [
|
|
38
|
+
"decco/ppx",
|
|
39
|
+
"lenses-ppx/ppx",
|
|
40
|
+
"res-react-intl/ppx"
|
|
41
|
+
],
|
|
38
42
|
"refmt": 3,
|
|
39
43
|
"warnings": {
|
|
40
44
|
"number": "-44-30-32",
|
|
@@ -46,4 +50,4 @@
|
|
|
46
50
|
"-open Belt",
|
|
47
51
|
"-open Cx"
|
|
48
52
|
]
|
|
49
|
-
}
|
|
53
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colisweb/rescript-toolkit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.33.1",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"clean": "rescript clean",
|
|
6
6
|
"build": "rescript build",
|
|
@@ -87,6 +87,7 @@
|
|
|
87
87
|
"react": "17.0.2",
|
|
88
88
|
"react-dom": "17.0.2",
|
|
89
89
|
"react-intl": "5.24.7",
|
|
90
|
+
"res-react-intl": "3.1.2",
|
|
90
91
|
"react-is": "17.0.2",
|
|
91
92
|
"sass": "1.45.0"
|
|
92
93
|
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
open ReactIntl
|
|
2
|
+
|
|
3
|
+
module Msg = {
|
|
4
|
+
@@intl.messages
|
|
5
|
+
let requiredValue = {defaultMessage: "required value"}
|
|
6
|
+
let requiredPosInt = {defaultMessage: "must be a positive integer"}
|
|
7
|
+
let requiredPosIntOrFloat = {defaultMessage: "must be a positive integer or float"}
|
|
8
|
+
let wrongFormat = {defaultMessage: "Wrong format (req: {exemple})"}
|
|
9
|
+
let maxNumberOfPackets = {defaultMessage: "Nb packets"}
|
|
10
|
+
let totalVolume = {defaultMessage: "Total volume"}
|
|
11
|
+
let binPacking = {defaultMessage: "Bin packing"}
|
|
12
|
+
let vehicleNameAlreadyUsed = {defaultMessage: "This name is already used in another flat rate"}
|
|
13
|
+
|
|
14
|
+
let requiredAlphanumericMax4 = {
|
|
15
|
+
defaultMessage: "required format : 4 characters or numbers (exemples: 'A1b2' 'abcd')",
|
|
16
|
+
}
|
|
17
|
+
let required14Digits = {
|
|
18
|
+
defaultMessage: "required format : 14 digits",
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let toReformResult = (opt: option<string>): Reform.fieldState =>
|
|
23
|
+
switch opt {
|
|
24
|
+
| Some(e) => Error(e)
|
|
25
|
+
| None => Valid
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let requiredStringNonEmpty = (intl, value) => {
|
|
29
|
+
switch value {
|
|
30
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
31
|
+
| _ => None
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let requiredPosInt = (intl, value) => {
|
|
36
|
+
switch value {
|
|
37
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
38
|
+
| value if !Toolkit.Utils.Regex.Test.isPositiveInt(value) =>
|
|
39
|
+
Some(Intl.formatMessage(intl, Msg.requiredPosInt))
|
|
40
|
+
| _ => None
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let optionalPosInt = (intl, value) => {
|
|
45
|
+
switch value {
|
|
46
|
+
| "" => None
|
|
47
|
+
| value if !Toolkit.Utils.Regex.Test.isPositiveInt(value) =>
|
|
48
|
+
Some(Intl.formatMessage(intl, Msg.requiredPosInt))
|
|
49
|
+
| _ => None
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
let requiredPosFloat = (intl, value) => {
|
|
53
|
+
switch value {
|
|
54
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
55
|
+
| value if !Toolkit.Utils.Regex.Test.isPositiveIntOrFloat(value) =>
|
|
56
|
+
Some(Intl.formatMessage(intl, Msg.requiredPosIntOrFloat))
|
|
57
|
+
| _ => None
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let requiredFloat = (intl, value) => {
|
|
62
|
+
switch value->Js.String2.split("-") {
|
|
63
|
+
| _ if value === "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
64
|
+
| ["", value]
|
|
65
|
+
| [value] if Toolkit.Utils.Regex.Test.isPositiveIntOrFloat(value) =>
|
|
66
|
+
None
|
|
67
|
+
| _ => Some(Intl.formatMessage(intl, Msg.requiredPosIntOrFloat))
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let optionalFloat = (intl, value) => {
|
|
72
|
+
switch value->Js.String2.split("-") {
|
|
73
|
+
| _ if value === "" => None
|
|
74
|
+
| ["", value]
|
|
75
|
+
| [value] if Toolkit.Utils.Regex.Test.isPositiveIntOrFloat(value) =>
|
|
76
|
+
None
|
|
77
|
+
| _ => Some(Intl.formatMessage(intl, Msg.requiredPosIntOrFloat))
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let requiredPosFloatCurrencyEur = (intl, value) => {
|
|
82
|
+
switch value {
|
|
83
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
84
|
+
| v =>
|
|
85
|
+
switch v->Toolkit.Decoders.UnitMeasure.Currency.WithUnit.decodeFromString {
|
|
86
|
+
| Ok(#EUR(_)) => None
|
|
87
|
+
| _ =>
|
|
88
|
+
Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 EUR' '0.5 EUR'"}))
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let requiredPosFloatTimeHour = (intl, value) => {
|
|
94
|
+
switch value {
|
|
95
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
96
|
+
| v =>
|
|
97
|
+
switch v->Toolkit.Decoders.UnitMeasure.Time.WithUnit.decodeFromString {
|
|
98
|
+
| Ok(#h(_)) => None
|
|
99
|
+
| _ => Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 h' '0.5 h'"}))
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
let requiredPosFloatTimeMin = (intl, value) => {
|
|
105
|
+
switch value {
|
|
106
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
107
|
+
| v =>
|
|
108
|
+
switch v->Toolkit.Decoders.UnitMeasure.Time.WithUnit.decodeFromString {
|
|
109
|
+
| Ok(#min(_)) => None
|
|
110
|
+
| _ =>
|
|
111
|
+
Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 min' '0.5 min'"}))
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let requiredPosFloatTimeHour_Min = (intl, value) => {
|
|
117
|
+
switch value {
|
|
118
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
119
|
+
| v =>
|
|
120
|
+
switch v->Toolkit.Decoders.UnitMeasure.Time.WithUnit.decodeFromString {
|
|
121
|
+
| Ok(#h(_)) => None
|
|
122
|
+
| Ok(#min(_)) => None
|
|
123
|
+
| _ =>
|
|
124
|
+
Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 min' '0.5 h'"}))
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
let optionalPosFloatTimeMin = (intl, value) => {
|
|
130
|
+
switch value {
|
|
131
|
+
| "" => None
|
|
132
|
+
| v =>
|
|
133
|
+
switch v->Toolkit.Decoders.UnitMeasure.Time.WithUnit.decodeFromString {
|
|
134
|
+
| Ok(#min(_)) => None
|
|
135
|
+
| _ =>
|
|
136
|
+
Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 min' '0.5 min'"}))
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let requiredPosFloatPriceEurByHour = (intl, value) => {
|
|
142
|
+
switch value {
|
|
143
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
144
|
+
| v =>
|
|
145
|
+
switch v->Toolkit.Decoders.UnitMeasure.CompositeUnits.CurrencyPerTime.WithUnit.decodeFromString {
|
|
146
|
+
| Ok(#EUR_h(_)) => None
|
|
147
|
+
| _ =>
|
|
148
|
+
Some(
|
|
149
|
+
Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 EUR/h' '0.5 EUR/h'"}),
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
let requiredPosFloatPriceEurByKm = (intl, value) => {
|
|
155
|
+
switch value {
|
|
156
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
157
|
+
| v =>
|
|
158
|
+
switch v->Toolkit.Decoders.UnitMeasure.CompositeUnits.CurrencyPerDistance.WithUnit.decodeFromString {
|
|
159
|
+
| Ok(#EUR_km(_)) => None
|
|
160
|
+
| _ =>
|
|
161
|
+
Some(
|
|
162
|
+
Intl.formatMessageWithValues(
|
|
163
|
+
intl,
|
|
164
|
+
Msg.wrongFormat,
|
|
165
|
+
{"exemple": "'10 EUR/km' '0.5 EUR/km'"},
|
|
166
|
+
),
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
let requiredPosFloatDistanceKm = (intl, value) => {
|
|
173
|
+
switch value {
|
|
174
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
175
|
+
| v =>
|
|
176
|
+
switch v->Toolkit.Decoders.UnitMeasure.Dimension.WithUnit.decodeFromString {
|
|
177
|
+
| Ok(#km(_)) => None
|
|
178
|
+
| _ =>
|
|
179
|
+
Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 km' '0.5 km'"}))
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
let requiredPosFloatDistanceKm_M = (intl, value) => {
|
|
184
|
+
switch value {
|
|
185
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
186
|
+
| v =>
|
|
187
|
+
switch v->Toolkit.Decoders.UnitMeasure.Dimension.WithUnit.decodeFromString {
|
|
188
|
+
| Ok(#km(_)) => None
|
|
189
|
+
| Ok(#m(_)) => None
|
|
190
|
+
| _ => Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'15 m' '0.5 km'"}))
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
let optionalPosFloatDistanceKm = (intl, value) => {
|
|
196
|
+
switch value {
|
|
197
|
+
| "" => None
|
|
198
|
+
| v =>
|
|
199
|
+
switch v->Toolkit.Decoders.UnitMeasure.Dimension.WithUnit.decodeFromString {
|
|
200
|
+
| Ok(#km(_)) => None
|
|
201
|
+
| _ =>
|
|
202
|
+
Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 km' '0.5 km'"}))
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let requiredPosFloatVolumeM3 = (intl, value) => {
|
|
208
|
+
switch value {
|
|
209
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
210
|
+
| v =>
|
|
211
|
+
switch v->Toolkit.Decoders.UnitMeasure.Volume.WithUnit.decodeFromString {
|
|
212
|
+
| Ok(#m3(_)) => None
|
|
213
|
+
| _ =>
|
|
214
|
+
Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": `'10 m³' '0.5 m³'`}))
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
let requiredPosFloatDimensionCm = (intl, value) => {
|
|
220
|
+
switch value {
|
|
221
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
222
|
+
| v =>
|
|
223
|
+
switch v->Toolkit.Decoders.UnitMeasure.Dimension.WithUnit.decodeFromString {
|
|
224
|
+
| Ok(#cm(_)) => None
|
|
225
|
+
| _ =>
|
|
226
|
+
Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 cm' '0.5 cm'"}))
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
let requiredPosFloatDimensionCm_M = (intl, value) => {
|
|
231
|
+
switch value {
|
|
232
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
233
|
+
| v =>
|
|
234
|
+
switch v->Toolkit.Decoders.UnitMeasure.Dimension.WithUnit.decodeFromString {
|
|
235
|
+
| Ok(#cm(_)) => None
|
|
236
|
+
| Ok(#m(_)) => None
|
|
237
|
+
| _ => Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 cm' '0.5 m'"}))
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
let requiredPosFloatWeightKg = (intl, value) => {
|
|
243
|
+
switch value {
|
|
244
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
245
|
+
| v =>
|
|
246
|
+
switch v->Toolkit.Decoders.UnitMeasure.Weight.WithUnit.decodeFromString {
|
|
247
|
+
| Ok(#kg(_)) => None
|
|
248
|
+
| _ =>
|
|
249
|
+
Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 kg' '0.5 kg'"}))
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
let optionalPosFloatWeightKg = (intl, value) => {
|
|
254
|
+
switch value {
|
|
255
|
+
| "" => None
|
|
256
|
+
| v =>
|
|
257
|
+
switch v->Toolkit.Decoders.UnitMeasure.Weight.WithUnit.decodeFromString {
|
|
258
|
+
| Ok(#kg(_)) => None
|
|
259
|
+
| _ =>
|
|
260
|
+
Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 kg' '0.5 kg'"}))
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
let requiredPosFloatWeightG = (intl, value) => {
|
|
265
|
+
switch value {
|
|
266
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
267
|
+
| v =>
|
|
268
|
+
switch v->Toolkit.Decoders.UnitMeasure.Weight.WithUnit.decodeFromString {
|
|
269
|
+
| Ok(#g(_)) => None
|
|
270
|
+
| _ =>
|
|
271
|
+
Some(Intl.formatMessageWithValues(intl, Msg.wrongFormat, {"exemple": "'10 kg' '0.5 kg'"}))
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
let requiredAlphanumericMax4 = (intl, value) => {
|
|
277
|
+
switch value {
|
|
278
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
279
|
+
| v =>
|
|
280
|
+
switch Js.Re.test_(%re("/^[a-zA-Z0-9]{4}$/"), v) {
|
|
281
|
+
| true => None
|
|
282
|
+
| false => Some(Intl.formatMessage(intl, Msg.requiredAlphanumericMax4))
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
let required14Digits = (intl, value) => {
|
|
288
|
+
switch value {
|
|
289
|
+
| "" => Some(Intl.formatMessage(intl, Msg.requiredValue))
|
|
290
|
+
| v =>
|
|
291
|
+
switch Js.Re.test_(%re("/^[0-9]{14}$/"), v) {
|
|
292
|
+
| true => None
|
|
293
|
+
| false => Some(Intl.formatMessage(intl, Msg.required14Digits))
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
@@ -52,6 +52,8 @@ module Array = {
|
|
|
52
52
|
let tail = array => array->Array.get(array->Array.length - 1)
|
|
53
53
|
let tailExn = array => array->Array.getExn(array->Array.length - 1)
|
|
54
54
|
let isLastIndex = (array, index) => array->Array.length - 1 == index
|
|
55
|
+
|
|
56
|
+
let flatten = array => array->Array.reduce([], (acc, value) => acc->Array.concat(value))
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
module Result = {
|
|
@@ -4,23 +4,36 @@ type status = [#success | #error | #warning | #info]
|
|
|
4
4
|
let make = (~title, ~description=?, ~status, ~className=?) =>
|
|
5
5
|
<div
|
|
6
6
|
className={cx([
|
|
7
|
-
"py-2 px-4 flex items-center",
|
|
7
|
+
"py-2 px-4 flex items-center border rounded",
|
|
8
8
|
switch status {
|
|
9
|
-
| #success => "bg-success-50"
|
|
10
|
-
| #error => "bg-danger-50"
|
|
11
|
-
| #warning => "bg-warning-50"
|
|
12
|
-
| #info => "bg-info-50"
|
|
9
|
+
| #success => "bg-success-50 border-success-500"
|
|
10
|
+
| #error => "bg-danger-50 border-danger-500"
|
|
11
|
+
| #warning => "bg-warning-50 border-warning-500"
|
|
12
|
+
| #info => "bg-info-50 border-info-500"
|
|
13
13
|
},
|
|
14
14
|
className->Option.getWithDefault(""),
|
|
15
15
|
])}>
|
|
16
16
|
{switch status {
|
|
17
|
-
| #success => <BsReactIcons.MdCheckCircle size=28 className="text-success-
|
|
17
|
+
| #success => <BsReactIcons.MdCheckCircle size=28 className="text-success-600 flex-shrink-0" />
|
|
18
18
|
| #error => <BsReactIcons.MdWarning size=28 className="text-danger-600 flex-shrink-0" />
|
|
19
|
-
| #warning => <BsReactIcons.MdWarning size=28 className="text-warning-
|
|
20
|
-
| #info => <BsReactIcons.
|
|
19
|
+
| #warning => <BsReactIcons.MdWarning size=28 className="text-warning-600 flex-shrink-0" />
|
|
20
|
+
| #info => <BsReactIcons.FaExclamationCircle size=28 className="text-info-600 flex-shrink-0" />
|
|
21
21
|
}}
|
|
22
22
|
<div className="mx-3">
|
|
23
|
-
<div
|
|
23
|
+
<div
|
|
24
|
+
className={cx([
|
|
25
|
+
description->Option.isSome ? "font-bold" : "",
|
|
26
|
+
{
|
|
27
|
+
switch status {
|
|
28
|
+
| #success => "text-success-600"
|
|
29
|
+
| #error => "text-danger-600"
|
|
30
|
+
| #warning => "text-warning-600"
|
|
31
|
+
| #info => "text-info-600"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
])}>
|
|
35
|
+
title
|
|
36
|
+
</div>
|
|
24
37
|
{description->Option.getWithDefault(React.null)}
|
|
25
38
|
</div>
|
|
26
39
|
</div>
|