5htp-core 0.2.6 → 0.2.7-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/app/index.ts +2 -2
- package/src/client/assets/css/text/icons.less +8 -2
- package/src/client/assets/css/utils/layouts.less +3 -0
- package/src/client/components/Form.ts +2 -2
- package/src/client/components/index.ts +2 -0
- package/src/client/components/input/Checkbox/index.less +0 -0
- package/src/client/components/input/Checkbox/index.tsx +58 -50
- package/src/client/components/input/Checkbox/old.tsx +74 -0
- package/src/client/components/inputv3/base.tsx +13 -1
- 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/pages/useHeader.tsx +3 -2
- package/src/client/services/router/components/router.tsx +3 -2
- package/src/client/services/router/request/api.ts +0 -5
- package/src/client/services/router/request/index.ts +10 -0
- package/src/client/services/router/request/multipart.ts +120 -9
- package/src/server/app/config.ts +2 -0
- package/src/server/app/index.ts +4 -2
- package/src/server/services/console/index.ts +4 -4
- package/src/server/services/fetch/index.ts +1 -1
- package/src/server/services/router/http/index.ts +7 -3
- package/src/server/services/router/index.ts +10 -2
- package/src/server/services/router/response/index.ts +3 -1
- package/src/server/services/router/response/page/document.tsx +7 -19
- package/src/server/services/router/response/page/index.tsx +17 -1
- package/src/server/services/router/service.ts +1 -1
- package/src/types/global/modules.d.ts +1 -1
- package/src/client/components/input/Date/index.less +0 -167
- package/src/client/components/input/Date/index.tsx +0 -90
- package/src/client/services/metrics/index.ts +0 -37
- package/src/server/services/metrics/detect.ts +0 -109
- package/src/server/services/metrics/index.ts +0 -272
|
@@ -55,7 +55,8 @@ export default ({ service: router }: { service: Router }) => {
|
|
|
55
55
|
|
|
56
56
|
// Page not found: Directly load with the browser
|
|
57
57
|
if (newpage === undefined) {
|
|
58
|
-
window.location.replace(request.
|
|
58
|
+
window.location.replace(request.url);
|
|
59
|
+
console.error("not found");
|
|
59
60
|
return;
|
|
60
61
|
// Unable to load (no connection, server error, ....)
|
|
61
62
|
} else if (newpage === null) {
|
|
@@ -86,7 +87,7 @@ export default ({ service: router }: { service: Router }) => {
|
|
|
86
87
|
// But when we call setLayout, the style of the previous layout are still oaded and applied
|
|
87
88
|
// Find a way to unload the previous layout / page resources before to load the new one
|
|
88
89
|
console.log(LogPrefix, `Changing layout. Before:`, curLayout, 'New layout:', newLayout);
|
|
89
|
-
window.location.replace(request.
|
|
90
|
+
window.location.replace(request.url);
|
|
90
91
|
return pages;
|
|
91
92
|
|
|
92
93
|
context.app.setLayout(newLayout);
|
|
@@ -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
|
}
|
|
@@ -27,6 +27,8 @@ export default class ClientRequest<TRouter extends ClientRouter = ClientRouter>
|
|
|
27
27
|
|
|
28
28
|
public api: ApiClient;
|
|
29
29
|
public response?: ClientResponse<TRouter>;
|
|
30
|
+
|
|
31
|
+
public url: string;
|
|
30
32
|
public hash?: string;
|
|
31
33
|
|
|
32
34
|
public constructor(
|
|
@@ -38,8 +40,16 @@ export default class ClientRequest<TRouter extends ClientRouter = ClientRouter>
|
|
|
38
40
|
super(location.pathname);
|
|
39
41
|
|
|
40
42
|
this.host = window.location.host;
|
|
43
|
+
this.url = window.location.protocol + '//' + window.location.host + this.path;
|
|
41
44
|
this.hash = location.hash;
|
|
42
45
|
|
|
46
|
+
// Extract search params
|
|
47
|
+
if (location.search) {
|
|
48
|
+
this.url += location.search;
|
|
49
|
+
this.data = Object.fromEntries( new URLSearchParams( location.search ));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Request services
|
|
43
53
|
this.api = new ApiClient(this.app, this);
|
|
44
54
|
}
|
|
45
55
|
|
|
@@ -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/config.ts
CHANGED
package/src/server/app/index.ts
CHANGED
|
@@ -183,7 +183,7 @@ export default abstract class Application extends Service<Config, Hooks, /* TODO
|
|
|
183
183
|
service.status = 'starting';
|
|
184
184
|
|
|
185
185
|
if (service.register)
|
|
186
|
-
service.register();
|
|
186
|
+
await service.register();
|
|
187
187
|
|
|
188
188
|
// Register commands
|
|
189
189
|
if (service.commands)
|
|
@@ -193,9 +193,11 @@ export default abstract class Application extends Service<Config, Hooks, /* TODO
|
|
|
193
193
|
if (service.start) {
|
|
194
194
|
service.started = service.start();
|
|
195
195
|
await service.started.catch(e => {
|
|
196
|
-
console.error("Catched error while starting service " + serviceClassName + '. Exiting process if mode production.');
|
|
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
|
|
|
@@ -190,10 +190,10 @@ export default class Console extends Service<Config, Hooks, Application> {
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
private clean() {
|
|
193
|
-
this.config.debug && console.log(LogPrefix, `Clean logs buffer. Current size:`, this.logs.length, '/', this.config.bufferLimit);
|
|
193
|
+
/*this.config.debug && console.log(LogPrefix, `Clean logs buffer. Current size:`, this.logs.length, '/', this.config.bufferLimit);
|
|
194
194
|
const bufferOverflow = this.logs.length - this.config.bufferLimit;
|
|
195
195
|
if (bufferOverflow > 0)
|
|
196
|
-
this.logs = this.logs.slice(bufferOverflow)
|
|
196
|
+
this.logs = this.logs.slice(bufferOverflow);*/
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
/*----------------------------------
|
|
@@ -230,7 +230,7 @@ export default class Console extends Service<Config, Hooks, Application> {
|
|
|
230
230
|
// On envoi l'email avant l'insertion dans bla bdd
|
|
231
231
|
// Car cette denrière a plus de chances de provoquer une erreur
|
|
232
232
|
const logsHtml = this.printHtml(
|
|
233
|
-
this.logs
|
|
233
|
+
this.logs/*.filter(e => e.channelId === channelId)*/.slice(-100),
|
|
234
234
|
true
|
|
235
235
|
);
|
|
236
236
|
|
|
@@ -372,7 +372,7 @@ export default class Console extends Service<Config, Hooks, Application> {
|
|
|
372
372
|
}
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
-
return this.printHtml( entries
|
|
375
|
+
return this.printHtml( entries );
|
|
376
376
|
}
|
|
377
377
|
|
|
378
378
|
public printHtml(logs: TLog[], full: boolean = false): string {
|
|
@@ -93,7 +93,7 @@ export default class FetchService extends Service<Config, Hooks, Application> {
|
|
|
93
93
|
|
|
94
94
|
// Convert to webp and finalize
|
|
95
95
|
const processedBuffer = await processing.webp({ quality }).toBuffer().catch(e => {
|
|
96
|
-
console.error(LogPrefix, `Error while processing image at ${
|
|
96
|
+
console.error(LogPrefix, `Error while processing image at ${imageFileUrl}:`, e);
|
|
97
97
|
return null;
|
|
98
98
|
})
|
|
99
99
|
|
|
@@ -43,6 +43,12 @@ export type Config = {
|
|
|
43
43
|
upload: {
|
|
44
44
|
maxSize: string // Expression package bytes
|
|
45
45
|
},
|
|
46
|
+
csp: {
|
|
47
|
+
default?: string[],
|
|
48
|
+
styles?: string[],
|
|
49
|
+
images?: string[],
|
|
50
|
+
scripts: string[],
|
|
51
|
+
}
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
export type Hooks = {
|
|
@@ -193,9 +199,7 @@ export default class HttpServer extends Service<Config, Hooks, Application> {
|
|
|
193
199
|
routes.use( csp.expressCspHeader({
|
|
194
200
|
directives: {
|
|
195
201
|
'script-src': [csp.INLINE, csp.SELF,
|
|
196
|
-
|
|
197
|
-
"https://www.googletagmanager.com/gtag/js",
|
|
198
|
-
"https://cdn.jsdelivr.net"
|
|
202
|
+
...this.config.csp.scripts
|
|
199
203
|
]
|
|
200
204
|
}
|
|
201
205
|
}));
|
|
@@ -282,7 +282,7 @@ export default class ServerRouter<
|
|
|
282
282
|
//await TrackingService.LoadCache();
|
|
283
283
|
|
|
284
284
|
// Generate typescript typings
|
|
285
|
-
if (this.app.env.profile
|
|
285
|
+
if (this.app.env.profile === 'dev')
|
|
286
286
|
this.genTypings();
|
|
287
287
|
|
|
288
288
|
// Ordonne par ordre de priorité
|
|
@@ -468,7 +468,12 @@ declare type Routes = {
|
|
|
468
468
|
|
|
469
469
|
public async resolve(request: ServerRequest<this>): Promise<ServerResponse<this>> {
|
|
470
470
|
|
|
471
|
-
console.info(request.ip, request.method, request.domain, request.path);
|
|
471
|
+
console.info(LogPrefix, request.ip, request.method, request.domain, request.path);
|
|
472
|
+
|
|
473
|
+
if (this.status === 'starting') {
|
|
474
|
+
console.log(LogPrefix, `Waiting for servert to be resdy before resolving request`);
|
|
475
|
+
await this.started;
|
|
476
|
+
}
|
|
472
477
|
|
|
473
478
|
const response = new ServerResponse<this>(request);
|
|
474
479
|
|
|
@@ -545,6 +550,9 @@ declare type Routes = {
|
|
|
545
550
|
// Rapport / debug
|
|
546
551
|
if (code === 500) {
|
|
547
552
|
|
|
553
|
+
// Print the error here so the stacktrace appears in the bug report logs
|
|
554
|
+
console.log(LogPrefix, "Error catched from the router:", e);
|
|
555
|
+
|
|
548
556
|
// Report error
|
|
549
557
|
await this.app.runHook('error', e, request);
|
|
550
558
|
|
|
@@ -133,7 +133,9 @@ export default class ServerResponse<
|
|
|
133
133
|
for (const serviceName in this.router.services) {
|
|
134
134
|
|
|
135
135
|
const routerService = this.router.services[serviceName];
|
|
136
|
-
|
|
136
|
+
const requestService = routerService.requestService( this.request );
|
|
137
|
+
if (requestService !== null)
|
|
138
|
+
contextServices[ serviceName ] = requestService;
|
|
137
139
|
|
|
138
140
|
}
|
|
139
141
|
|
|
@@ -19,10 +19,10 @@ import type Page from '.';
|
|
|
19
19
|
/*----------------------------------
|
|
20
20
|
- SERVICE
|
|
21
21
|
----------------------------------*/
|
|
22
|
-
export default class DocumentRenderer {
|
|
22
|
+
export default class DocumentRenderer<TRouter extends Router> {
|
|
23
23
|
|
|
24
24
|
public constructor(
|
|
25
|
-
public router:
|
|
25
|
+
public router: TRouter,
|
|
26
26
|
public app = router.app
|
|
27
27
|
) {
|
|
28
28
|
|
|
@@ -55,7 +55,7 @@ export default class DocumentRenderer {
|
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
public async page( html: string, page: Page, response: ServerResponse<
|
|
58
|
+
public async page( html: string, page: Page, response: ServerResponse<TRouter> ) {
|
|
59
59
|
|
|
60
60
|
const fullUrl = this.router.http.publicUrl + response.request.path;
|
|
61
61
|
|
|
@@ -133,7 +133,7 @@ export default class DocumentRenderer {
|
|
|
133
133
|
</>
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
private styles( page ) {
|
|
136
|
+
private styles( page: Page ) {
|
|
137
137
|
return <>
|
|
138
138
|
<link rel="stylesheet" type="text/css" href="/public/icons.css" />
|
|
139
139
|
<link rel="preload" href="/public/client.css" as="style" />
|
|
@@ -151,7 +151,7 @@ export default class DocumentRenderer {
|
|
|
151
151
|
</>
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
private async scripts( response
|
|
154
|
+
private async scripts( response: ServerResponse<TRouter>, page: Page ) {
|
|
155
155
|
|
|
156
156
|
const context = safeStringify( response.forSsr(page) );
|
|
157
157
|
|
|
@@ -174,21 +174,9 @@ export default class DocumentRenderer {
|
|
|
174
174
|
<link rel="preload" href={script.url} as="script" />
|
|
175
175
|
<script type="text/javascript" src={script.url} {...script.attrs || {}} />
|
|
176
176
|
</> : <>
|
|
177
|
-
<script type="text/javascript" {...script.attrs || {}} id={script.id}
|
|
177
|
+
<script type="text/javascript" {...script.attrs || {}} id={script.id}
|
|
178
|
+
dangerouslySetInnerHTML={{ __html: script.inline }} />
|
|
178
179
|
</>)}
|
|
179
|
-
|
|
180
|
-
{/* Initialize GTM & GA for pagechange events */}
|
|
181
|
-
{/* TODO: append via the metrics module */}
|
|
182
|
-
{/*<script async src={"https://www.googletagmanager.com/gtag/js?id=" + this.app.config.tracking.ga.pub}></script>
|
|
183
|
-
<script dangerouslySetInnerHTML={{ __html: `
|
|
184
|
-
window.dataLayer = window.dataLayer || [];
|
|
185
|
-
function gtag(){dataLayer.push(arguments);}
|
|
186
|
-
gtag('js', new Date());
|
|
187
|
-
|
|
188
|
-
gtag('config', '${this.app.config.tracking.ga.pub}', {
|
|
189
|
-
send_page_view: false
|
|
190
|
-
});
|
|
191
|
-
`}} />*/}
|
|
192
180
|
</>
|
|
193
181
|
}
|
|
194
182
|
}
|
|
@@ -22,6 +22,11 @@ const chunks = require('./chunk-manifest.json');
|
|
|
22
22
|
- TYPES
|
|
23
23
|
----------------------------------*/
|
|
24
24
|
|
|
25
|
+
const seoLimits = {
|
|
26
|
+
title: 70,
|
|
27
|
+
description: 255
|
|
28
|
+
}
|
|
29
|
+
|
|
25
30
|
/*----------------------------------
|
|
26
31
|
- FONCTION
|
|
27
32
|
----------------------------------*/
|
|
@@ -35,7 +40,8 @@ export default class Page<TRouter extends Router = Router> extends PageResponse<
|
|
|
35
40
|
public layout?: Layout,
|
|
36
41
|
|
|
37
42
|
public route = context.route,
|
|
38
|
-
public
|
|
43
|
+
public app = context.app,
|
|
44
|
+
public router = context.request.router,
|
|
39
45
|
|
|
40
46
|
) {
|
|
41
47
|
|
|
@@ -45,6 +51,16 @@ export default class Page<TRouter extends Router = Router> extends PageResponse<
|
|
|
45
51
|
|
|
46
52
|
public render(): Promise<string> {
|
|
47
53
|
|
|
54
|
+
// Complete SEO metadatas
|
|
55
|
+
const titleSuffix = ' | ' + this.app.identity.web.titleSuffix
|
|
56
|
+
if (this.title === undefined)
|
|
57
|
+
this.title = this.app.identity.web.fullTitle;
|
|
58
|
+
else if (this.title.length < seoLimits.title - titleSuffix.length)
|
|
59
|
+
this.title += titleSuffix;
|
|
60
|
+
|
|
61
|
+
if (this.description === undefined)
|
|
62
|
+
this.description = this.app.identity.web.description;
|
|
63
|
+
|
|
48
64
|
// We render page & document separatly,
|
|
49
65
|
// because document needs to access to runtime assigned values
|
|
50
66
|
// Ex: runtime added scripts, title, metas, ....
|
|
@@ -43,6 +43,6 @@ export default abstract class RouterService<TRouter extends Router = Router> {
|
|
|
43
43
|
|
|
44
44
|
public abstract register(): Promise<void>;
|
|
45
45
|
|
|
46
|
-
public abstract requestService( request: ServerRequest<TRouter> ): RequestService;
|
|
46
|
+
public abstract requestService( request: ServerRequest<TRouter> ): RequestService | null;
|
|
47
47
|
|
|
48
48
|
}
|
|
@@ -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
|
-
}
|