@osimatic/helpers-js 1.2.7 → 1.3.0
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/chartjs.js +309 -0
- package/date_time.js +55 -18
- package/duration.js +14 -13
- package/index.js +4 -3
- package/package.json +1 -1
package/chartjs.js
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
class Chartjs {
|
|
2
|
+
static init() {
|
|
3
|
+
if (typeof Chartjs.initialized == 'undefined' || Chartjs.initialized) {
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
Chartjs.initialized = true;
|
|
8
|
+
|
|
9
|
+
const centerTextPlugin = {
|
|
10
|
+
id: 'centerText',
|
|
11
|
+
afterDraw(chart) {
|
|
12
|
+
if (typeof chart.config.options.centerText == 'undefined' || !chart.config.options.centerText.display) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { ctx, chartArea: { width, height } } = chart;
|
|
17
|
+
ctx.save();
|
|
18
|
+
const total = chart.data.datasets[0].data.reduce((a,b) => a+b, 0);
|
|
19
|
+
const label = chart.config.options.centerText.label || '';
|
|
20
|
+
const fontSize = chart.config.options.centerText.fontSize || 16;
|
|
21
|
+
const textColor = chart.config.options.centerText.color || '#333';
|
|
22
|
+
|
|
23
|
+
ctx.font = `bold ${fontSize}px sans-serif`;
|
|
24
|
+
ctx.fillStyle = textColor;
|
|
25
|
+
ctx.textAlign = 'center';
|
|
26
|
+
ctx.textBaseline = 'middle';
|
|
27
|
+
ctx.fillText(`${total}`, width / 2, height / 2);
|
|
28
|
+
if (label) {
|
|
29
|
+
ctx.font = `12px sans-serif`;
|
|
30
|
+
ctx.fillText(label, width / 2, height / 2 + 20);
|
|
31
|
+
}
|
|
32
|
+
ctx.restore();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
Chart.register(centerTextPlugin);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static createStackedChart(chartDiv, chartData, title=null, options={}) {
|
|
40
|
+
chartDiv.empty();
|
|
41
|
+
new Chart(chartDiv.get(0).getContext("2d"), $.extend(true, {}, {
|
|
42
|
+
type: "bar",
|
|
43
|
+
data: {
|
|
44
|
+
labels: chartData.labels,
|
|
45
|
+
datasets: chartData.datasets
|
|
46
|
+
},
|
|
47
|
+
options: {
|
|
48
|
+
responsive: true,
|
|
49
|
+
scales: {
|
|
50
|
+
x: {
|
|
51
|
+
stacked: true
|
|
52
|
+
},
|
|
53
|
+
y: {
|
|
54
|
+
stacked: true,
|
|
55
|
+
beginAtZero: true,
|
|
56
|
+
ticks: {
|
|
57
|
+
precision: 0
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
plugins: {
|
|
62
|
+
title: {
|
|
63
|
+
display: null !== title,
|
|
64
|
+
text: title || '',
|
|
65
|
+
font: { size: 14 },
|
|
66
|
+
color: "#333",
|
|
67
|
+
padding: { top: 10, bottom: 20 }
|
|
68
|
+
},
|
|
69
|
+
legend: {
|
|
70
|
+
position: "bottom",
|
|
71
|
+
labels: {
|
|
72
|
+
usePointStyle: true,
|
|
73
|
+
padding: 15
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
tooltip: {
|
|
77
|
+
callbacks: {
|
|
78
|
+
label: function(context) {
|
|
79
|
+
return `${context.dataset.label}: ${context.parsed.y}`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}, options));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static createBarChart(chartDiv, chartData, title=null, options={}) {
|
|
89
|
+
chartDiv.empty();
|
|
90
|
+
new Chart(chartDiv.get(0).getContext("2d"), $.extend(true, {}, {
|
|
91
|
+
type: "bar",
|
|
92
|
+
data: {
|
|
93
|
+
labels: chartData.labels,
|
|
94
|
+
datasets: chartData.datasets
|
|
95
|
+
},
|
|
96
|
+
options: {
|
|
97
|
+
responsive: false,
|
|
98
|
+
maintainAspectRatio: false,
|
|
99
|
+
aspectRatio: 2,
|
|
100
|
+
scales: {
|
|
101
|
+
x: {
|
|
102
|
+
grid: {
|
|
103
|
+
display: false
|
|
104
|
+
},
|
|
105
|
+
/*ticks: {
|
|
106
|
+
font: { size: 12 }
|
|
107
|
+
}*/
|
|
108
|
+
},
|
|
109
|
+
y: {
|
|
110
|
+
beginAtZero: true,
|
|
111
|
+
ticks: {
|
|
112
|
+
precision: 0
|
|
113
|
+
//stepSize: 10, font: { size: 12 }
|
|
114
|
+
},
|
|
115
|
+
grid: {
|
|
116
|
+
color: "#eee"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
plugins: {
|
|
121
|
+
title: {
|
|
122
|
+
display: null !== title,
|
|
123
|
+
text: title || '',
|
|
124
|
+
font: { size: 14 },
|
|
125
|
+
color: "#333",
|
|
126
|
+
padding: { top: 10, bottom: 20 }
|
|
127
|
+
},
|
|
128
|
+
legend: {
|
|
129
|
+
display: chartData.datasets.length > 1,
|
|
130
|
+
position: "bottom",
|
|
131
|
+
},
|
|
132
|
+
tooltip: {
|
|
133
|
+
callbacks: {
|
|
134
|
+
label: context => context.dataset.label + ' : ' + context.parsed.y
|
|
135
|
+
//label: (context) => `${context.formattedValue} pointages`
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
animation: {
|
|
140
|
+
duration: 1200,
|
|
141
|
+
easing: "easeOutQuart"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}, options));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static createLineChart(chartDiv, chartData, title=null, options={}) {
|
|
148
|
+
Chartjs.init();
|
|
149
|
+
|
|
150
|
+
chartDiv.empty();
|
|
151
|
+
new Chart(chartDiv.get(0).getContext("2d"), $.extend(true, {}, {
|
|
152
|
+
type: "line",
|
|
153
|
+
data: {
|
|
154
|
+
labels: chartData.labels,
|
|
155
|
+
datasets: chartData.datasets
|
|
156
|
+
},
|
|
157
|
+
options: {
|
|
158
|
+
responsive: false,
|
|
159
|
+
maintainAspectRatio: false,
|
|
160
|
+
aspectRatio: 2,
|
|
161
|
+
scales: {
|
|
162
|
+
y: {
|
|
163
|
+
beginAtZero: true,
|
|
164
|
+
ticks: {
|
|
165
|
+
precision: 0
|
|
166
|
+
},
|
|
167
|
+
grid: {
|
|
168
|
+
color: "#eee"
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
x: {
|
|
172
|
+
grid: {
|
|
173
|
+
display: false
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
plugins: {
|
|
178
|
+
title: {
|
|
179
|
+
display: null !== title,
|
|
180
|
+
text: title || '',
|
|
181
|
+
font: { size: 14 },
|
|
182
|
+
color: "#333",
|
|
183
|
+
padding: { top: 10, bottom: 20 }
|
|
184
|
+
},
|
|
185
|
+
legend: {
|
|
186
|
+
display: chartData.datasets.length > 1,
|
|
187
|
+
position: "bottom",
|
|
188
|
+
},
|
|
189
|
+
tooltip: {
|
|
190
|
+
callbacks: {
|
|
191
|
+
label: context => context.dataset.label + ' : ' + context.parsed.y
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}, options));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
static createDoughnutChart(chartDiv, chartData, title=null, options={}) {
|
|
200
|
+
Chartjs.init();
|
|
201
|
+
|
|
202
|
+
chartDiv.empty();
|
|
203
|
+
new Chart(chartDiv.get(0).getContext("2d"), $.extend(true, {}, {
|
|
204
|
+
type: "doughnut",
|
|
205
|
+
data: {
|
|
206
|
+
labels: chartData.labels,
|
|
207
|
+
datasets: [{
|
|
208
|
+
data: chartData.values,
|
|
209
|
+
backgroundColor: chartData.colors,
|
|
210
|
+
borderWidth: 0,
|
|
211
|
+
hoverOffset: 10
|
|
212
|
+
}]
|
|
213
|
+
},
|
|
214
|
+
options: {
|
|
215
|
+
cutout: "65%",
|
|
216
|
+
responsive: false,
|
|
217
|
+
maintainAspectRatio: false,
|
|
218
|
+
aspectRatio: 2,
|
|
219
|
+
plugins: {
|
|
220
|
+
title: {
|
|
221
|
+
display: null !== title,
|
|
222
|
+
text: title || ''
|
|
223
|
+
},
|
|
224
|
+
legend: {
|
|
225
|
+
position: "right",
|
|
226
|
+
labels: {
|
|
227
|
+
boxWidth: 12,
|
|
228
|
+
font: { size: 12 },
|
|
229
|
+
usePointStyle: true
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
tooltip: {
|
|
233
|
+
callbacks: {
|
|
234
|
+
label: function(context) {
|
|
235
|
+
const total = context.dataset.data.reduce((a,b)=>a+b,0);
|
|
236
|
+
const value = context.raw;
|
|
237
|
+
const percent = ((value / total) * 100).toFixed(1);
|
|
238
|
+
return `${context.label}: ${value} (${percent}%)`;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
animation: {
|
|
244
|
+
animateRotate: true,
|
|
245
|
+
animateScale: true
|
|
246
|
+
},
|
|
247
|
+
centerText: {
|
|
248
|
+
display: false,
|
|
249
|
+
fontSize: 18,
|
|
250
|
+
color: "#000"
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}, options));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
static groupByPeriod(data, period, metrics) {
|
|
257
|
+
const grouped = {};
|
|
258
|
+
|
|
259
|
+
//data = Object.entries(dataObj).map(([date, values]) => ({ date, ...values }));
|
|
260
|
+
|
|
261
|
+
Object.entries(data).forEach(([date, values]) => {
|
|
262
|
+
//data.forEach(entry => {
|
|
263
|
+
const d = new Date(date);
|
|
264
|
+
let key;
|
|
265
|
+
|
|
266
|
+
if (period === 'week') {
|
|
267
|
+
const week = Math.ceil((d.getDate() - d.getDay() + 1) / 7);
|
|
268
|
+
key = `${d.getFullYear()}-S${week}`;
|
|
269
|
+
}
|
|
270
|
+
else if (period === 'month') {
|
|
271
|
+
key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
key = date;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (!grouped[key]) {
|
|
278
|
+
grouped[key] = {};
|
|
279
|
+
metrics.forEach(m => grouped[key][m] = []);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
metrics.forEach(m => {
|
|
283
|
+
if (values[m] !== undefined) grouped[key][m].push(values[m]);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
return Object.entries(grouped).map(([label, vals]) => {
|
|
288
|
+
const aggregated = {};
|
|
289
|
+
metrics.forEach(m => {
|
|
290
|
+
aggregated[m] = vals[m].reduce((a, b) => a + b, 0) / vals[m].length;
|
|
291
|
+
});
|
|
292
|
+
return { label, ...aggregated };
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
static getPeriodLabels(data, period, locale = 'fr-FR', timeZone = 'Europe/Paris') {
|
|
297
|
+
return DatePeriod.getPeriodLabels(Object.keys(data), period, locale, timeZone);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
static getAutoGranularity(data) {
|
|
301
|
+
const dates = Object.keys(data);
|
|
302
|
+
const days = (new Date(dates[dates.length - 1]) - new Date(dates[0])) / (1000 * 60 * 60 * 24);
|
|
303
|
+
if (days > 90) return 'month';
|
|
304
|
+
if (days > 30) return 'week';
|
|
305
|
+
return 'day_of_month';
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
module.exports = { Chartjs };
|
package/date_time.js
CHANGED
|
@@ -121,8 +121,8 @@ class DateTime {
|
|
|
121
121
|
|
|
122
122
|
static getTimeDisplayWithNbDays(jsDate, jsPreviousDate, locale="fr-FR", timeZone="Europe/Paris") {
|
|
123
123
|
let str = this.getTimeDisplay(jsDate, locale, timeZone);
|
|
124
|
-
if (jsPreviousDate
|
|
125
|
-
let nbDaysDiff =
|
|
124
|
+
if (jsPreviousDate !== 0 && jsPreviousDate != null) {
|
|
125
|
+
let nbDaysDiff = DatePeriod.getNbDayBetweenTwo(jsPreviousDate, jsDate, false);
|
|
126
126
|
if (nbDaysDiff > 0) {
|
|
127
127
|
str += ' (J+'+nbDaysDiff+')';
|
|
128
128
|
}
|
|
@@ -238,7 +238,7 @@ class DateTime {
|
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
static isDateEqual(jsDate1, jsDate2) {
|
|
241
|
-
return (jsDate1.getFullYear()
|
|
241
|
+
return (jsDate1.getFullYear() === jsDate2.getFullYear() && jsDate1.getMonth() === jsDate2.getMonth() && jsDate1.getDate() === jsDate2.getDate());
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
static isDateInThePast(jsDate) {
|
|
@@ -277,6 +277,27 @@ class DateTime {
|
|
|
277
277
|
return jsDateTime > today;
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
+
static addDays(date, days) {
|
|
281
|
+
date.setUTCDate(date.getUTCDate() + days);
|
|
282
|
+
return date;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
static addMonths(date, months) {
|
|
286
|
+
let d = date.getDate();
|
|
287
|
+
date.setMonth(date.getMonth() + +months);
|
|
288
|
+
if (date.getDate() !== d) {
|
|
289
|
+
date.setDate(0);
|
|
290
|
+
}
|
|
291
|
+
return date;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/** @deprecated use DatePeriod.getNbDayBetweenTwo instead */
|
|
295
|
+
static getNbDayBetweenTwo(jsDate1, jsDate2, asPeriod=false, timeZone="Europe/Paris") {
|
|
296
|
+
return DatePeriod.getNbDayBetweenTwo(jsDate1, jsDate2, asPeriod, timeZone);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
class DatePeriod {
|
|
280
301
|
static getNbDayBetweenTwo(jsDate1, jsDate2, asPeriod=false, timeZone="Europe/Paris") {
|
|
281
302
|
//jsDate1.set
|
|
282
303
|
if (jsDate1 == null || jsDate2 == null) {
|
|
@@ -299,18 +320,34 @@ class DateTime {
|
|
|
299
320
|
return parseInt(Math.round((timestamp2-timestamp1)/86400));
|
|
300
321
|
}
|
|
301
322
|
|
|
302
|
-
static
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
323
|
+
static getPeriodLabels(data, period, locale = 'fr-FR', timeZone = 'Europe/Paris') {
|
|
324
|
+
if (!data || data.length === 0) {
|
|
325
|
+
return [];
|
|
326
|
+
}
|
|
306
327
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
328
|
+
if (period === 'month') {
|
|
329
|
+
data.map(yearAndMonth => {
|
|
330
|
+
const [year, month] = yearAndMonth.split('-').map(Number);
|
|
331
|
+
return DateTime.getMonthNameByMonth(month, locale).capitalize()+' '+year;
|
|
332
|
+
});
|
|
312
333
|
}
|
|
313
|
-
|
|
334
|
+
if (period === 'week') {
|
|
335
|
+
return data.map(yearAndWeek => {
|
|
336
|
+
const [year, weekStr] = yearAndWeek.split('-S');
|
|
337
|
+
const week = parseInt(weekStr, 10);
|
|
338
|
+
return 'S'+week+' '+year;
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
if (period === 'day_of_week') {
|
|
342
|
+
return data.map(weekDay => DateTime.getDayNameByDayOfWeek(weekDay, locale).capitalize());
|
|
343
|
+
}
|
|
344
|
+
if (period === 'day_of_month') {
|
|
345
|
+
return data.map(sqlDate => SqlDate.getDateDigitalDisplay(sqlDate, locale, timeZone));
|
|
346
|
+
}
|
|
347
|
+
if (period === 'hour') {
|
|
348
|
+
return data.map(hour => String(hour).padStart(2, '0')+'h');
|
|
349
|
+
}
|
|
350
|
+
return data;
|
|
314
351
|
}
|
|
315
352
|
}
|
|
316
353
|
|
|
@@ -386,7 +423,7 @@ class TimestampUnix {
|
|
|
386
423
|
}
|
|
387
424
|
|
|
388
425
|
static getNbDayBetweenTwo(timestamp1, timestamp2, asPeriod=false, timeZone="Europe/Paris") {
|
|
389
|
-
return
|
|
426
|
+
return DatePeriod.getNbDayBetweenTwo(this.parse(timestamp1), this.parse(timestamp2), asPeriod, timeZone);
|
|
390
427
|
}
|
|
391
428
|
|
|
392
429
|
static isDateInThePast(timestamp) {
|
|
@@ -452,7 +489,7 @@ class SqlDate {
|
|
|
452
489
|
return DateTime.isDateInTheFuture(SqlDateTime.parse(sqlDate + " 00:00:00"));
|
|
453
490
|
}
|
|
454
491
|
static getNbDayBetweenTwo(sqlDate1, sqlDate2, asPeriod=false) {
|
|
455
|
-
return
|
|
492
|
+
return DatePeriod.getNbDayBetweenTwo(SqlDateTime.parse(sqlDate1 + " 00:00:00"), SqlDateTime.parse(sqlDate2 + " 00:00:00"), asPeriod);
|
|
456
493
|
}
|
|
457
494
|
}
|
|
458
495
|
|
|
@@ -465,7 +502,7 @@ class SqlTime {
|
|
|
465
502
|
return null;
|
|
466
503
|
}
|
|
467
504
|
|
|
468
|
-
if ((sqlTime.match(/\:/g) || []).length
|
|
505
|
+
if ((sqlTime.match(/\:/g) || []).length === 1) {
|
|
469
506
|
sqlTime += ':00';
|
|
470
507
|
}
|
|
471
508
|
|
|
@@ -585,9 +622,9 @@ class SqlDateTime {
|
|
|
585
622
|
}
|
|
586
623
|
|
|
587
624
|
static getNbDayBetweenTwo(sqlDateTime1, sqlDateTime2, asPeriod=false) {
|
|
588
|
-
return
|
|
625
|
+
return DatePeriod.getNbDayBetweenTwo(this.parse(sqlDateTime1), this.parse(sqlDateTime2), asPeriod);
|
|
589
626
|
}
|
|
590
627
|
|
|
591
628
|
}
|
|
592
629
|
|
|
593
|
-
module.exports = { DateTime, TimestampUnix, SqlDate, SqlTime, SqlDateTime };
|
|
630
|
+
module.exports = { DateTime, DatePeriod, TimestampUnix, SqlDate, SqlTime, SqlDateTime };
|
package/duration.js
CHANGED
|
@@ -51,30 +51,31 @@ class Duration {
|
|
|
51
51
|
return (durationInSecondsOriginal < 0 ? '- ' : '')+hours+':'+minutes+(displayMode==='input_time'?':':'.')+seconds;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
static convertToDurationInHourStringDisplay(durationInSeconds,
|
|
54
|
+
static convertToDurationInHourStringDisplay(durationInSeconds, withSeconds=true, withMinutes=true, withMinuteLabel=true, fullLabel=false, hideHourIfZeroHour=false) {
|
|
55
55
|
durationInSeconds = Math.round(durationInSeconds);
|
|
56
56
|
|
|
57
57
|
// Heures
|
|
58
58
|
let strHeure = '';
|
|
59
59
|
let nbHeures = this.getNbHoursOfDurationInSeconds(durationInSeconds);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
if (!hideHourIfZeroHour || nbHeures > 0) {
|
|
61
|
+
strHeure += nbHeures;
|
|
62
|
+
if (fullLabel) {
|
|
63
|
+
strHeure += ' heure'+(nbHeures>1?'s':'');
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
strHeure += 'h';
|
|
67
|
+
}
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
// Minutes
|
|
69
71
|
let strMinute = '';
|
|
70
|
-
let nbMinutes = 0;
|
|
71
72
|
if (withMinutes) {
|
|
72
|
-
nbMinutes = this.getNbMinutesRemainingOfDurationInSeconds(durationInSeconds);
|
|
73
|
+
let nbMinutes = this.getNbMinutesRemainingOfDurationInSeconds(durationInSeconds);
|
|
73
74
|
strMinute += ' ';
|
|
74
75
|
//strMinute += sprintf('%02d', nbMinutes);
|
|
75
76
|
strMinute += nbMinutes.toString().padStart(2, '0');
|
|
76
|
-
if (
|
|
77
|
-
if (
|
|
77
|
+
if (withMinuteLabel) {
|
|
78
|
+
if (fullLabel) {
|
|
78
79
|
strMinute += ' minute'+(nbMinutes>1?'s':'');
|
|
79
80
|
}
|
|
80
81
|
else {
|
|
@@ -85,12 +86,12 @@ class Duration {
|
|
|
85
86
|
|
|
86
87
|
// Secondes
|
|
87
88
|
let strSeconde = '';
|
|
88
|
-
if (
|
|
89
|
+
if (withSeconds) {
|
|
89
90
|
let nbSecondes = this.getNbSecondsRemainingOfDurationInSeconds(durationInSeconds);
|
|
90
91
|
strSeconde += ' ';
|
|
91
92
|
//strSeconde += sprintf('%02d', nbSecondes);
|
|
92
93
|
strSeconde += nbSecondes.toString().padStart(2, '0');
|
|
93
|
-
if (
|
|
94
|
+
if (fullLabel) {
|
|
94
95
|
strSeconde += ' seconde'+(nbSecondes>1?'s':'');
|
|
95
96
|
}
|
|
96
97
|
else {
|
package/index.js
CHANGED
|
@@ -12,7 +12,7 @@ const { HTTPRequest, Cookie, UrlAndQueryString } = require('./network');
|
|
|
12
12
|
const { IBAN, BankCard } = require('./bank');
|
|
13
13
|
const { AudioMedia, VideoMedia, UserMedia } = require('./media');
|
|
14
14
|
const { PersonName, Email, TelephoneNumber } = require('./contact_details');
|
|
15
|
-
const { DateTime, TimestampUnix, SqlDate, SqlTime, SqlDateTime } = require('./date_time');
|
|
15
|
+
const { DateTime, DatePeriod, TimestampUnix, SqlDate, SqlTime, SqlDateTime } = require('./date_time');
|
|
16
16
|
const { Duration } = require('./duration');
|
|
17
17
|
const { File, CSV, Img } = require('./file');
|
|
18
18
|
const { FormHelper, EditValue } = require('./form_helper');
|
|
@@ -41,6 +41,7 @@ const { WebRTC } = require('./web_rtc');
|
|
|
41
41
|
const { EventBus } = require('./event_bus');
|
|
42
42
|
|
|
43
43
|
// exports surcouche lib externe
|
|
44
|
+
const { Chartjs } = require('./chartjs');
|
|
44
45
|
const { GoogleCharts } = require('./google_charts');
|
|
45
46
|
const { GoogleRecaptcha } = require('./google_recaptcha');
|
|
46
47
|
const { GoogleMap } = require('./google_maps');
|
|
@@ -49,8 +50,8 @@ const { WebSocket } = require('./web_socket');
|
|
|
49
50
|
|
|
50
51
|
module.exports = {
|
|
51
52
|
Array, Object, Number, String,
|
|
52
|
-
HTTPClient, HTTPRequest, Cookie, UrlAndQueryString, IBAN, BankCard, AudioMedia, VideoMedia, UserMedia, PersonName, Email, TelephoneNumber, DateTime, TimestampUnix, SqlDate, SqlTime, SqlDateTime, Duration, File, CSV, Img, FormHelper, Country, PostalAddress, GeographicCoordinates, HexColor, RgbColor, SocialNetwork, NumberFormatter
|
|
53
|
+
HTTPClient, HTTPRequest, Cookie, UrlAndQueryString, IBAN, BankCard, AudioMedia, VideoMedia, UserMedia, PersonName, Email, TelephoneNumber, DateTime, DatePeriod, TimestampUnix, SqlDate, SqlTime, SqlDateTime, Duration, File, CSV, Img, FormHelper, Country, PostalAddress, GeographicCoordinates, HexColor, RgbColor, SocialNetwork, NumberFormatter,
|
|
53
54
|
Browser, DataTable, Pagination, Navigation, DetailsSubArray, SelectAll, MultipleActionInTable, MultipleActionInDivList, EditValue, FormDate, InputPeriod, ShoppingCart, FlashMessage, CountDown, ImportFromCsv, JwtToken, JwtSession, ApiTokenSession, ListBox, WebRTC, WebSocket, EventBus,
|
|
54
55
|
sleep, refresh, chr, ord, trim, empty,
|
|
55
|
-
GoogleCharts, GoogleRecaptcha, GoogleMap, OpenStreetMap
|
|
56
|
+
Chartjs, GoogleCharts, GoogleRecaptcha, GoogleMap, OpenStreetMap
|
|
56
57
|
};
|