5htp-core 0.2.6-1 → 0.2.6-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 +5 -4
- package/src/client/components/Form.ts +2 -2
- package/src/client/components/index.ts +1 -0
- package/src/client/components/inputv3/date/index.tsx +49 -0
- package/src/client/components/inputv3/date/react-calendar.less +143 -0
- package/src/client/components/inputv3/date/react-daterange-picker.less +112 -0
- package/src/client/services/router/request/api.ts +0 -5
- package/src/client/services/router/request/multipart.ts +120 -9
- package/src/server/app/index.ts +2 -0
- package/src/server/services/router/index.ts +2 -0
- package/src/client/components/input/Date/index.less +0 -167
- package/src/client/components/input/Date/index.tsx +0 -90
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.2.6-
|
|
4
|
+
"version": "0.2.6-2",
|
|
5
5
|
"author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
|
|
6
6
|
"repository": "git://github.com/gaetanlegac/5htp-core.git",
|
|
7
7
|
"license": "MIT",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"framework"
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
|
+
"@wojtekmaj/react-daterange-picker": "^4.2.0",
|
|
16
17
|
"accepts": "^1.3.7",
|
|
17
18
|
"activity-detector": "^3.0.0",
|
|
18
19
|
"ansi-to-html": "^0.7.1",
|
|
@@ -93,7 +94,7 @@
|
|
|
93
94
|
"@types/yargs-parser": "^21.0.0",
|
|
94
95
|
"babel-plugin-glob-import": "^0.0.6-2"
|
|
95
96
|
},
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
"peerDependencies": {
|
|
98
|
+
"5htp": "0.2.3"
|
|
99
|
+
}
|
|
99
100
|
}
|
|
@@ -86,7 +86,7 @@ export default function useForm<TFormData extends {}>(
|
|
|
86
86
|
|
|
87
87
|
// Autosave
|
|
88
88
|
if (options.autoSave !== undefined)
|
|
89
|
-
saveLocally(data, options.autoSave);
|
|
89
|
+
saveLocally(data, options.autoSave.id);
|
|
90
90
|
|
|
91
91
|
}, [data]);
|
|
92
92
|
|
|
@@ -134,7 +134,7 @@ export default function useForm<TFormData extends {}>(
|
|
|
134
134
|
|
|
135
135
|
// Reset autosaved data
|
|
136
136
|
if (options.autoSave)
|
|
137
|
-
localStorage.removeItem(options.autoSave.id);
|
|
137
|
+
localStorage.removeItem('form.' + options.autoSave.id);
|
|
138
138
|
|
|
139
139
|
return submitResult;
|
|
140
140
|
}
|
|
@@ -28,6 +28,7 @@ export { default as CircularProgressbar } from './data/progressbar/circular';
|
|
|
28
28
|
export { default as Select } from './Select';
|
|
29
29
|
export { default as Input } from './inputv3';
|
|
30
30
|
export { default as File } from './inputv3/file';
|
|
31
|
+
export { default as DateRangeInput } from './inputv3/date';
|
|
31
32
|
|
|
32
33
|
// TOD: fix popover component
|
|
33
34
|
//export { default as Date } from './input/Date';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { StateUpdater } from 'preact/hooks';
|
|
8
|
+
import DateRangePicker from '@wojtekmaj/react-daterange-picker/dist/entry.nostyle';
|
|
9
|
+
|
|
10
|
+
// Core
|
|
11
|
+
|
|
12
|
+
// App
|
|
13
|
+
|
|
14
|
+
/*----------------------------------
|
|
15
|
+
- TYPES
|
|
16
|
+
----------------------------------*/
|
|
17
|
+
|
|
18
|
+
type TValue = [Date, Date]
|
|
19
|
+
export type Props = {
|
|
20
|
+
value: TValue,
|
|
21
|
+
onChange: StateUpdater<TValue>,
|
|
22
|
+
placeholder?: string,
|
|
23
|
+
min?: string,
|
|
24
|
+
max?: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/*----------------------------------
|
|
28
|
+
- COMPOSANT
|
|
29
|
+
----------------------------------*/
|
|
30
|
+
import './react-calendar.less';
|
|
31
|
+
import './react-daterange-picker.less';
|
|
32
|
+
export default ({ value, Props, min, max, onChange }) => {
|
|
33
|
+
|
|
34
|
+
const state = React.useState(false);
|
|
35
|
+
|
|
36
|
+
/*----------------------------------
|
|
37
|
+
- CONSTRUCTION CHAMP
|
|
38
|
+
----------------------------------*/
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
/*----------------------------------
|
|
42
|
+
- RENDU DU CHAMP
|
|
43
|
+
----------------------------------*/
|
|
44
|
+
return (
|
|
45
|
+
<div>
|
|
46
|
+
<DateRangePicker onChange={onChange} value={value || [null, null]} />
|
|
47
|
+
</div>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
.react-calendar {
|
|
2
|
+
width: 350px;
|
|
3
|
+
max-width: 100%;
|
|
4
|
+
background: white;
|
|
5
|
+
border: 1px solid #a0a096;
|
|
6
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
7
|
+
line-height: 1.125em;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.react-calendar--doubleView {
|
|
11
|
+
width: 700px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.react-calendar--doubleView .react-calendar__viewContainer {
|
|
15
|
+
display: flex;
|
|
16
|
+
margin: -0.5em;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.react-calendar--doubleView .react-calendar__viewContainer > * {
|
|
20
|
+
width: 50%;
|
|
21
|
+
margin: 0.5em;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.react-calendar,
|
|
25
|
+
.react-calendar *,
|
|
26
|
+
.react-calendar *:before,
|
|
27
|
+
.react-calendar *:after {
|
|
28
|
+
-moz-box-sizing: border-box;
|
|
29
|
+
-webkit-box-sizing: border-box;
|
|
30
|
+
box-sizing: border-box;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.react-calendar button {
|
|
34
|
+
margin: 0;
|
|
35
|
+
border: 0;
|
|
36
|
+
outline: none;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.react-calendar button:enabled:hover {
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.react-calendar__navigation {
|
|
44
|
+
display: flex;
|
|
45
|
+
height: 44px;
|
|
46
|
+
margin-bottom: 1em;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.react-calendar__navigation button {
|
|
50
|
+
min-width: 44px;
|
|
51
|
+
background: none;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.react-calendar__navigation button:disabled {
|
|
55
|
+
background-color: #f0f0f0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.react-calendar__navigation button:enabled:hover,
|
|
59
|
+
.react-calendar__navigation button:enabled:focus {
|
|
60
|
+
background-color: #e6e6e6;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.react-calendar__month-view__weekdays {
|
|
64
|
+
text-align: center;
|
|
65
|
+
text-transform: uppercase;
|
|
66
|
+
font-weight: bold;
|
|
67
|
+
font-size: 0.75em;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.react-calendar__month-view__weekdays__weekday {
|
|
71
|
+
padding: 0.5em;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.react-calendar__month-view__weekNumbers .react-calendar__tile {
|
|
75
|
+
display: flex;
|
|
76
|
+
align-items: center;
|
|
77
|
+
justify-content: center;
|
|
78
|
+
font-size: 0.75em;
|
|
79
|
+
font-weight: bold;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.react-calendar__month-view__days__day--weekend {
|
|
83
|
+
color: #d10000;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.react-calendar__month-view__days__day--neighboringMonth {
|
|
87
|
+
color: #757575;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.react-calendar__year-view .react-calendar__tile,
|
|
91
|
+
.react-calendar__decade-view .react-calendar__tile,
|
|
92
|
+
.react-calendar__century-view .react-calendar__tile {
|
|
93
|
+
padding: 2em 0.5em;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.react-calendar__tile {
|
|
97
|
+
max-width: 100%;
|
|
98
|
+
padding: 10px 6.6667px;
|
|
99
|
+
background: none;
|
|
100
|
+
text-align: center;
|
|
101
|
+
line-height: 16px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.react-calendar__tile:disabled {
|
|
105
|
+
background-color: #f0f0f0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.react-calendar__tile:enabled:hover,
|
|
109
|
+
.react-calendar__tile:enabled:focus {
|
|
110
|
+
background-color: #e6e6e6;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.react-calendar__tile--now {
|
|
114
|
+
background: #ffff76;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.react-calendar__tile--now:enabled:hover,
|
|
118
|
+
.react-calendar__tile--now:enabled:focus {
|
|
119
|
+
background: #ffffa9;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.react-calendar__tile--hasActive {
|
|
123
|
+
background: #76baff;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.react-calendar__tile--hasActive:enabled:hover,
|
|
127
|
+
.react-calendar__tile--hasActive:enabled:focus {
|
|
128
|
+
background: #a9d4ff;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.react-calendar__tile--active {
|
|
132
|
+
background: #006edc;
|
|
133
|
+
color: white;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.react-calendar__tile--active:enabled:hover,
|
|
137
|
+
.react-calendar__tile--active:enabled:focus {
|
|
138
|
+
background: #1087ff;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.react-calendar--selectRange .react-calendar__tile--hover {
|
|
142
|
+
background-color: #e6e6e6;
|
|
143
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
.react-daterange-picker {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
position: relative;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.react-daterange-picker,
|
|
7
|
+
.react-daterange-picker *,
|
|
8
|
+
.react-daterange-picker *:before,
|
|
9
|
+
.react-daterange-picker *:after {
|
|
10
|
+
-moz-box-sizing: border-box;
|
|
11
|
+
-webkit-box-sizing: border-box;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.react-daterange-picker--disabled {
|
|
16
|
+
background-color: #f0f0f0;
|
|
17
|
+
color: #6d6d6d;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.react-daterange-picker__wrapper {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-grow: 1;
|
|
23
|
+
flex-shrink: 0;
|
|
24
|
+
align-items: center;
|
|
25
|
+
border: thin solid gray;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.react-daterange-picker__inputGroup {
|
|
29
|
+
min-width: calc((4px * 3) + 0.54em * 8 + 0.217em * 2);
|
|
30
|
+
height: 100%;
|
|
31
|
+
flex-grow: 1;
|
|
32
|
+
padding: 0 2px;
|
|
33
|
+
box-sizing: content-box;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.react-daterange-picker__inputGroup__divider {
|
|
37
|
+
padding: 1px 0;
|
|
38
|
+
white-space: pre;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.react-daterange-picker__inputGroup__divider,
|
|
42
|
+
.react-daterange-picker__inputGroup__leadingZero {
|
|
43
|
+
display: inline-block;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.react-daterange-picker__inputGroup__input {
|
|
47
|
+
min-width: 0.54em;
|
|
48
|
+
height: 100%;
|
|
49
|
+
position: relative;
|
|
50
|
+
padding: 0 1px;
|
|
51
|
+
border: 0;
|
|
52
|
+
background: none;
|
|
53
|
+
font: inherit;
|
|
54
|
+
box-sizing: content-box;
|
|
55
|
+
-webkit-appearance: textfield;
|
|
56
|
+
-moz-appearance: textfield;
|
|
57
|
+
appearance: textfield;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.react-daterange-picker__inputGroup__input::-webkit-outer-spin-button,
|
|
61
|
+
.react-daterange-picker__inputGroup__input::-webkit-inner-spin-button {
|
|
62
|
+
-webkit-appearance: none;
|
|
63
|
+
-moz-appearance: none;
|
|
64
|
+
appearance: none;
|
|
65
|
+
margin: 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.react-daterange-picker__inputGroup__input:invalid {
|
|
69
|
+
background: rgba(255, 0, 0, 0.1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.react-daterange-picker__inputGroup__input--hasLeadingZero {
|
|
73
|
+
margin-left: -0.54em;
|
|
74
|
+
padding-left: calc(1px + 0.54em);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.react-daterange-picker__button {
|
|
78
|
+
border: 0;
|
|
79
|
+
background: transparent;
|
|
80
|
+
padding: 4px 6px;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.react-daterange-picker__button:enabled {
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.react-daterange-picker__button:enabled:hover .react-daterange-picker__button__icon,
|
|
88
|
+
.react-daterange-picker__button:enabled:focus .react-daterange-picker__button__icon {
|
|
89
|
+
stroke: #0078d7;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.react-daterange-picker__button:disabled .react-daterange-picker__button__icon {
|
|
93
|
+
stroke: #6d6d6d;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.react-daterange-picker__button svg {
|
|
97
|
+
display: inherit;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.react-daterange-picker__calendar {
|
|
101
|
+
width: 350px;
|
|
102
|
+
max-width: 100vw;
|
|
103
|
+
z-index: 1;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.react-daterange-picker__calendar--closed {
|
|
107
|
+
display: none;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.react-daterange-picker__calendar .react-calendar {
|
|
111
|
+
border-width: thin;
|
|
112
|
+
}
|
|
@@ -89,16 +89,11 @@ export default class ApiClient implements ApiClientService {
|
|
|
89
89
|
fetcher.data = { ...(fetcher.data || {}), ...params };
|
|
90
90
|
|
|
91
91
|
console.log("[api][reload]", id, fetcher.method, fetcher.path, fetcher.data);
|
|
92
|
-
const indicator = this.toast.loading("Loading ...");
|
|
93
92
|
|
|
94
93
|
this.fetchAsync(fetcher.method, fetcher.path, fetcher.data).then((data) => {
|
|
95
94
|
|
|
96
95
|
this.set({ [id]: data });
|
|
97
96
|
|
|
98
|
-
}).finally(() => {
|
|
99
|
-
|
|
100
|
-
indicator.close(true);
|
|
101
|
-
|
|
102
97
|
})
|
|
103
98
|
}
|
|
104
99
|
}
|
|
@@ -10,18 +10,129 @@ import { FileToUpload } from '@client/components/inputv3/file';
|
|
|
10
10
|
- TYPES
|
|
11
11
|
----------------------------------*/
|
|
12
12
|
|
|
13
|
+
function mergeObjects(object1, object2) {
|
|
14
|
+
return [object1, object2].reduce(function (carry, objectToMerge) {
|
|
15
|
+
Object.keys(objectToMerge).forEach(function (objectKey) {
|
|
16
|
+
carry[objectKey] = objectToMerge[objectKey];
|
|
17
|
+
});
|
|
18
|
+
return carry;
|
|
19
|
+
}, {});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function isArray(val) {
|
|
23
|
+
|
|
24
|
+
return ({}).toString.call(val) === '[object Array]';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function isJsonObject(val) {
|
|
28
|
+
|
|
29
|
+
return !isArray(val) && typeof val === 'object' && !!val && !(val instanceof Blob) && !(val instanceof Date);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function isAppendFunctionPresent(formData) {
|
|
33
|
+
|
|
34
|
+
return typeof formData.append === 'function';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function isGlobalFormDataPresent() {
|
|
38
|
+
|
|
39
|
+
return typeof FormData === 'function';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getDefaultFormData() {
|
|
43
|
+
|
|
44
|
+
if (isGlobalFormDataPresent()) {
|
|
45
|
+
return new FormData();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function convertRecursively(jsonObject, options, formData, parentKey) {
|
|
50
|
+
|
|
51
|
+
var index = 0;
|
|
52
|
+
|
|
53
|
+
for (var key in jsonObject) {
|
|
54
|
+
|
|
55
|
+
if (jsonObject.hasOwnProperty(key)) {
|
|
56
|
+
|
|
57
|
+
var propName = parentKey || key;
|
|
58
|
+
var value = options.mapping(jsonObject[key]);
|
|
59
|
+
|
|
60
|
+
if (parentKey && isJsonObject(jsonObject)) {
|
|
61
|
+
propName = parentKey + '[' + key + ']';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (parentKey && isArray(jsonObject)) {
|
|
65
|
+
|
|
66
|
+
if (isArray(value) || options.showLeafArrayIndexes ) {
|
|
67
|
+
propName = parentKey + '[' + index + ']';
|
|
68
|
+
} else {
|
|
69
|
+
propName = parentKey + '[]';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Exract the file object from value
|
|
74
|
+
if (typeof value === 'object' && value instanceof FileToUpload)
|
|
75
|
+
value = value.data;
|
|
76
|
+
|
|
77
|
+
if (isArray(value) || isJsonObject(value)) {
|
|
78
|
+
|
|
79
|
+
convertRecursively(value, options, formData, propName);
|
|
80
|
+
|
|
81
|
+
} else if (value instanceof FileList) {
|
|
82
|
+
|
|
83
|
+
for (var j = 0; j < value.length; j++) {
|
|
84
|
+
formData.append(propName + '[' + j + ']', value.item(j));
|
|
85
|
+
}
|
|
86
|
+
} else if (value instanceof Blob) {
|
|
87
|
+
|
|
88
|
+
formData.append(propName, value, value.name);
|
|
89
|
+
|
|
90
|
+
} else if (value instanceof Date) {
|
|
91
|
+
|
|
92
|
+
formData.append(propName, value.toISOString());
|
|
93
|
+
|
|
94
|
+
} else if (((value === null && options.includeNullValues) || value !== null) && value !== undefined) {
|
|
95
|
+
|
|
96
|
+
formData.append(propName, value);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
index++;
|
|
100
|
+
}
|
|
101
|
+
return formData;
|
|
102
|
+
}
|
|
103
|
+
|
|
13
104
|
/*----------------------------------
|
|
14
105
|
- UTILS
|
|
15
106
|
----------------------------------*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
107
|
+
/* Based on https://github.com/hyperatom/json-form-data
|
|
108
|
+
Changes:
|
|
109
|
+
- Add support for FileToUpload
|
|
110
|
+
*/
|
|
111
|
+
export const toMultipart = (jsonObject: TPostData, options) => {
|
|
112
|
+
|
|
113
|
+
if (options && options.initialFormData) {
|
|
114
|
+
|
|
115
|
+
if (!isAppendFunctionPresent(options.initialFormData)) {
|
|
116
|
+
throw 'initialFormData must have an append function.';
|
|
117
|
+
}
|
|
118
|
+
} else if (!isGlobalFormDataPresent()) {
|
|
119
|
+
|
|
120
|
+
throw 'This environment does not have global form data. options.initialFormData must be specified.';
|
|
24
121
|
}
|
|
25
122
|
|
|
26
|
-
|
|
123
|
+
var defaultOptions = {
|
|
124
|
+
initialFormData: getDefaultFormData(),
|
|
125
|
+
showLeafArrayIndexes: true,
|
|
126
|
+
includeNullValues: false,
|
|
127
|
+
mapping: function(value) {
|
|
128
|
+
if (typeof value === 'boolean') {
|
|
129
|
+
return +value ? '1': '0';
|
|
130
|
+
}
|
|
131
|
+
return value;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
var mergedOptions = mergeObjects(defaultOptions, options || {});
|
|
136
|
+
|
|
137
|
+
return convertRecursively(jsonObject, mergedOptions, mergedOptions.initialFormData);
|
|
27
138
|
}
|
package/src/server/app/index.ts
CHANGED
|
@@ -196,6 +196,8 @@ export default abstract class Application extends Service<Config, Hooks, /* TODO
|
|
|
196
196
|
console.error("Catched error while starting service " + serviceClassName + '. Exiting process if mode production.', e);
|
|
197
197
|
if (this.env.profile === 'prod')
|
|
198
198
|
process.exit();
|
|
199
|
+
else
|
|
200
|
+
throw e;
|
|
199
201
|
})
|
|
200
202
|
}
|
|
201
203
|
|
|
@@ -548,6 +548,8 @@ declare type Routes = {
|
|
|
548
548
|
// Report error
|
|
549
549
|
await this.app.runHook('error', e, request);
|
|
550
550
|
|
|
551
|
+
console.log("ERROR 500 VIA ROUTER", e);
|
|
552
|
+
|
|
551
553
|
// Don't exose technical errors to users
|
|
552
554
|
if (this.app.env.profile === 'prod')
|
|
553
555
|
e.message = "We encountered an internal error, and our team has just been notified. Sorry for the inconvenience.";
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
.champ.periode {
|
|
2
|
-
|
|
3
|
-
display: flex;
|
|
4
|
-
|
|
5
|
-
> .input-date {
|
|
6
|
-
|
|
7
|
-
display: flex;
|
|
8
|
-
justify-content: center;
|
|
9
|
-
align-items: center;
|
|
10
|
-
|
|
11
|
-
> input[type=number] {
|
|
12
|
-
-moz-appearance: textfield;
|
|
13
|
-
padding: 0;
|
|
14
|
-
text-align: center;
|
|
15
|
-
|
|
16
|
-
width: 30px;
|
|
17
|
-
&.annee { width: 45px; }
|
|
18
|
-
|
|
19
|
-
&::-webkit-outer-spin-button,
|
|
20
|
-
&::-webkit-inner-spin-button {
|
|
21
|
-
-webkit-appearance: none;
|
|
22
|
-
margin: 0;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// https://github.com/wojtekmaj/react-calendar/blob/master/src/Calendar.less
|
|
30
|
-
.react-calendar {
|
|
31
|
-
|
|
32
|
-
&--doubleView {
|
|
33
|
-
width: 700px;
|
|
34
|
-
|
|
35
|
-
.react-calendar__viewContainer {
|
|
36
|
-
display: flex;
|
|
37
|
-
margin: -.5em;
|
|
38
|
-
|
|
39
|
-
> * {
|
|
40
|
-
width: 50%;
|
|
41
|
-
margin: .5em;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
&, & *, & *:before, & *:after {
|
|
47
|
-
-moz-box-sizing: border-box;
|
|
48
|
-
-webkit-box-sizing: border-box;
|
|
49
|
-
box-sizing: border-box;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
button {
|
|
53
|
-
margin: 0;
|
|
54
|
-
border: 0;
|
|
55
|
-
outline: none;
|
|
56
|
-
border-radius: @radiusBase;
|
|
57
|
-
|
|
58
|
-
&:enabled {
|
|
59
|
-
&:hover {
|
|
60
|
-
cursor: pointer;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
&__navigation {
|
|
66
|
-
height: 40px;
|
|
67
|
-
|
|
68
|
-
button {
|
|
69
|
-
min-width: 44px;
|
|
70
|
-
background: none;
|
|
71
|
-
|
|
72
|
-
&:enabled {
|
|
73
|
-
&:hover, &:focus {
|
|
74
|
-
background-color: var(--cBgControl)
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
&[disabled] {
|
|
79
|
-
color: var(--cTxtDiscret)
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
&__month-view {
|
|
85
|
-
&__weekdays {
|
|
86
|
-
text-align: center;
|
|
87
|
-
text-transform: uppercase;
|
|
88
|
-
font-weight: bold;
|
|
89
|
-
font-size: .75em;
|
|
90
|
-
|
|
91
|
-
&__weekday {
|
|
92
|
-
padding: .5em;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
&__weekNumbers {
|
|
97
|
-
font-weight: bold;
|
|
98
|
-
|
|
99
|
-
.react-calendar__tile {
|
|
100
|
-
display: flex;
|
|
101
|
-
align-items: center;
|
|
102
|
-
justify-content: center;
|
|
103
|
-
font-size: .75em;
|
|
104
|
-
padding: calc(.75em / .75) calc(.5em / .75);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
&__days {
|
|
109
|
-
&__day {
|
|
110
|
-
&--weekend {
|
|
111
|
-
//color: rgb(209, 0, 0);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
&--neighboringMonth {
|
|
115
|
-
color: var(--cTxtDesc)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
&__year-view,
|
|
122
|
-
&__decade-view,
|
|
123
|
-
&__century-view {
|
|
124
|
-
.react-calendar__tile {
|
|
125
|
-
padding: 2em .5em;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
&__tile {
|
|
130
|
-
max-width: 100%;
|
|
131
|
-
text-align: center;
|
|
132
|
-
padding: .75em .5em;
|
|
133
|
-
background: none;
|
|
134
|
-
|
|
135
|
-
&:disabled {
|
|
136
|
-
color: var(--cTxtDiscret)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
&:enabled {
|
|
140
|
-
&:hover, &:focus {
|
|
141
|
-
background-color: var(--cBgControl)
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
&--now {
|
|
146
|
-
font-weight: 700;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
&--hasActive {
|
|
150
|
-
background: var(--cPrincipale);
|
|
151
|
-
color: #fff;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
&--active {
|
|
155
|
-
background: var(--cPrincipale);
|
|
156
|
-
color: #fff;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
&--selectRange {
|
|
161
|
-
.react-calendar__tile {
|
|
162
|
-
&--hover {
|
|
163
|
-
background-color: var(--cBgControl)
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/*----------------------------------
|
|
2
|
-
- DEPENDANCES
|
|
3
|
-
----------------------------------*/
|
|
4
|
-
import React from 'react';
|
|
5
|
-
import Champ from '../Base';
|
|
6
|
-
import dayjs from 'dayjs';
|
|
7
|
-
import Popover from '@client/components/Conteneurs/Popover';
|
|
8
|
-
import Calendar from 'react-calendar';
|
|
9
|
-
|
|
10
|
-
/*----------------------------------
|
|
11
|
-
- TYPES
|
|
12
|
-
----------------------------------*/
|
|
13
|
-
type TValeur = string | Date;
|
|
14
|
-
type TValeurDefaut = Date;
|
|
15
|
-
type TValeurOut = Date;
|
|
16
|
-
const valeurDefaut = undefined;
|
|
17
|
-
|
|
18
|
-
export type Props = {
|
|
19
|
-
valeur: TValeur,
|
|
20
|
-
placeholder?: string,
|
|
21
|
-
min?: string,
|
|
22
|
-
max?: string
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/*----------------------------------
|
|
26
|
-
- COMPOSANT
|
|
27
|
-
----------------------------------*/
|
|
28
|
-
import './index.less';
|
|
29
|
-
export default Champ<Props, TValeurDefaut, TValeurOut>('date', { valeurDefaut }, ({
|
|
30
|
-
// Spread TOUTES les props dont on a besoin pour éviter les problèmes de référence avec props
|
|
31
|
-
prefixe, className, min, max
|
|
32
|
-
}, { state, valeur, setState }, rendre) => {
|
|
33
|
-
|
|
34
|
-
const maintenant = new Date;
|
|
35
|
-
|
|
36
|
-
/* TODO: onchange saisie input = pas de validation
|
|
37
|
-
onchange click calendrier = validation immédiate
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
const [affCalendrier, setAffCalendrier] = React.useState<boolean>(false);
|
|
41
|
-
|
|
42
|
-
const saisieValide = valeur !== undefined && (
|
|
43
|
-
typeof valeur !== 'string' || !isNaN( Date.parse( valeur ) )
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
/*----------------------------------
|
|
47
|
-
- CONSTRUCTION CHAMP
|
|
48
|
-
----------------------------------*/
|
|
49
|
-
if (prefixe === undefined)
|
|
50
|
-
prefixe = <i src="calendar-alt" />;
|
|
51
|
-
|
|
52
|
-
/*----------------------------------
|
|
53
|
-
- RENDU DU CHAMP
|
|
54
|
-
----------------------------------*/
|
|
55
|
-
return rendre(<>
|
|
56
|
-
|
|
57
|
-
<Popover
|
|
58
|
-
afficher={affCalendrier}
|
|
59
|
-
fermer={() => setAffCalendrier(false)}
|
|
60
|
-
interactions
|
|
61
|
-
//{...props}
|
|
62
|
-
className={"bloc input-date" + (className ? ' ' + className : '')}
|
|
63
|
-
width={300}
|
|
64
|
-
content={(
|
|
65
|
-
<div>
|
|
66
|
-
<Calendar
|
|
67
|
-
minDate={min ? new Date(min) : maintenant}
|
|
68
|
-
maxDate={max ? new Date(max) : undefined}
|
|
69
|
-
value={saisieValide ? new Date(valeur) : maintenant}
|
|
70
|
-
showDoubleView={false}
|
|
71
|
-
onChange={(val: Date) => {
|
|
72
|
-
setAffCalendrier(false)
|
|
73
|
-
setState({ valeur: val });
|
|
74
|
-
}}
|
|
75
|
-
/>
|
|
76
|
-
</div>
|
|
77
|
-
)}
|
|
78
|
-
>
|
|
79
|
-
<input
|
|
80
|
-
className="champ"
|
|
81
|
-
value={saisieValide ? dayjs(valeur).format('DD/MM/YYYY') : valeur}
|
|
82
|
-
onChange={(e) => setState({ valeur: e.target.value })}
|
|
83
|
-
onFocus={() => setAffCalendrier(true)}
|
|
84
|
-
placeholder='DD/MM/YYYY'
|
|
85
|
-
readOnly
|
|
86
|
-
/>
|
|
87
|
-
</Popover>
|
|
88
|
-
|
|
89
|
-
</>, { prefixe }); // Les propétés modifiées sont passées ici
|
|
90
|
-
})
|