5htp-core 0.2.5 → 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.
Files changed (33) hide show
  1. package/package.json +5 -4
  2. package/src/client/components/Dialog/Manager.tsx +4 -5
  3. package/src/client/components/Form.ts +88 -36
  4. package/src/client/components/Form_old/index.tsx +17 -17
  5. package/src/client/components/Form_old/index.tsx.old +17 -17
  6. package/src/client/components/Select/ChoiceSelector.tsx +172 -0
  7. package/src/client/components/Select/index.tsx +27 -138
  8. package/src/client/components/containers/Popover/getPosition.ts +14 -11
  9. package/src/client/components/containers/Popover/index.tsx +52 -35
  10. package/src/client/components/containers/Popover/popover.less +7 -1
  11. package/src/client/components/dropdown/index.tsx +1 -1
  12. package/src/client/components/index.ts +2 -1
  13. package/src/client/components/input/Number/index.tsx +2 -2
  14. package/src/client/components/inputv3/date/index.tsx +49 -0
  15. package/src/client/components/inputv3/date/react-calendar.less +143 -0
  16. package/src/client/components/inputv3/date/react-daterange-picker.less +112 -0
  17. package/src/client/components/inputv3/{string/index.tsx → index.tsx} +6 -2
  18. package/src/client/pages/_messages/403.tsx +1 -1
  19. package/src/client/pages/_messages/500.tsx +1 -1
  20. package/src/client/pages/bug.tsx +3 -3
  21. package/src/client/services/router/request/api.ts +0 -5
  22. package/src/client/services/router/request/multipart.ts +120 -9
  23. package/src/client/utils/dom.ts +12 -1
  24. package/src/common/validation/schema.ts +26 -27
  25. package/src/common/validation/validator.ts +14 -5
  26. package/src/server/app/index.ts +10 -1
  27. package/src/server/app/service.ts +1 -0
  28. package/src/server/services/console/index.ts +33 -32
  29. package/src/server/services/database/connection.ts +16 -13
  30. package/src/server/services/router/index.ts +2 -0
  31. package/src/server/services/schema/request.ts +0 -1
  32. package/src/client/components/input/Date/index.less +0 -167
  33. package/src/client/components/input/Date/index.tsx +0 -90
@@ -23,6 +23,8 @@ import logToHTML from './html';
23
23
  type TLogProfile = 'silly' | 'info' | 'warn' | 'error'
24
24
 
