@colisweb/rescript-toolkit 1.29.4 → 2.0.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 +4 -4
- package/src/decoders/Toolkit__Decoders.res +19 -1
- package/src/sentry/SentryReactNativeLogger.res +114 -0
- package/src/ui/Toolkit__Ui_Layout.res +28 -13
- package/src/ui/Toolkit__Ui_Snackbar.res +42 -34
- package/src/ui/Toolkit__Ui_Snackbar.resi +1 -1
- package/src/vendors/BsSentryReactNative.res +9 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colisweb/rescript-toolkit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"clean": "rescript clean",
|
|
6
6
|
"build": "rescript build",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@reach/visually-hidden": "0.16.0",
|
|
39
39
|
"@rescript/react": "0.10.3",
|
|
40
40
|
"autoprefixer": "10.3.6",
|
|
41
|
-
"axios": "0.
|
|
41
|
+
"axios": "0.24.0",
|
|
42
42
|
"bs-axios": "0.0.43",
|
|
43
43
|
"bs-css": "13.4.0",
|
|
44
44
|
"bs-css-emotion": "2.4.0",
|
|
@@ -71,10 +71,10 @@
|
|
|
71
71
|
"restorative": "0.4.0-beta.1",
|
|
72
72
|
"string.prototype.matchall": "4.0.5",
|
|
73
73
|
"swr": "1.0.1",
|
|
74
|
-
"tailwindcss": "2.2.
|
|
74
|
+
"tailwindcss": "2.2.19"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
|
-
"@babel/core": "7.
|
|
77
|
+
"@babel/core": "7.16.0",
|
|
78
78
|
"@storybook/addon-actions": "6.1.21",
|
|
79
79
|
"@storybook/addon-essentials": "6.1.21",
|
|
80
80
|
"@storybook/addon-knobs": "6.1.21",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module Datetime = {
|
|
2
2
|
type date = Js.Date.t
|
|
3
3
|
|
|
4
4
|
let encoder: Decco.encoder<date> = value => value->Js.Date.toISOString->Decco.stringToJson
|
|
@@ -15,6 +15,24 @@ module Date = {
|
|
|
15
15
|
type t = @decco.codec(codec) date
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
module Date = {
|
|
19
|
+
type date = Js.Date.t
|
|
20
|
+
|
|
21
|
+
let encoder: Decco.encoder<date> = date =>
|
|
22
|
+
date->BsDateFns.formatWithPattern("yyyy-MM-dd")->Decco.stringToJson
|
|
23
|
+
|
|
24
|
+
let decoder: Decco.decoder<date> = json =>
|
|
25
|
+
switch Decco.stringFromJson(json) {
|
|
26
|
+
| Ok(v) => Js.Date.fromString(v)->Ok
|
|
27
|
+
| Error(_) as err => err
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let codec: Decco.codec<date> = (encoder, decoder)
|
|
31
|
+
|
|
32
|
+
@decco
|
|
33
|
+
type t = @decco.codec(codec) date
|
|
34
|
+
}
|
|
35
|
+
|
|
18
36
|
module Int = {
|
|
19
37
|
let encoder = value => value->Decco.intToJson
|
|
20
38
|
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
open BsSentryReactNative
|
|
2
|
+
|
|
3
|
+
let error = (loc: ReScriptLogger.Location.t, event) => {
|
|
4
|
+
open Sentry
|
|
5
|
+
withScope(scope => {
|
|
6
|
+
scope->Scope.setExtra("module", loc.subModulePath->List.toArray)
|
|
7
|
+
scope->Scope.setExtra("fullPath", loc.fullPath)
|
|
8
|
+
scope->Scope.setExtra("function", loc.value)
|
|
9
|
+
captureMessage(event)
|
|
10
|
+
})
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let error1 = (loc: ReScriptLogger.Location.t, event, (label, data)) => {
|
|
14
|
+
open Sentry
|
|
15
|
+
withScope(scope => {
|
|
16
|
+
scope->Scope.setExtra("module", loc.subModulePath->List.toArray)
|
|
17
|
+
scope->Scope.setExtra("fullPath", loc.fullPath)
|
|
18
|
+
scope->Scope.setExtra("function", loc.value)
|
|
19
|
+
scope->Scope.setExtra(label, data)
|
|
20
|
+
captureMessage(event)
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let error2 = (loc: ReScriptLogger.Location.t, event, (label1, data1), (label2, data2)) => {
|
|
25
|
+
open Sentry
|
|
26
|
+
withScope(scope => {
|
|
27
|
+
scope->Scope.setExtra("module", loc.subModulePath->List.toArray)
|
|
28
|
+
scope->Scope.setExtra("fullPath", loc.fullPath)
|
|
29
|
+
scope->Scope.setExtra("function", loc.value)
|
|
30
|
+
scope->Scope.setExtra(label1, data1)
|
|
31
|
+
scope->Scope.setExtra(label2, data2)
|
|
32
|
+
captureMessage(event)
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let error3 = (
|
|
37
|
+
loc: ReScriptLogger.Location.t,
|
|
38
|
+
event,
|
|
39
|
+
(label1, data1),
|
|
40
|
+
(label2, data2),
|
|
41
|
+
(label3, data3),
|
|
42
|
+
) => {
|
|
43
|
+
open Sentry
|
|
44
|
+
withScope(scope => {
|
|
45
|
+
scope->Scope.setExtra("module", loc.subModulePath->List.toArray)
|
|
46
|
+
scope->Scope.setExtra("fullPath", loc.fullPath)
|
|
47
|
+
scope->Scope.setExtra("function", loc.value)
|
|
48
|
+
scope->Scope.setExtra(label1, data1)
|
|
49
|
+
scope->Scope.setExtra(label2, data2)
|
|
50
|
+
scope->Scope.setExtra(label3, data3)
|
|
51
|
+
captureMessage(event)
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
let error4 = (
|
|
55
|
+
loc: ReScriptLogger.Location.t,
|
|
56
|
+
event,
|
|
57
|
+
(label1, data1),
|
|
58
|
+
(label2, data2),
|
|
59
|
+
(label3, data3),
|
|
60
|
+
(label4, data4),
|
|
61
|
+
) => {
|
|
62
|
+
open Sentry
|
|
63
|
+
withScope(scope => {
|
|
64
|
+
scope->Scope.setExtra("module", loc.subModulePath->List.toArray)
|
|
65
|
+
scope->Scope.setExtra("fullPath", loc.fullPath)
|
|
66
|
+
scope->Scope.setExtra("function", loc.value)
|
|
67
|
+
scope->Scope.setExtra(label1, data1)
|
|
68
|
+
scope->Scope.setExtra(label2, data2)
|
|
69
|
+
scope->Scope.setExtra(label3, data3)
|
|
70
|
+
scope->Scope.setExtra(label4, data4)
|
|
71
|
+
captureMessage(event)
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
let error5 = (
|
|
75
|
+
loc: ReScriptLogger.Location.t,
|
|
76
|
+
event,
|
|
77
|
+
(label1, data1),
|
|
78
|
+
(label2, data2),
|
|
79
|
+
(label3, data3),
|
|
80
|
+
(label4, data4),
|
|
81
|
+
(label5, data5),
|
|
82
|
+
) => {
|
|
83
|
+
open Sentry
|
|
84
|
+
withScope(scope => {
|
|
85
|
+
scope->Scope.setExtra("module", loc.subModulePath->List.toArray)
|
|
86
|
+
scope->Scope.setExtra("fullPath", loc.fullPath)
|
|
87
|
+
scope->Scope.setExtra("function", loc.value)
|
|
88
|
+
scope->Scope.setExtra(label1, data1)
|
|
89
|
+
scope->Scope.setExtra(label2, data2)
|
|
90
|
+
scope->Scope.setExtra(label3, data3)
|
|
91
|
+
scope->Scope.setExtra(label4, data4)
|
|
92
|
+
scope->Scope.setExtra(label5, data5)
|
|
93
|
+
captureMessage(event)
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
let errorWithData = (loc: ReScriptLogger.Location.t, event, (label, data)) => {
|
|
98
|
+
open Sentry
|
|
99
|
+
withScope(scope => {
|
|
100
|
+
scope->Scope.setExtra("module", loc.subModulePath->List.toArray)
|
|
101
|
+
scope->Scope.setExtra(label, data)
|
|
102
|
+
captureMessage(event)
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let errorWithData2 = (loc: ReScriptLogger.Location.t, event, (label1, data1), (label2, data2)) => {
|
|
107
|
+
open Sentry
|
|
108
|
+
withScope(scope => {
|
|
109
|
+
scope->Scope.setExtra("module", loc.subModulePath->List.toArray)
|
|
110
|
+
scope->Scope.setExtra(label1, data1)
|
|
111
|
+
scope->Scope.setExtra(label2, data2)
|
|
112
|
+
captureMessage(event)
|
|
113
|
+
})
|
|
114
|
+
}
|
|
@@ -23,6 +23,19 @@ module Footer = {
|
|
|
23
23
|
</footer>
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
module NavOpenContext = {
|
|
27
|
+
let context = React.createContext(false)
|
|
28
|
+
|
|
29
|
+
module Provider = {
|
|
30
|
+
let provider = React.Context.provider(context)
|
|
31
|
+
|
|
32
|
+
@react.component
|
|
33
|
+
let make = (~value, ~children) => {
|
|
34
|
+
React.createElement(provider, {"value": value, "children": children})
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
26
39
|
module App = {
|
|
27
40
|
let localStorageNavKey = "@colisweb/navOpen"
|
|
28
41
|
|
|
@@ -149,19 +162,21 @@ module App = {
|
|
|
149
162
|
|
|
150
163
|
let hideMenu = React.useCallback(_ => setOpen(_ => false))
|
|
151
164
|
|
|
152
|
-
<
|
|
153
|
-
<
|
|
154
|
-
|
|
155
|
-
<
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
className
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
165
|
+
<NavOpenContext.Provider value={isNavOpen}>
|
|
166
|
+
<div>
|
|
167
|
+
<TopNavigationBar username logout logoutLabel toggleMenu onLogoClick />
|
|
168
|
+
<div className="flex">
|
|
169
|
+
<LeftNavigationBar isNavOpen ?bottom hideMenu> sideNavRender </LeftNavigationBar>
|
|
170
|
+
<main
|
|
171
|
+
className={cx([
|
|
172
|
+
className,
|
|
173
|
+
"flex-initial w-full transition-all duration-300 ease-in-out mt-16 z-20",
|
|
174
|
+
isNavOpen ? "navOpen lg:pl-64" : "lg:pl-16",
|
|
175
|
+
])}>
|
|
176
|
+
children
|
|
177
|
+
</main>
|
|
178
|
+
</div>
|
|
164
179
|
</div>
|
|
165
|
-
</
|
|
180
|
+
</NavOpenContext.Provider>
|
|
166
181
|
}
|
|
167
182
|
}
|
|
@@ -3,7 +3,7 @@ and options = {
|
|
|
3
3
|
id: id,
|
|
4
4
|
isVisible: bool,
|
|
5
5
|
title: string,
|
|
6
|
-
|
|
6
|
+
content: option<React.element>,
|
|
7
7
|
closable: bool,
|
|
8
8
|
variant: variant,
|
|
9
9
|
timeout: int,
|
|
@@ -32,14 +32,14 @@ let store = Restorative.createStore({list: []}, (state, action) =>
|
|
|
32
32
|
}
|
|
33
33
|
)
|
|
34
34
|
|
|
35
|
-
let show = (~title, ~
|
|
35
|
+
let show = (~title, ~content=?, ~closable=true, ~variant, ~timeout=5000, ()) => {
|
|
36
36
|
let id: id = Js.Math.random()->Js.Float.toString->Obj.magic
|
|
37
37
|
store.dispatch(
|
|
38
38
|
Show({
|
|
39
39
|
id: id,
|
|
40
40
|
isVisible: true,
|
|
41
41
|
title: title,
|
|
42
|
-
|
|
42
|
+
content: content,
|
|
43
43
|
closable: closable,
|
|
44
44
|
variant: variant,
|
|
45
45
|
timeout: timeout,
|
|
@@ -58,12 +58,13 @@ let hide = id => {
|
|
|
58
58
|
module Item = {
|
|
59
59
|
@react.component
|
|
60
60
|
let make = (~options) => {
|
|
61
|
-
let {id, isVisible, variant, title,
|
|
61
|
+
let {id, isVisible, variant, title, content, closable, timeout} = options
|
|
62
62
|
|
|
63
63
|
let (mounted, setMounted) = React.useState(() => false)
|
|
64
64
|
|
|
65
65
|
React.useEffect0(() => {
|
|
66
66
|
setMounted(_ => true)
|
|
67
|
+
|
|
67
68
|
let timeoutId = Js.Global.setTimeout(() => {
|
|
68
69
|
hide(id)
|
|
69
70
|
}, timeout)
|
|
@@ -71,51 +72,58 @@ module Item = {
|
|
|
71
72
|
})
|
|
72
73
|
|
|
73
74
|
<div
|
|
75
|
+
style={ReactDOM.Style.make(~pointerEvents="all", ())}
|
|
74
76
|
className={cx([
|
|
75
|
-
"
|
|
76
|
-
{
|
|
77
|
-
open Css
|
|
78
|
-
style(list{bottom(40->px), unsafe("pointer-events", "all")})
|
|
79
|
-
},
|
|
77
|
+
"rounded shadow transition duration-500 ease-in-out mt-3 p-3 pl-3 pr-10 transform",
|
|
80
78
|
mounted ? "-translate-y-14" : "!opacity-0",
|
|
81
79
|
isVisible ? "opacity-100" : "opacity-0 translate-x-[200px]",
|
|
82
80
|
{
|
|
83
81
|
switch variant {
|
|
84
|
-
| #success => "bg-success-
|
|
85
|
-
| #warning => "bg-warning-
|
|
86
|
-
| #danger => "bg-danger-
|
|
82
|
+
| #success => "bg-success-100"
|
|
83
|
+
| #warning => "bg-warning-100"
|
|
84
|
+
| #danger => "bg-danger-100 "
|
|
87
85
|
}
|
|
88
86
|
},
|
|
89
87
|
])}>
|
|
90
|
-
|
|
88
|
+
{closable
|
|
89
|
+
? <button className="absolute right-1" onClick={_ => hide(id)}>
|
|
90
|
+
<BsReactIcons.MdClose
|
|
91
|
+
size={24}
|
|
92
|
+
className={cx([
|
|
93
|
+
{
|
|
94
|
+
switch variant {
|
|
95
|
+
| #success => "text-neutral-700"
|
|
96
|
+
| #warning => "text-warning-700"
|
|
97
|
+
| #danger => "text-danger-700"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
])}
|
|
101
|
+
/>
|
|
102
|
+
</button>
|
|
103
|
+
: React.null}
|
|
104
|
+
<div className="flex flex-row gap-3 relative">
|
|
91
105
|
<div>
|
|
92
106
|
{switch variant {
|
|
93
|
-
| #success => <BsReactIcons.MdCheckCircle size=28 />
|
|
94
|
-
| #warning => <BsReactIcons.MdWarning size=28 />
|
|
95
|
-
| #danger => <BsReactIcons.MdError size=28 />
|
|
107
|
+
| #success => <BsReactIcons.MdCheckCircle size=28 className="text-success-600" />
|
|
108
|
+
| #warning => <BsReactIcons.MdWarning size=28 className="text-warning-600" />
|
|
109
|
+
| #danger => <BsReactIcons.MdError size=28 className="text-danger-600" />
|
|
96
110
|
}}
|
|
97
111
|
</div>
|
|
98
112
|
<div>
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
</p>
|
|
111
|
-
)}
|
|
113
|
+
<p
|
|
114
|
+
className={cx([
|
|
115
|
+
"text-lg",
|
|
116
|
+
switch variant {
|
|
117
|
+
| #success => "text-neutral-700"
|
|
118
|
+
| #warning => "text-warning-700"
|
|
119
|
+
| #danger => "text-danger-700"
|
|
120
|
+
},
|
|
121
|
+
])}>
|
|
122
|
+
{title->React.string}
|
|
123
|
+
</p>
|
|
112
124
|
</div>
|
|
113
|
-
{closable
|
|
114
|
-
? <button className="self-start" onClick={_ => hide(id)}>
|
|
115
|
-
<BsReactIcons.MdClose />
|
|
116
|
-
</button>
|
|
117
|
-
: React.null}
|
|
118
125
|
</div>
|
|
126
|
+
{content->Option.getWithDefault(React.null)}
|
|
119
127
|
</div>
|
|
120
128
|
}
|
|
121
129
|
}
|
|
@@ -2,21 +2,23 @@ module Sentry = {
|
|
|
2
2
|
module Scope = {
|
|
3
3
|
type t
|
|
4
4
|
|
|
5
|
-
@
|
|
5
|
+
@send external setExtra: (t, string, 'a) => unit = "setExtra"
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
@module("
|
|
9
|
-
external init: Js.t<'a> => unit = "init"
|
|
8
|
+
@module("sentry-expo") external init: 'a => unit = "init"
|
|
10
9
|
|
|
11
|
-
@module("
|
|
10
|
+
@module("sentry-expo") @scope("Native")
|
|
12
11
|
external setTag: (string, string) => unit = "setTag"
|
|
13
12
|
|
|
14
|
-
@module("
|
|
13
|
+
@module("sentry-expo") @scope("Native")
|
|
14
|
+
external setUser: 'a => unit = "setUser"
|
|
15
|
+
|
|
16
|
+
@module("sentry-expo") @scope("Native")
|
|
15
17
|
external captureException: Js.Promise.error => unit = "captureException"
|
|
16
18
|
|
|
17
|
-
@module("
|
|
19
|
+
@module("sentry-expo") @scope("Native")
|
|
18
20
|
external captureMessage: string => unit = "captureMessage"
|
|
19
21
|
|
|
20
|
-
@module("
|
|
22
|
+
@module("sentry-expo") @scope("Native")
|
|
21
23
|
external withScope: (Scope.t => unit) => unit = "withScope"
|
|
22
24
|
}
|