5htp-core 0.4.1 → 0.4.2
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 +2 -3
- package/src/client/app/index.ts +8 -7
- package/src/client/assets/css/components/button.less +13 -9
- package/src/client/assets/css/components/table.less +13 -1
- package/src/client/assets/css/core.less +0 -1
- package/src/client/assets/css/text/text.less +1 -2
- package/src/client/assets/css/utils/layouts.less +8 -0
- package/src/client/components/Form.ts +7 -1
- package/src/client/components/Select/index.tsx +14 -2
- package/src/client/components/Table/index.tsx +56 -80
- package/src/client/components/containers/Popover/index.tsx +2 -2
- package/src/client/components/input/Checkbox/index.tsx +6 -4
- package/src/client/components/inputv3/date/Calendar.css +156 -0
- package/src/client/components/inputv3/date/Clock.css +62 -0
- package/src/client/components/inputv3/date/DateTimePicker.css +132 -0
- package/src/client/components/inputv3/date/index.tsx +9 -9
- package/src/client/components/inputv3/index.tsx +36 -38
- package/src/client/services/router/index.tsx +3 -2
- package/src/client/services/router/request/api.ts +27 -10
- package/src/client/services/router/request/index.ts +0 -8
- package/src/common/router/layouts.ts +3 -2
- package/src/common/validation/schema.ts +2 -5
- package/src/common/validation/validators.ts +5 -6
- package/src/server/services/database/index.ts +2 -2
- package/src/server/services/router/response/index.ts +0 -0
- package/src/server/services/router/response/page/document.tsx +4 -6
- package/src/client/assets/fonts/Inter.zip +0 -0
- package/src/client/assets/fonts/Lato/index.less +0 -71
- package/src/client/assets/fonts/Lato/latin-400.woff2 +0 -0
- package/src/client/assets/fonts/Lato/latin-700.woff2 +0 -0
- package/src/client/assets/fonts/Lato/latin-900.woff2 +0 -0
- package/src/client/assets/fonts/Lato/latin-ext-400.woff2 +0 -0
- package/src/client/assets/fonts/Lato/latin-ext-700.woff2 +0 -0
- package/src/client/assets/fonts/Lato/latin-ext-900.woff2 +0 -0
- package/src/client/assets/fonts/Oswald.zip +0 -0
- package/src/client/components/inputv3/date/react-calendar.less +0 -143
- package/src/client/components/inputv3/date/react-daterange-picker.less +0 -112
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
.react-clock {
|
|
2
|
+
display: block;
|
|
3
|
+
position: relative;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.react-clock,
|
|
7
|
+
.react-clock *,
|
|
8
|
+
.react-clock *:before,
|
|
9
|
+
.react-clock *:after {
|
|
10
|
+
-moz-box-sizing: border-box;
|
|
11
|
+
-webkit-box-sizing: border-box;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.react-clock__face {
|
|
16
|
+
position: absolute;
|
|
17
|
+
top: 0;
|
|
18
|
+
bottom: 0;
|
|
19
|
+
left: 0;
|
|
20
|
+
right: 0;
|
|
21
|
+
border: 1px solid black;
|
|
22
|
+
border-radius: 50%;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.react-clock__hand {
|
|
26
|
+
position: absolute;
|
|
27
|
+
top: 0;
|
|
28
|
+
bottom: 0;
|
|
29
|
+
left: 50%;
|
|
30
|
+
right: 50%;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.react-clock__hand__body {
|
|
34
|
+
position: absolute;
|
|
35
|
+
background-color: black;
|
|
36
|
+
transform: translateX(-50%);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.react-clock__mark {
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: 0;
|
|
42
|
+
bottom: 0;
|
|
43
|
+
left: 50%;
|
|
44
|
+
right: 50%;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.react-clock__mark__body {
|
|
48
|
+
position: absolute;
|
|
49
|
+
background-color: black;
|
|
50
|
+
transform: translateX(-50%);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.react-clock__mark__number {
|
|
54
|
+
position: absolute;
|
|
55
|
+
left: -40px;
|
|
56
|
+
width: 80px;
|
|
57
|
+
text-align: center;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.react-clock__second-hand__body {
|
|
61
|
+
background-color: red;
|
|
62
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
.react-datetime-picker {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
position: relative;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.react-datetime-picker,
|
|
7
|
+
.react-datetime-picker *,
|
|
8
|
+
.react-datetime-picker *:before,
|
|
9
|
+
.react-datetime-picker *:after {
|
|
10
|
+
-moz-box-sizing: border-box;
|
|
11
|
+
-webkit-box-sizing: border-box;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.react-datetime-picker--disabled {
|
|
16
|
+
background-color: #f0f0f0;
|
|
17
|
+
color: #6d6d6d;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.react-datetime-picker__wrapper {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-grow: 1;
|
|
23
|
+
flex-shrink: 0;
|
|
24
|
+
border: thin solid gray;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.react-datetime-picker__inputGroup {
|
|
28
|
+
min-width: calc(4px + (4px * 3) + 0.54em * 6 + 0.217em * 2);
|
|
29
|
+
flex-grow: 1;
|
|
30
|
+
padding: 0 2px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.react-datetime-picker__inputGroup__divider {
|
|
34
|
+
padding: 1px 0;
|
|
35
|
+
white-space: pre;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.react-datetime-picker__inputGroup__divider,
|
|
39
|
+
.react-datetime-picker__inputGroup__leadingZero {
|
|
40
|
+
display: inline-block;
|
|
41
|
+
font: inherit;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.react-datetime-picker__inputGroup__input {
|
|
45
|
+
min-width: 0.54em;
|
|
46
|
+
height: calc(100% - 2px);
|
|
47
|
+
position: relative;
|
|
48
|
+
padding: 1px;
|
|
49
|
+
border: 0;
|
|
50
|
+
background: none;
|
|
51
|
+
color: currentColor;
|
|
52
|
+
font: inherit;
|
|
53
|
+
box-sizing: content-box;
|
|
54
|
+
-webkit-appearance: textfield;
|
|
55
|
+
-moz-appearance: textfield;
|
|
56
|
+
appearance: textfield;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.react-datetime-picker__inputGroup__input::-webkit-outer-spin-button,
|
|
60
|
+
.react-datetime-picker__inputGroup__input::-webkit-inner-spin-button {
|
|
61
|
+
-webkit-appearance: none;
|
|
62
|
+
-moz-appearance: none;
|
|
63
|
+
appearance: none;
|
|
64
|
+
margin: 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.react-datetime-picker__inputGroup__input:invalid {
|
|
68
|
+
background: rgba(255, 0, 0, 0.1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.react-datetime-picker__inputGroup__input--hasLeadingZero {
|
|
72
|
+
margin-left: -0.54em;
|
|
73
|
+
padding-left: calc(1px + 0.54em);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.react-datetime-picker__inputGroup__amPm {
|
|
77
|
+
font: inherit;
|
|
78
|
+
-webkit-appearance: menulist;
|
|
79
|
+
-moz-appearance: menulist;
|
|
80
|
+
appearance: menulist;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.react-datetime-picker__button {
|
|
84
|
+
border: 0;
|
|
85
|
+
background: transparent;
|
|
86
|
+
padding: 4px 6px;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.react-datetime-picker__button:enabled {
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.react-datetime-picker__button:enabled:hover .react-datetime-picker__button__icon,
|
|
94
|
+
.react-datetime-picker__button:enabled:focus .react-datetime-picker__button__icon {
|
|
95
|
+
stroke: #0078d7;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.react-datetime-picker__button:disabled .react-datetime-picker__button__icon {
|
|
99
|
+
stroke: #6d6d6d;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.react-datetime-picker__button svg {
|
|
103
|
+
display: inherit;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.react-datetime-picker__calendar,
|
|
107
|
+
.react-datetime-picker__clock {
|
|
108
|
+
z-index: 1;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.react-datetime-picker__calendar--closed,
|
|
112
|
+
.react-datetime-picker__clock--closed {
|
|
113
|
+
display: none;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.react-datetime-picker__calendar {
|
|
117
|
+
width: 350px;
|
|
118
|
+
max-width: 100vw;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.react-datetime-picker__calendar .react-calendar {
|
|
122
|
+
border-width: thin;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.react-datetime-picker__clock {
|
|
126
|
+
width: 200px;
|
|
127
|
+
height: 200px;
|
|
128
|
+
max-width: 100vw;
|
|
129
|
+
padding: 25px;
|
|
130
|
+
background-color: white;
|
|
131
|
+
border: thin solid #a0a096;
|
|
132
|
+
}
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
// Npm
|
|
6
6
|
import React from 'react';
|
|
7
|
-
import
|
|
8
|
-
import DateRangePicker from '@wojtekmaj/react-daterange-picker';
|
|
7
|
+
import DateRangePicker, { DateTimePickerProps } from 'react-datetime-picker';
|
|
9
8
|
|
|
10
9
|
// Core
|
|
11
10
|
|
|
@@ -16,9 +15,9 @@ import DateRangePicker from '@wojtekmaj/react-daterange-picker';
|
|
|
16
15
|
----------------------------------*/
|
|
17
16
|
|
|
18
17
|
type TValue = [Date, Date]
|
|
19
|
-
export type Props = {
|
|
20
|
-
value: TValue,
|
|
21
|
-
onChange: StateUpdater<TValue>,
|
|
18
|
+
export type Props = DateTimePickerProps & {
|
|
19
|
+
//value: TValue,
|
|
20
|
+
//onChange: StateUpdater<TValue>,
|
|
22
21
|
placeholder?: string,
|
|
23
22
|
min?: string,
|
|
24
23
|
max?: string
|
|
@@ -27,9 +26,10 @@ export type Props = {
|
|
|
27
26
|
/*----------------------------------
|
|
28
27
|
- COMPOSANT
|
|
29
28
|
----------------------------------*/
|
|
30
|
-
import './
|
|
31
|
-
import './
|
|
32
|
-
|
|
29
|
+
import './DateTimePicker.css';
|
|
30
|
+
import './Calendar.css';
|
|
31
|
+
import './Clock.css';
|
|
32
|
+
export default ({ value, Props, min, max, onChange, ...otherProps }) => {
|
|
33
33
|
|
|
34
34
|
const state = React.useState(false);
|
|
35
35
|
|
|
@@ -43,7 +43,7 @@ export default ({ value, Props, min, max, onChange }) => {
|
|
|
43
43
|
----------------------------------*/
|
|
44
44
|
return (
|
|
45
45
|
<div>
|
|
46
|
-
<DateRangePicker onChange={onChange} value={value || [null, null]} />
|
|
46
|
+
<DateRangePicker {...otherProps} onChange={onChange} value={value || [null, null]} />
|
|
47
47
|
</div>
|
|
48
48
|
)
|
|
49
49
|
}
|
|
@@ -168,44 +168,42 @@ export default ({
|
|
|
168
168
|
/*----------------------------------
|
|
169
169
|
- RENDER
|
|
170
170
|
----------------------------------*/
|
|
171
|
-
return
|
|
172
|
-
<div class=
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
<
|
|
197
|
-
|
|
198
|
-
)}</label>
|
|
199
|
-
</div>
|
|
200
|
-
|
|
201
|
-
{suffix}
|
|
202
|
-
|
|
171
|
+
return <>
|
|
172
|
+
<div class={className} onClick={() => refInput.current?.focus()}>
|
|
173
|
+
|
|
174
|
+
{prefix}
|
|
175
|
+
|
|
176
|
+
<div class="contValue">
|
|
177
|
+
|
|
178
|
+
<Tag {...fieldProps}
|
|
179
|
+
// @ts-ignore: Property 'ref' does not exist on type 'IntrinsicAttributes'
|
|
180
|
+
ref={refInput}
|
|
181
|
+
value={value}
|
|
182
|
+
onFocus={() => setState({ focus: true })}
|
|
183
|
+
onBlur={() => setState({ focus: false })}
|
|
184
|
+
onChange={(e) => updateValue(e.target.value)}
|
|
185
|
+
|
|
186
|
+
onKeyDown={(e: KeyboardEvent) => {
|
|
187
|
+
|
|
188
|
+
if (onPressEnter && e.key === 'Enter' && value !== undefined) {
|
|
189
|
+
commitValue();
|
|
190
|
+
onPressEnter(value)
|
|
191
|
+
}
|
|
192
|
+
}}
|
|
193
|
+
/>
|
|
194
|
+
|
|
195
|
+
<label>{props.title}{required && (
|
|
196
|
+
<span class="fg error"> *</span>
|
|
197
|
+
)}</label>
|
|
203
198
|
</div>
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
</div>
|
|
208
|
-
)}
|
|
199
|
+
|
|
200
|
+
{suffix}
|
|
201
|
+
|
|
209
202
|
</div>
|
|
210
|
-
|
|
203
|
+
{errors?.length && (
|
|
204
|
+
<div class="fg error txt-left">
|
|
205
|
+
{errors.join('. ')}
|
|
206
|
+
</div>
|
|
207
|
+
)}
|
|
208
|
+
</>
|
|
211
209
|
}
|
|
@@ -159,7 +159,7 @@ export default class ClientRouter<
|
|
|
159
159
|
public url = (path: string, params: {} = {}, absolute: boolean = true) =>
|
|
160
160
|
buildUrl(path, params, this.domains, absolute);
|
|
161
161
|
|
|
162
|
-
public go( url: string, data: {}, opt: {
|
|
162
|
+
public go( url: string, data: {} = {}, opt: {
|
|
163
163
|
newTab?: boolean
|
|
164
164
|
} = {}) {
|
|
165
165
|
|
|
@@ -448,7 +448,8 @@ export default class ClientRouter<
|
|
|
448
448
|
// Nor page configurated for this error
|
|
449
449
|
if (route === undefined) {
|
|
450
450
|
console.error(`Error page for http error code ${code} not found.`, this.errors, this.routes);
|
|
451
|
-
|
|
451
|
+
e.http = 404;
|
|
452
|
+
this.app.handleError(e);
|
|
452
453
|
throw new Error(`Error page for http error code ${code} not found.`);
|
|
453
454
|
}
|
|
454
455
|
|
|
@@ -117,11 +117,28 @@ export default class ApiClient implements ApiClientService {
|
|
|
117
117
|
const [method, path, data, options] = args;
|
|
118
118
|
return {
|
|
119
119
|
method, path, data, options,
|
|
120
|
+
|
|
120
121
|
// For async calls: api.post(...).then((data) => ...)
|
|
121
|
-
then: (callback: (data: any) => void) => this.fetchAsync<TData>(...args)
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
then: (callback: (data: any) => void) => this.fetchAsync<TData>(...args)
|
|
123
|
+
.then(callback)
|
|
124
|
+
.catch( e => this.app.handleError(e)),
|
|
125
|
+
|
|
126
|
+
// Default error behavior only if not handled before by the app
|
|
127
|
+
catch: (callback: (data: any) => void) => this.fetchAsync<TData>(...args)
|
|
128
|
+
.catch((e) => {
|
|
129
|
+
try {
|
|
130
|
+
callback(e);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
this.app.handleError(e)
|
|
133
|
+
}
|
|
134
|
+
}),
|
|
135
|
+
|
|
136
|
+
finally: (callback: () => void) => this.fetchAsync<TData>(...args)
|
|
137
|
+
.finally(callback)
|
|
138
|
+
.catch( e => this.app.handleError(e)),
|
|
139
|
+
|
|
124
140
|
run: () => this.fetchAsync<TData>(...args)
|
|
141
|
+
.catch( e => this.app.handleError(e)),
|
|
125
142
|
};
|
|
126
143
|
}
|
|
127
144
|
|
|
@@ -132,10 +149,7 @@ export default class ApiClient implements ApiClientService {
|
|
|
132
149
|
/*if (options?.captcha !== undefined)
|
|
133
150
|
await this.gui.captcha.check(options?.captcha);*/
|
|
134
151
|
|
|
135
|
-
return await this.execute<TData>(method, path, data, options)
|
|
136
|
-
this.app.handleError(e);
|
|
137
|
-
throw e; // Throw to break the loop
|
|
138
|
-
})
|
|
152
|
+
return await this.execute<TData>(method, path, data, options);
|
|
139
153
|
}
|
|
140
154
|
|
|
141
155
|
public async fetchSync(fetchers: TFetcherList, alreadyLoadedData: {}): Promise<TObjetDonnees> {
|
|
@@ -163,6 +177,12 @@ export default class ApiClient implements ApiClientService {
|
|
|
163
177
|
|
|
164
178
|
return data;
|
|
165
179
|
|
|
180
|
+
}).catch(e => {
|
|
181
|
+
|
|
182
|
+
// API Error hook
|
|
183
|
+
this.app.handleError(e);
|
|
184
|
+
|
|
185
|
+
throw e;
|
|
166
186
|
})
|
|
167
187
|
|
|
168
188
|
// Errors will be catched in the caller
|
|
@@ -239,9 +259,6 @@ export default class ApiClient implements ApiClientService {
|
|
|
239
259
|
e.response.data
|
|
240
260
|
);
|
|
241
261
|
|
|
242
|
-
// API Error hook
|
|
243
|
-
this.app.handleError(error, e.response.status);
|
|
244
|
-
|
|
245
262
|
throw error;
|
|
246
263
|
|
|
247
264
|
// Erreur réseau: l'utilisateur n'ets probablement plus connecté à internet
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
// Npm
|
|
6
6
|
import { Location } from 'history';
|
|
7
|
-
import type Bowser from 'bowser';
|
|
8
7
|
|
|
9
8
|
// Core
|
|
10
9
|
import BaseRequest from '@common/router/request';
|
|
@@ -52,11 +51,4 @@ export default class ClientRequest<TRouter extends ClientRouter = ClientRouter>
|
|
|
52
51
|
// Request services
|
|
53
52
|
this.api = new ApiClient(this.app, this);
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
// To move to a service
|
|
57
|
-
public device(): Bowser.Parser.ParsedResult | undefined {
|
|
58
|
-
// We load bowser only when required
|
|
59
|
-
const Bowser = require("bowser");
|
|
60
|
-
return Bowser.parse(window.navigator.userAgent);
|
|
61
|
-
}
|
|
62
54
|
}
|
|
@@ -9,6 +9,7 @@ import type { ClientContext } from '@/client/context';
|
|
|
9
9
|
import type { TRouteOptions } from '.';
|
|
10
10
|
// App
|
|
11
11
|
import internalLayout from '@client/pages/_layout';
|
|
12
|
+
|
|
12
13
|
import layouts from '@/client/pages/**/_layout/index.tsx';
|
|
13
14
|
|
|
14
15
|
/*----------------------------------
|
|
@@ -63,8 +64,8 @@ export const getLayout = (routePath: string, routeOptions?: TRouteOptions): Layo
|
|
|
63
64
|
// Automatic layout via the nearest _layout folder
|
|
64
65
|
for (const layoutPath in layouts)
|
|
65
66
|
if (
|
|
66
|
-
// The layout is nammed
|
|
67
|
-
layoutPath === '
|
|
67
|
+
// The layout is nammed '' when it's at the root (@/client/pages/_layout)
|
|
68
|
+
layoutPath === '' // Root layout
|
|
68
69
|
// Exact match
|
|
69
70
|
|| chunkId === layoutPath
|
|
70
71
|
// Parent
|
|
@@ -102,10 +102,6 @@ export default class Schema<TFields extends TSchemaFields> {
|
|
|
102
102
|
const cheminAstr = cheminA.join('.')
|
|
103
103
|
const valOrigine = dataToValidate[fieldName];
|
|
104
104
|
|
|
105
|
-
// Key not in the input data, we don't create an entry in the output
|
|
106
|
-
if (!( fieldName in dataToValidate))
|
|
107
|
-
continue;
|
|
108
|
-
|
|
109
105
|
// Validation
|
|
110
106
|
try {
|
|
111
107
|
|
|
@@ -117,7 +113,8 @@ export default class Schema<TFields extends TSchemaFields> {
|
|
|
117
113
|
// Exemple: undefinec = suppression fichier | Absende donnée = conservation fihcier actuel
|
|
118
114
|
if (val === EXCLUDE_VALUE)
|
|
119
115
|
opts.debug && console.log(LogPrefix, '[' + cheminA + '] Exclusion demandée');
|
|
120
|
-
|
|
116
|
+
// Key not in the input data, we don't create an entry in the output
|
|
117
|
+
else if (fieldName in dataToValidate)
|
|
121
118
|
output[fieldName] = val;
|
|
122
119
|
|
|
123
120
|
opts.debug && console.log(LogPrefix, '[' + cheminA + ']', valOrigine, '=>', val);
|
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
|
|
5
5
|
// Npm
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from 'validator';
|
|
6
|
+
import trim from 'validator/lib/trim';
|
|
7
|
+
import isISO8601 from 'validator/lib/isISO8601';
|
|
8
|
+
import toDate from 'validator/lib/toDate';
|
|
9
|
+
import isEmail from 'validator/lib/isEmail';
|
|
10
|
+
import isURL from 'validator/lib/isURL';
|
|
12
11
|
|
|
13
12
|
import normalizeUrl, { Options as NormalizeUrlOptions } from 'normalize-url';
|
|
14
13
|
|
|
@@ -279,12 +279,12 @@ export default class SQL extends Service<Config, Hooks, Application, Services> {
|
|
|
279
279
|
public query = this.select;
|
|
280
280
|
|
|
281
281
|
public first = <TRowData extends TObjetDonnees = {}>(query: string, opts: TSelectQueryOptions = {}): Promise<TRowData> =>
|
|
282
|
-
this.
|
|
282
|
+
this.select(query, opts).then((resultatRequetes: any) => {
|
|
283
283
|
return resultatRequetes[0] || null;
|
|
284
284
|
});
|
|
285
285
|
|
|
286
286
|
public firstOrFail = <TRowData extends TObjetDonnees = {}>(query: string, message?: string, opts: TSelectQueryOptions = {}): Promise<TRowData> =>
|
|
287
|
-
this.
|
|
287
|
+
this.select(query, opts).then((resultatRequetes: any) => {
|
|
288
288
|
|
|
289
289
|
if (resultatRequetes.length === 0)
|
|
290
290
|
throw new NotFound(message);
|
|
File without changes
|
|
@@ -30,7 +30,7 @@ export default class DocumentRenderer<TRouter extends Router> {
|
|
|
30
30
|
|
|
31
31
|
public staticDocument() {
|
|
32
32
|
const routesForClient = JSON.stringify( this.router.ssrRoutes );
|
|
33
|
-
return renderToString(
|
|
33
|
+
return '<!doctype html>' + renderToString(
|
|
34
34
|
<html lang="en">
|
|
35
35
|
<head>
|
|
36
36
|
{/* Format */}
|
|
@@ -63,7 +63,7 @@ export default class DocumentRenderer<TRouter extends Router> {
|
|
|
63
63
|
className: [...page.bodyClass].join(' '),
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
return renderToString(
|
|
66
|
+
return '<!doctype html>' + renderToString(
|
|
67
67
|
<html lang="en" {...(page.amp ? { amp: "true" } : {})}>
|
|
68
68
|
<head>
|
|
69
69
|
{/* Format */}
|
|
@@ -114,14 +114,12 @@ export default class DocumentRenderer<TRouter extends Router> {
|
|
|
114
114
|
<meta name="msapplication-TileColor" content={this.app.identity.maincolor} />
|
|
115
115
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
116
116
|
<meta name="apple-mobile-web-app-title" content={this.app.identity.web.title} />
|
|
117
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
|
|
117
118
|
|
|
118
119
|
{/* Identité */}
|
|
119
120
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
120
121
|
<meta name="application-name" content={this.app.identity.web.title} />
|
|
121
122
|
<meta name="type" content="website" />
|
|
122
|
-
{/*app.identity.social?.facebook?.appId && (
|
|
123
|
-
<meta content={app.identity.social?.facebook?.appId} property="fb:appid" />
|
|
124
|
-
)*/}
|
|
125
123
|
|
|
126
124
|
{/* https://stackoverflow.com/questions/48956465/favicon-standard-2019-svg-ico-png-and-dimensions */}
|
|
127
125
|
{/*<link rel="manifest" href={RES['manifest.json']} />*/}
|
|
@@ -139,7 +137,7 @@ export default class DocumentRenderer<TRouter extends Router> {
|
|
|
139
137
|
|
|
140
138
|
private styles( page: Page ) {
|
|
141
139
|
return <>
|
|
142
|
-
<link rel="stylesheet" type="text/css" href="/public/icons.css" />
|
|
140
|
+
<link rel="stylesheet" type="text/css" href={"/public/icons.css?" + BUILD_ID} />
|
|
143
141
|
<link rel="preload" href="/public/client.css" as="style" />
|
|
144
142
|
<link rel="stylesheet" type="text/css" href="/public/client.css" />
|
|
145
143
|
|
|
Binary file
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
/*
|
|
3
|
-
The use of Unicode range subsets and separate files for each stylistic variant of
|
|
4
|
-
the font allows you to define a composite font family that is both faster and more
|
|
5
|
-
efficient to download. Visitors only download the variants and subsets they need,
|
|
6
|
-
and they aren't forced to download subsets that they may never see or use on the page.
|
|
7
|
-
|
|
8
|
-
https://web.dev/reduce-webfont-size/#unicode-range-subsetting
|
|
9
|
-
|
|
10
|
-
Original stylesheet: https://fonts.googleapis.com/css2?family=Rubik:wght@600&display=swap
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/* latin-ext */
|
|
14
|
-
@font-face {
|
|
15
|
-
font-family: 'Lato';
|
|
16
|
-
font-style: normal;
|
|
17
|
-
font-weight: 400;
|
|
18
|
-
font-display: swap;
|
|
19
|
-
src: url(./latin-ext-400.woff2) format('woff2');
|
|
20
|
-
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/* latin */
|
|
24
|
-
@font-face {
|
|
25
|
-
font-family: 'Lato';
|
|
26
|
-
font-style: normal;
|
|
27
|
-
font-weight: 400;
|
|
28
|
-
font-display: swap;
|
|
29
|
-
src: url(./latin-400.woff2) format('woff2');
|
|
30
|
-
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/* latin-ext */
|
|
34
|
-
@font-face {
|
|
35
|
-
font-family: 'Lato';
|
|
36
|
-
font-style: normal;
|
|
37
|
-
font-weight: 700;
|
|
38
|
-
font-display: swap;
|
|
39
|
-
src: url(./latin-ext-700.woff2) format('woff2');
|
|
40
|
-
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/* latin */
|
|
44
|
-
@font-face {
|
|
45
|
-
font-family: 'Lato';
|
|
46
|
-
font-style: normal;
|
|
47
|
-
font-weight: 700;
|
|
48
|
-
font-display: swap;
|
|
49
|
-
src: url(./latin-700.woff2) format('woff2');
|
|
50
|
-
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/* latin-ext */
|
|
54
|
-
@font-face {
|
|
55
|
-
font-family: 'Lato';
|
|
56
|
-
font-style: normal;
|
|
57
|
-
font-weight: 900;
|
|
58
|
-
font-display: swap;
|
|
59
|
-
src: url(./latin-ext-900.woff2) format('woff2');
|
|
60
|
-
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/* latin */
|
|
64
|
-
@font-face {
|
|
65
|
-
font-family: 'Lato';
|
|
66
|
-
font-style: normal;
|
|
67
|
-
font-weight: 900;
|
|
68
|
-
font-display: swap;
|
|
69
|
-
src: url(./latin-900.woff2) format('woff2');
|
|
70
|
-
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
|
71
|
-
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|