25
25
  export type Config = {
26
+ debug?: boolean,
27
+ bufferLimit: number,
26
28
  dev: {
27
29
  level: TLogProfile,
28
30
  },
@@ -77,17 +79,12 @@ export type TQueryLogs = ChannelInfos & {
77
79
  time: number,
78
80
  }
79
81
 
80
- export type TLog = ChannelInfos & {
81
-
82
- }
82
+ export type TLog = ILogObject & ChannelInfos
83
83
 
84
84
  /*----------------------------------
85
85
  - TYPES: BUG REPORT
86
86
  ----------------------------------*/
87
87
  export type ServerBug = {
88
-
89
- type: 'server',
90
-
91
88
  // Context
92
89
  hash: string,
93
90
  date: Date, // Timestamp
@@ -125,7 +122,7 @@ const logFields = [
125
122
  'lineNumber',
126
123
  'argumentsArray',
127
124
  'stack',
128
- ]
125
+ ] as const
129
126
 
130
127
  /*----------------------------------
131
128
  - LOGGER
@@ -186,14 +183,17 @@ export default class Console extends Service<Config, Hooks, Application> {
186
183
  fatal: this.logEntry.bind(this),
187
184
  }, envConfig.level);
188
185
 
189
- setInterval(() => this.clean(), 60000);
186
+ setInterval(() => this.clean(), 10000);
190
187
 
191
188
  // Send email report
192
189
  this.app.on('error', this.createBugReport.bind(this));
193
190
  }
194
191
 
195
192
  private clean() {
196
- // Clean memory from old logs
193
+ this.config.debug && console.log(LogPrefix, `Clean logs buffer. Current size:`, this.logs.length, '/', this.config.bufferLimit);
194
+ const bufferOverflow = this.logs.length - this.config.bufferLimit;
195
+ if (bufferOverflow > 0)
196
+ this.logs = this.logs.slice(bufferOverflow);
197
197
  }
198
198
 
199
199
  /*----------------------------------
@@ -235,9 +235,6 @@ export default class Console extends Service<Config, Hooks, Application> {
235
235
  );
236
236
 
237
237
  const bugReport: ServerBug = {
238
-
239
- type: 'server',
240
-
241
238
  // Context
242
239
  hash: hash,
243
240
  date: now,
@@ -264,6 +261,7 @@ export default class Console extends Service<Config, Hooks, Application> {
264
261
 
265
262
  private logEntry(entry: ILogObject) {
266
263
 
264
+ // Don't keep logs from the admin sashboard
267
265
  const [channelType, channelId] = entry.requestId?.split(':') || ['master'];
268
266
  if (entry.requestId === 'admin')
269
267
  return;
@@ -274,22 +272,6 @@ export default class Console extends Service<Config, Hooks, Application> {
274
272
  for (const k of logFields)
275
273
  miniLog[k] = entry[k];
276
274
 
277
- // remove webpack path
278
- if (miniLog.filePath !== undefined) {
279
-
280
- const appPrefix = '/webpack:/' + this.app.pkg.name + '/src/';
281
- const appPrefixIndex = miniLog.filePath.indexOf(appPrefix);
282
-
283
- const corePrefix = '/webpack:/' + this.app.pkg.name + '/node_modules/5htp-core/src/';
284
- const corePrefixIndex = miniLog.filePath.indexOf(corePrefix);
285
-
286
- if (appPrefixIndex !== -1)
287
- miniLog.filePath = '@/' + miniLog.filePath.substring(appPrefixIndex + appPrefix.length);
288
- else if (corePrefixIndex !== -1)
289
- miniLog.filePath = '@' + miniLog.filePath.substring(corePrefixIndex + corePrefix.length);
290
-
291
- }
292
-
293
275
  this.logs.push(miniLog as TLog);
294
276
  }
295
277
 
@@ -367,11 +349,30 @@ export default class Console extends Service<Config, Hooks, Application> {
367
349
  if (channelId !== undefined)
368
350
  filters.channelId = channelId;
369
351
 
370
- const fromBuffer = this.logs.filter(
371
- e => e.channelId === channelId && e.channelType === channelType
372
- ).reverse();
352
+ const entries: TLog[] = []
353
+ for (const log of this.logs) {
354
+
355
+ // Filters
356
+ if (!(log.channelId === channelId && log.channelType === channelType))
357
+ continue;
358
+
359
+ // Remove path prefixs
360
+ if (log.filePath !== undefined) {
361
+
362
+ const appPrefix = '/webpack:/' + this.app.pkg.name + '/src/';
363
+ const appPrefixIndex = log.filePath.indexOf(appPrefix);
364
+
365
+ const corePrefix = '/webpack:/' + this.app.pkg.name + '/node_modules/5htp-core/src/';
366
+ const corePrefixIndex = log.filePath.indexOf(corePrefix);
367
+
368
+ if (appPrefixIndex !== -1)
369
+ log.filePath = '@/' + log.filePath.substring(appPrefixIndex + appPrefix.length);
370
+ else if (corePrefixIndex !== -1)
371
+ log.filePath = '@' + log.filePath.substring(corePrefixIndex + corePrefix.length);
372
+ }
373
+ }
373
374
 
374
- return this.printHtml(fromBuffer);
375
+ return this.printHtml( entries.reverse() );
375
376
  }
376
377
 
377
378
  public printHtml(logs: TLog[], full: boolean = false): string {
@@ -95,8 +95,8 @@ export default class DatabaseManager extends Service<DatabaseServiceConfig, THoo
95
95
  const connectionErrors: string[] = []
96
96
  for (const connectionConfig of this.config.connections){
97
97
  try {
98
- this.connection = await this.connect(connectionConfig);
99
- this.connectionConfig = connectionConfig;
98
+ await this.connect(connectionConfig)
99
+ break;
100
100
  } catch (error) {
101
101
  console.warn(LogPrefix, `Failed to connect to ${connectionConfig.name}: ` + error);
102
102
  connectionErrors.push(connectionConfig.name + ': ' + error);
@@ -110,9 +110,6 @@ export default class DatabaseManager extends Service<DatabaseServiceConfig, THoo
110
110
  // Disconnect from the database when the app is terminated
111
111
  this.app.on('cleanup', () => this.disconnect());
112
112
 
113
- // Load tables metas
114
- this.tables = await this.metas.load( this.connectionConfig.databases );
115
-
116
113
  // Ready to make queries
117
114
  this.initialized = true;
118
115
  }
@@ -124,16 +121,17 @@ export default class DatabaseManager extends Service<DatabaseServiceConfig, THoo
124
121
  /*----------------------------------
125
122
  - INIT
126
123
  ----------------------------------*/
127
- public async connect({ name, databases, host, login, password, port }: ConnectionConfig) {
128
- console.info(LogPrefix, `Trying to connect to ${name} ...`);
129
- return await mysql.createPool({
124
+ public async connect(config: ConnectionConfig) {
125
+
126
+ console.info(LogPrefix, `Trying to connect to ${config.name} ...`);
127
+ this.connection = mysql.createPool({
130
128
 
131
129
  // Identification
132
- host: host,
133
- port: port,
134
- user: login,
135
- password: password,
136
- database: databases[0],
130
+ host: config.host,
131
+ port: config.port,
132
+ user: config.login,
133
+ password: config.password,
134
+ database: config.databases[0],
137
135
 
138
136
  // Pool
139
137
  waitForConnections: true,
@@ -159,6 +157,11 @@ export default class DatabaseManager extends Service<DatabaseServiceConfig, THoo
159
157
  return query;
160
158
  }
161
159
  })
160
+
161
+ this.connectionConfig = config;
162
+
163
+ this.tables = await this.metas.load( config.databases );
164
+ console.info(LogPrefix, `Successfully connected to ${config.name}.`);
162
165
  }
163
166
 
164
167
  private typeCast( field: mysql.Field, next: Function ) {
@@ -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.";
@@ -54,7 +54,6 @@ export default class RequestValidator extends ServerSchemaValidator implements R
54
54
  {
55
55
  debug: this.config.debug,
56
56
  throwError: true,
57
- validateAll: true,
58
57
  validateDeps: false
59
58
  },
60
59
  []
@@ -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
- })