5htp-core 0.3.4 → 0.3.5
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/client/app/component.tsx +3 -0
- package/src/client/assets/css/components/button.less +6 -5
- package/src/client/assets/css/components/card.less +0 -22
- package/src/client/assets/css/components.less +0 -25
- package/src/client/assets/css/core.less +62 -3
- package/src/client/assets/css/text/icons.less +3 -2
- package/src/client/assets/css/text/text.less +0 -4
- package/src/client/assets/css/theme.less +69 -39
- package/src/client/assets/css/utils/layouts.less +1 -12
- package/src/client/assets/css/utils/medias.less +2 -15
- package/src/client/components/Dialog/index.less +2 -0
- package/src/client/components/Form.ts +4 -3
- package/src/client/components/Row/index.less +2 -0
- package/src/client/components/Video/index.less +6 -1
- package/src/client/components/containers/Popover/index.tsx +1 -2
- package/src/client/components/containers/Popover/popover.less +2 -0
- package/src/client/components/data/progressbar/index.less +2 -0
- package/src/client/components/inputv3/base.less +6 -0
- package/src/client/components/inputv3/file/index.less +2 -0
- package/src/client/pages/_messages/401.tsx +1 -2
- package/src/client/services/router/components/Page.tsx +1 -0
- package/src/client/services/router/components/router.tsx +37 -13
- package/src/client/services/router/index.tsx +22 -13
- package/src/client/services/router/request/api.ts +21 -13
- package/src/client/services/router/response/index.tsx +26 -12
- package/src/client/services/router/response/page.ts +1 -1
- package/src/common/router/index.ts +41 -0
- package/src/common/router/request/api.ts +2 -0
- package/src/common/router/response/index.ts +2 -2
- package/src/common/router/response/page.ts +1 -0
- package/src/common/validation/validator.ts +12 -2
- package/src/common/validation/validators.ts +5 -5
- package/src/server/app/index.ts +0 -1
- package/src/server/app/service/index.ts +12 -3
- package/src/server/services/console/index.ts +2 -4
- package/src/server/services/router/http/index.ts +5 -7
- package/src/server/services/router/index.ts +9 -10
- package/src/server/services/router/request/api.ts +7 -2
- package/src/server/services/router/response/index.ts +13 -12
- package/src/types/aliases.d.ts +4 -4
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "5htp-core",
|
|
3
3
|
"description": "Convenient TypeScript framework designed for Performance and Productivity.",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.5",
|
|
5
5
|
"author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
|
|
6
6
|
"repository": "git://github.com/gaetanlegac/5htp-core.git",
|
|
7
7
|
"license": "MIT",
|
|
@@ -14,6 +14,9 @@ import DialogManager from '@client/components/Dialog/Manager'
|
|
|
14
14
|
import RouterComponent from '@client/services/router/components/router';
|
|
15
15
|
import type { TClientOrServerContext } from '@common/router';
|
|
16
16
|
|
|
17
|
+
// Resources
|
|
18
|
+
import '@client/assets/css/core.less';
|
|
19
|
+
|
|
17
20
|
/*----------------------------------
|
|
18
21
|
- COMPOSANT
|
|
19
22
|
----------------------------------*/
|
|
@@ -27,16 +27,17 @@
|
|
|
27
27
|
font-weight: 600;
|
|
28
28
|
|
|
29
29
|
// Colors
|
|
30
|
+
background: var(--cBg);
|
|
30
31
|
color: var(--cTxtAccent);
|
|
31
32
|
|
|
32
33
|
// Hover
|
|
33
|
-
transition: all .5s linear;
|
|
34
|
+
//transition: all .5s linear;
|
|
34
35
|
&:hover,
|
|
35
36
|
&.selected,
|
|
36
37
|
li:hover > & {
|
|
37
38
|
|
|
38
39
|
color: var(--cTxtImportant);
|
|
39
|
-
transition: all .1s linear;
|
|
40
|
+
//transition: all .1s linear;
|
|
40
41
|
|
|
41
42
|
> i {
|
|
42
43
|
color: var(--cAccent)
|
|
@@ -63,8 +64,8 @@
|
|
|
63
64
|
text-align: left;
|
|
64
65
|
white-space: nowrap; // Autrement, si plusieurs mots, affiché sur plusieurs ligne
|
|
65
66
|
gap: @spacing / 2;
|
|
66
|
-
min-width: 4em;
|
|
67
67
|
font-size: 1rem;
|
|
68
|
+
line-height: 1.5em;
|
|
68
69
|
z-index: 1; // Make the label on top of ::before for example
|
|
69
70
|
|
|
70
71
|
li > & {
|
|
@@ -99,7 +100,7 @@
|
|
|
99
100
|
&:not(:disabled) {
|
|
100
101
|
&:hover,
|
|
101
102
|
li:hover > & {
|
|
102
|
-
background: var(--
|
|
103
|
+
background: var(--cBgActive);
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
|
|
@@ -220,7 +221,7 @@ ul.row {
|
|
|
220
221
|
|
|
221
222
|
&.selected,
|
|
222
223
|
&:hover {
|
|
223
|
-
background: var(--
|
|
224
|
+
background: var(--cBgActive);
|
|
224
225
|
color: var(--cTxtImportant);
|
|
225
226
|
}
|
|
226
227
|
|
|
@@ -145,28 +145,6 @@
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
.msg, .card.bg.info {
|
|
149
|
-
|
|
150
|
-
padding: @spacing @cardPaddingLong;
|
|
151
|
-
|
|
152
|
-
.build-theme-bg( lighten(@cInfo, 35%), darken(@cInfo, 20%));
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
.msg, .card.bg {
|
|
157
|
-
&.error {
|
|
158
|
-
.build-theme-bg( lighten(@cInfo, 35%), darken(@cInfo, 20%));
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
&.warn {
|
|
162
|
-
.build-theme-bg( lighten(@cWarn, 25%), darken(@cWarn, 30%));
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
&.success {
|
|
166
|
-
.build-theme-bg( lighten(@cSuccess, 50%), darken(@cSuccess, 30%));
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
148
|
iframe {
|
|
171
149
|
border: none;
|
|
172
150
|
}
|
|
@@ -23,31 +23,6 @@
|
|
|
23
23
|
@import './utils/layouts.less';
|
|
24
24
|
@import './utils/medias.less';
|
|
25
25
|
|
|
26
|
-
.white-card() {
|
|
27
|
-
background: white;
|
|
28
|
-
box-shadow: 0 3px 2px fade(#000, 10%);
|
|
29
|
-
border: solid 1px fade(#000, 10%);
|
|
30
|
-
border-radius: @radius;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.card,
|
|
34
|
-
.btn,
|
|
35
|
-
.input.text,
|
|
36
|
-
.input.select,
|
|
37
|
-
i.solid {
|
|
38
|
-
|
|
39
|
-
.build-theme-bg( #fff, #8E8E8E);
|
|
40
|
-
|
|
41
|
-
&:not(.bg) {
|
|
42
|
-
.white-card();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.bg & {
|
|
46
|
-
box-shadow: none;
|
|
47
|
-
border: none;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
26
|
.input.text {
|
|
52
27
|
&.error {
|
|
53
28
|
border-color: @cError;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import (reference) '@/client/assets/vars.less';
|
|
2
|
+
|
|
1
3
|
// Utils
|
|
2
4
|
@import './utils/sizing.less';
|
|
3
5
|
@import './utils/spacing.less';
|
|
@@ -18,16 +20,41 @@
|
|
|
18
20
|
background-repeat: no-repeat;
|
|
19
21
|
background-position: center;
|
|
20
22
|
|
|
21
|
-
.build-theme-bg(#000, #fff);
|
|
22
23
|
text-shadow: 0 0 10px fade(#000, 20%);
|
|
23
24
|
|
|
25
|
+
.apply-theme({
|
|
26
|
+
background: #000;
|
|
27
|
+
foreground: #fff;
|
|
28
|
+
accent1: #fff;
|
|
29
|
+
accent2: #fff;
|
|
30
|
+
}, {
|
|
31
|
+
background: #111;
|
|
32
|
+
foreground: #fff;
|
|
33
|
+
accent1: #fff;
|
|
34
|
+
accent2: #fff;
|
|
35
|
+
});
|
|
36
|
+
|
|
24
37
|
--cTxtDiscret: fade(#fff, 40%)
|
|
25
38
|
--cTxtDesc: fade(#fff, 60%);
|
|
26
39
|
--cTxtBase: fade(#fff, 80%);
|
|
27
40
|
--cTxtImportant: fade(#fff, 100%);
|
|
28
|
-
--cTxtAccent:
|
|
41
|
+
--cTxtAccent: #FFF;
|
|
29
42
|
|
|
30
43
|
&.light {
|
|
44
|
+
.apply-theme({
|
|
45
|
+
background: #fff;
|
|
46
|
+
foreground: #000;
|
|
47
|
+
accent1: #000;
|
|
48
|
+
accent2: #000;
|
|
49
|
+
},{
|
|
50
|
+
background: #fff;
|
|
51
|
+
foreground: #000;
|
|
52
|
+
accent1: #000;
|
|
53
|
+
accent2: #000;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
text-shadow: none;
|
|
57
|
+
|
|
31
58
|
--cTxtDiscret: fade(#000, 40%)
|
|
32
59
|
--cTxtDesc: fade(#000, 60%);
|
|
33
60
|
--cTxtBase: fade(#000, 80%);
|
|
@@ -55,6 +82,33 @@
|
|
|
55
82
|
position: relative;
|
|
56
83
|
}
|
|
57
84
|
}
|
|
85
|
+
|
|
86
|
+
&.faded {
|
|
87
|
+
position: relative;
|
|
88
|
+
|
|
89
|
+
> * {
|
|
90
|
+
z-index: 1;
|
|
91
|
+
position: relative;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
&:after {
|
|
95
|
+
content: ' ';
|
|
96
|
+
display: block;
|
|
97
|
+
|
|
98
|
+
z-index: 0;
|
|
99
|
+
position: absolute;
|
|
100
|
+
bottom: 0px;
|
|
101
|
+
left: 0px;
|
|
102
|
+
right: 0px;
|
|
103
|
+
|
|
104
|
+
height: 85%;
|
|
105
|
+
background: linear-gradient(
|
|
106
|
+
to bottom,
|
|
107
|
+
transparent,
|
|
108
|
+
#fff
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
58
112
|
}
|
|
59
113
|
|
|
60
114
|
&.bg-cover {
|
|
@@ -106,4 +160,9 @@ body {
|
|
|
106
160
|
-webkit-font-smoothing: antialiased;
|
|
107
161
|
-moz-osx-font-smoothing: grayscale;
|
|
108
162
|
|
|
109
|
-
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Import components style (always after variables declaration)
|
|
166
|
+
@import "@client/assets/css/components.less";
|
|
167
|
+
|
|
168
|
+
@import '@/client/assets/theme.less';
|
|
@@ -201,11 +201,7 @@ pre {
|
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
code {
|
|
204
|
-
background: @c3;
|
|
205
|
-
border-top: solid 1px @c3 - #111;
|
|
206
|
-
border-bottom: solid 1px @c3 - #111;
|
|
207
204
|
padding: @spacing @readingMargin;
|
|
208
|
-
color: @c3 + #888;
|
|
209
205
|
text-align: left;
|
|
210
206
|
font-size: 1rem;
|
|
211
207
|
line-height: 2em;
|
|
@@ -1,67 +1,97 @@
|
|
|
1
1
|
@bgDelta: #111;
|
|
2
2
|
@fgDelta: #999;
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
@bg,
|
|
6
|
-
@fg: if( lightness(@bg) >= 80%, @bg - @fgDelta, @bg + @fgDelta),
|
|
7
|
-
@cAccent: @c1,
|
|
8
|
-
@cAccent2: @c2,
|
|
9
|
-
@apply: true
|
|
10
|
-
) {
|
|
4
|
+
/* Theme structure:
|
|
11
5
|
|
|
12
|
-
|
|
6
|
+
background?: COLOR;
|
|
7
|
+
foreground: COLOR;
|
|
8
|
+
accent1: COLOR;
|
|
9
|
+
accent2: COLOR;
|
|
10
|
+
*/
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
.apply-theme( @theme, @componentsTheme: false, @apply: true ) {
|
|
13
|
+
|
|
14
|
+
.apply-theme-style( @theme, @componentsTheme, @apply );
|
|
15
|
+
|
|
16
|
+
// Children Components
|
|
17
|
+
& when not (@componentsTheme = false) {
|
|
18
|
+
// Default theming for the children components
|
|
19
|
+
@{componentsSelector} {
|
|
20
|
+
// Don't apply the default theme to already themed components
|
|
21
|
+
&:not(.bg) {
|
|
22
|
+
.apply-theme-style( @componentsTheme, false, false );
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.apply-theme-style( @theme, @componentsTheme: false, @apply: true ) {
|
|
29
|
+
|
|
30
|
+
@isLight: boolean( lightness( @bg ) >= 80% );
|
|
31
|
+
|
|
32
|
+
// Flags
|
|
33
|
+
@bg: @theme[background];
|
|
34
|
+
@bgActive: if( @isLight,
|
|
35
|
+
@bg - #111,
|
|
36
|
+
@bg + #111,
|
|
37
|
+
);
|
|
38
|
+
@fg: @theme[foreground];
|
|
16
39
|
|
|
17
40
|
// Background
|
|
18
|
-
// TODO: Nettoyer
|
|
19
|
-
@bg2: darken(@bg, 8%);
|
|
20
|
-
@bgDark: darken(@bg, 7%);
|
|
21
|
-
@bgDarkPlus: darken(@bg, 10%);
|
|
22
41
|
--cBg: @bg;
|
|
23
|
-
--
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
--cBgHover: #f5f5f5;
|
|
42
|
+
--cBgActive: @bgActive;
|
|
43
|
+
& when (@apply = true) {
|
|
44
|
+
background: var(--cBg);
|
|
45
|
+
}
|
|
28
46
|
|
|
29
|
-
|
|
30
|
-
|
|
47
|
+
// Accent
|
|
48
|
+
& when (@theme[accent1]) {
|
|
49
|
+
--cAccent: @theme[accent1];
|
|
50
|
+
}
|
|
51
|
+
& when (@theme[accent2]) {
|
|
52
|
+
--cAccent2: @theme[accent2];
|
|
53
|
+
}
|
|
31
54
|
|
|
32
|
-
//
|
|
55
|
+
// Lines
|
|
33
56
|
@cLine: if( @isLight, @bg - #151515, @bg + #151515);
|
|
34
|
-
@cLine2: if( @isLight, @bg - #191919, @bg + #050505);
|
|
35
57
|
--cLine: @cLine;
|
|
58
|
+
@cLine2: if( @isLight, @bg - #191919, @bg + #050505);
|
|
36
59
|
--cLine2: @cLine2;
|
|
37
60
|
|
|
38
61
|
// Text
|
|
39
|
-
.build-theme-fg(@fg, @bg, @
|
|
62
|
+
.build-theme-fg(@fg, @bg, @theme[accent1], @theme[accent2]);
|
|
40
63
|
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
/*.input.text {
|
|
45
|
-
border: if(@bg = #ffffff, solid 2px var(--cLine), none);
|
|
46
|
-
}*/
|
|
47
|
-
}
|
|
64
|
+
// TO REMOVE
|
|
65
|
+
--cBgControl: if( @bg = #fff, @cBgPage, #fff );
|
|
66
|
+
--cBgHover: #f5f5f5;
|
|
48
67
|
}
|
|
49
68
|
|
|
50
|
-
.build-theme-fg(
|
|
69
|
+
.build-theme-fg(
|
|
70
|
+
@cTxtBase,
|
|
71
|
+
@bg: @cBgPage,
|
|
72
|
+
@cAccent: false,
|
|
73
|
+
@cAccent2: false
|
|
74
|
+
) {
|
|
51
75
|
|
|
52
76
|
@isLight: boolean( lightness(@bg) >= 70% );
|
|
77
|
+
|
|
78
|
+
// Base
|
|
79
|
+
--cTxtBase: @cTxtBase;
|
|
53
80
|
|
|
54
|
-
//
|
|
81
|
+
// Discret
|
|
55
82
|
@cTxtDiscret: if( @isLight, @bg - #444, @bg + #444);
|
|
56
|
-
@cTxtDesc: if( @isLight, @cTxtBase + #222, @cTxtBase - #222);
|
|
57
|
-
@cTxtImportant: if( @isLight, @cDark, #fff);
|
|
58
|
-
@cTxtAccent: if( @bg = @c1, @cTxtImportant, @c1);
|
|
59
|
-
|
|
60
83
|
--cTxtDiscret: @cTxtDiscret;
|
|
84
|
+
|
|
85
|
+
// Desc
|
|
86
|
+
@cTxtDesc: if( @isLight, @cTxtBase + #222, @cTxtBase - #222);
|
|
61
87
|
--cTxtDesc: @cTxtDesc;
|
|
62
|
-
|
|
88
|
+
|
|
89
|
+
// Important
|
|
90
|
+
@cTxtImportant: if( @isLight, @cDark, #fff);
|
|
63
91
|
--cTxtImportant: @cTxtImportant;
|
|
64
|
-
|
|
92
|
+
|
|
93
|
+
// Accent
|
|
94
|
+
--cTxtAccent: @cAccent;
|
|
65
95
|
|
|
66
96
|
color: var(--cTxtBase);
|
|
67
97
|
}
|
|
@@ -47,17 +47,6 @@
|
|
|
47
47
|
> li {
|
|
48
48
|
position: relative;
|
|
49
49
|
|
|
50
|
-
> a:hover::before {
|
|
51
|
-
content: ' ';
|
|
52
|
-
position: absolute;
|
|
53
|
-
top: 0; left: 0; bottom: 0; right: 0;
|
|
54
|
-
margin: 0 0.3em;
|
|
55
|
-
background: var(--cBgAccent);
|
|
56
|
-
border-radius: @radius;
|
|
57
|
-
z-index: 0;
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
50
|
> a > * {
|
|
62
51
|
z-index: 1;
|
|
63
52
|
position: relative;
|
|
@@ -298,7 +287,7 @@
|
|
|
298
287
|
&.y-@{i} {
|
|
299
288
|
/*@t_zones: (@L_max) / @i;
|
|
300
289
|
@espace_zone: ~"repeat(@{i}, minmax(@{L_min}, @{t_zones}))";*/
|
|
301
|
-
@espace_zone: ~"repeat(@{i},
|
|
290
|
+
@espace_zone: ~"repeat(@{i}, min-content)";
|
|
302
291
|
.construire(@espace_zone, row);
|
|
303
292
|
}
|
|
304
293
|
|
|
@@ -1,23 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
img.img,
|
|
3
|
-
.bg.img {
|
|
4
|
-
background: @cBgPage - #101010;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
1
|
img {
|
|
8
2
|
max-width: 100%;
|
|
9
3
|
display: block;
|
|
10
4
|
|
|
11
5
|
&.img {
|
|
12
6
|
border-radius: @radius;
|
|
7
|
+
object-fit: cover;
|
|
8
|
+
object-position: center;
|
|
13
9
|
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/*----------------------------------
|
|
17
|
-
- IMAGE CONFIG
|
|
18
|
-
----------------------------------*/
|
|
19
|
-
|
|
20
|
-
img.img {
|
|
21
|
-
object-fit: cover;
|
|
22
|
-
object-position: center;
|
|
23
10
|
}
|
|
@@ -181,15 +181,16 @@ export default function useForm<TFormData extends {}>(
|
|
|
181
181
|
|
|
182
182
|
// Submit on press enter
|
|
183
183
|
onKeyDown: e => {
|
|
184
|
-
if (e.key === 'Enter') {
|
|
184
|
+
if (e.key === 'Enter' || (e.keyCode || e.which) === 13) {
|
|
185
185
|
submit({ [fieldName]: e.target.value } as Partial<TFormData>);
|
|
186
186
|
}
|
|
187
187
|
},
|
|
188
188
|
|
|
189
189
|
// Error
|
|
190
190
|
errors: state.errors[fieldName],
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
|
|
192
|
+
// Component attributes
|
|
193
|
+
...validator.componentAttributes
|
|
193
194
|
}
|
|
194
195
|
}
|
|
195
196
|
}
|
|
@@ -102,12 +102,11 @@ export default (props: Props) => {
|
|
|
102
102
|
let renderedContent: ComponentChild;
|
|
103
103
|
if (active) {
|
|
104
104
|
//content = typeof content === 'function' ? React.createElement(content) : content;
|
|
105
|
-
console.log("render content", content);
|
|
106
105
|
renderedContent = React.cloneElement(
|
|
107
106
|
content,
|
|
108
107
|
{
|
|
109
108
|
className: (content.props.className || '')
|
|
110
|
-
+ ' card
|
|
109
|
+
+ ' card popover pd-1'
|
|
111
110
|
+ (position ? ' pos_' + position.cote : ''),
|
|
112
111
|
|
|
113
112
|
ref: (ref: any) => {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import (reference) "@/client/assets/vars.less";
|
|
2
|
+
|
|
1
3
|
@hInput: @sizeComponent;
|
|
2
4
|
@labelH: 0.6em;
|
|
3
5
|
|
|
@@ -14,6 +16,9 @@
|
|
|
14
16
|
&.text,
|
|
15
17
|
&.select {
|
|
16
18
|
|
|
19
|
+
background: var(--cBg);
|
|
20
|
+
border-radius: @radius;
|
|
21
|
+
|
|
17
22
|
> i {
|
|
18
23
|
color: var(--cTxtDesc);
|
|
19
24
|
}
|
|
@@ -108,6 +113,7 @@
|
|
|
108
113
|
width: 100%;
|
|
109
114
|
padding: @labelH 0 0 0;
|
|
110
115
|
font-size: 1rem;
|
|
116
|
+
color: inherit;
|
|
111
117
|
}
|
|
112
118
|
|
|
113
119
|
input {
|
|
@@ -21,7 +21,7 @@ import useHeader from '@client/pages/useHeader';
|
|
|
21
21
|
----------------------------------*/
|
|
22
22
|
Router.error( 401, ({ message, request, page }) => {
|
|
23
23
|
|
|
24
|
-
request.response?.redirect('
|
|
24
|
+
request.response?.redirect('https://becrosspath.com');
|
|
25
25
|
|
|
26
26
|
useHeader({
|
|
27
27
|
title: 'Authentication Required',
|
|
@@ -32,7 +32,6 @@ Router.error( 401, ({ message, request, page }) => {
|
|
|
32
32
|
|
|
33
33
|
page?.go('/');
|
|
34
34
|
|
|
35
|
-
|
|
36
35
|
}, []);
|
|
37
36
|
|
|
38
37
|
return (
|
|
@@ -44,31 +44,59 @@ const PageLoading = ({ clientRouter }: { clientRouter?: ClientRouter }) => {
|
|
|
44
44
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
const scrollToElement = (selector: string) => document.querySelector( selector )
|
|
48
|
+
?.scrollIntoView({
|
|
49
|
+
behavior: "smooth",
|
|
50
|
+
block: "start",
|
|
51
|
+
inline: "nearest"
|
|
52
|
+
})
|
|
53
|
+
|
|
47
54
|
/*----------------------------------
|
|
48
55
|
- COMPONENT
|
|
49
56
|
----------------------------------*/
|
|
50
57
|
export default ({ service: clientRouter }: { service?: ClientRouter }) => {
|
|
51
58
|
|
|
59
|
+
/*----------------------------------
|
|
60
|
+
- INIT
|
|
61
|
+
----------------------------------*/
|
|
62
|
+
|
|
52
63
|
const context = useContext();
|
|
53
64
|
|
|
65
|
+
// Bind context object to client router
|
|
66
|
+
if (clientRouter !== undefined)
|
|
67
|
+
clientRouter.context = context;
|
|
68
|
+
|
|
54
69
|
const [pages, setPages] = React.useState<{
|
|
55
70
|
current: undefined | Page
|
|
56
71
|
}>({
|
|
57
72
|
current: context.page
|
|
58
73
|
});
|
|
59
74
|
|
|
75
|
+
/*----------------------------------
|
|
76
|
+
- ACTIONS
|
|
77
|
+
----------------------------------*/
|
|
60
78
|
const resolvePage = async (request: ClientRequest, locationUpdate?: Update) => {
|
|
61
79
|
|
|
62
80
|
if (!clientRouter) return;
|
|
63
81
|
|
|
82
|
+
const currentRequest = context.request;
|
|
83
|
+
context.request = request;
|
|
84
|
+
|
|
64
85
|
// WARNING: Don"t try to play with pages here, since the object will not be updated
|
|
65
86
|
// If needed to play with pages, do it in the setPages callback below
|
|
87
|
+
// Unchanged path
|
|
88
|
+
if (request.path === currentRequest.path) {
|
|
89
|
+
|
|
90
|
+
// Scroll to component
|
|
91
|
+
if (request.hash) {
|
|
92
|
+
scrollToElement(request.hash);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
66
97
|
|
|
67
98
|
// Set loading state
|
|
68
99
|
clientRouter.setLoading(true);
|
|
69
|
-
|
|
70
|
-
// Load the route chunks
|
|
71
|
-
context.request = request;
|
|
72
100
|
const newpage = context.page = await clientRouter.resolve(request);
|
|
73
101
|
|
|
74
102
|
// Page not found: Directly load with the browser
|
|
@@ -82,7 +110,7 @@ export default ({ service: clientRouter }: { service?: ClientRouter }) => {
|
|
|
82
110
|
}
|
|
83
111
|
|
|
84
112
|
// Fetch API data to hydrate the page
|
|
85
|
-
const newData =
|
|
113
|
+
const newData = await newpage.fetchData();
|
|
86
114
|
|
|
87
115
|
// Add page container
|
|
88
116
|
setPages( pages => {
|
|
@@ -111,16 +139,12 @@ export default ({ service: clientRouter }: { service?: ClientRouter }) => {
|
|
|
111
139
|
context.app.setLayout(newLayout);
|
|
112
140
|
}
|
|
113
141
|
|
|
114
|
-
return
|
|
142
|
+
return { current: newpage }
|
|
115
143
|
});
|
|
116
144
|
}
|
|
117
145
|
|
|
118
146
|
const restoreScroll = (currentPage?: Page) => currentPage?.scrollToId
|
|
119
|
-
&&
|
|
120
|
-
behavior: "smooth",
|
|
121
|
-
block: "start",
|
|
122
|
-
inline: "nearest"
|
|
123
|
-
})
|
|
147
|
+
&& scrollToElement( currentPage.scrollToId.substring(1) )
|
|
124
148
|
|
|
125
149
|
// First render
|
|
126
150
|
React.useEffect(() => {
|
|
@@ -135,9 +159,6 @@ export default ({ service: clientRouter }: { service?: ClientRouter }) => {
|
|
|
135
159
|
// Load the concerned route
|
|
136
160
|
const request = new ClientRequest(locationUpdate.location, context.Router);
|
|
137
161
|
await resolvePage(request);
|
|
138
|
-
|
|
139
|
-
// Scroll to the selected content via url hash
|
|
140
|
-
//restoreScroll(pages.current);
|
|
141
162
|
})
|
|
142
163
|
}, []);
|
|
143
164
|
|
|
@@ -161,6 +182,9 @@ export default ({ service: clientRouter }: { service?: ClientRouter }) => {
|
|
|
161
182
|
|
|
162
183
|
}, [pages.current]);
|
|
163
184
|
|
|
185
|
+
/*----------------------------------
|
|
186
|
+
- RENDER
|
|
187
|
+
----------------------------------*/
|
|
164
188
|
// Render the page component
|
|
165
189
|
return <>
|
|
166
190
|
{/*pages.previous && (
|