weekly quick-entry form (#2793)
This commit is contained in:
@@ -38,6 +38,10 @@ export default class KimaiDateUtils extends KimaiPlugin {
|
||||
return this.formatMomentDuration(duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {moment.Duration} duration
|
||||
* @returns {string|*}
|
||||
*/
|
||||
formatMomentDuration(duration) {
|
||||
const hours = parseInt(duration.asHours()).toString();
|
||||
const minutes = duration.minutes();
|
||||
@@ -58,7 +62,41 @@ export default class KimaiDateUtils extends KimaiPlugin {
|
||||
|
||||
const format = this.getConfiguration('formatDuration');
|
||||
|
||||
return format.replace('%h', hours).replace('%m', ('0'+minutes).substr(-2)).replace('%s', ('0'+seconds).substr(-2));
|
||||
return format.replace('%h', hours).replace('%m', ('0' + minutes).substr(-2)).replace('%s', ('0' + seconds).substr(-2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} duration
|
||||
* @returns {int}
|
||||
*/
|
||||
getSecondsFromDurationString(duration)
|
||||
{
|
||||
duration = duration.trim().toUpperCase();
|
||||
let momentDuration = moment.duration(NaN);
|
||||
|
||||
if (duration.indexOf(':') !== -1) {
|
||||
momentDuration = moment.duration(duration);
|
||||
} else if (duration.indexOf('.') !== -1 || duration.indexOf(',') !== -1) {
|
||||
duration = duration.replace(/,/, '.');
|
||||
duration = (parseFloat(duration) * 3600).toString();
|
||||
momentDuration = moment.duration('PT' + duration + 'S');
|
||||
} else if (duration.indexOf('H') !== -1 || duration.indexOf('M') !== -1 || duration.indexOf('S') !== -1) {
|
||||
/* D for days does not work, because 'PT1H' but with days 'P1D' is used */
|
||||
momentDuration = moment.duration('PT' + duration);
|
||||
} else {
|
||||
let c = parseInt(duration);
|
||||
let d = parseInt(duration).toFixed();
|
||||
if (!isNaN(c) && duration === d) {
|
||||
duration = (c * 3600).toString();
|
||||
momentDuration = moment.duration('PT' + duration + 'S');
|
||||
}
|
||||
}
|
||||
|
||||
if (!momentDuration.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return momentDuration.asSeconds();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,19 +23,21 @@ export default class KimaiFormSelect extends KimaiPlugin {
|
||||
return 'form-select';
|
||||
}
|
||||
|
||||
activateSelectPicker(selector, container) {
|
||||
const elementSelector = this.selector;
|
||||
let options = {};
|
||||
if (container !== undefined) {
|
||||
options = {
|
||||
dropdownParent: $(container),
|
||||
};
|
||||
}
|
||||
init() {
|
||||
// selects the original value inside select2 dropdowns, as the "reset" event (the updated option)
|
||||
// is not automatically catched by select2
|
||||
jQuery('body').on('reset', 'form', function(event) {
|
||||
setTimeout(function() {
|
||||
jQuery(event.target).find(this.selector).trigger('change');
|
||||
}, 10);
|
||||
});
|
||||
|
||||
const self = this;
|
||||
|
||||
// Function to match the name of the parent and not only the names of the children
|
||||
// Based on the original matcher function of Select2: https://github.com/select2/select2/blob/5765090318c4d382ae56463cfa25ba8ca7bdd495/src/js/select2/defaults.js#L272
|
||||
// More information: https://select2.org/searching | https://github.com/select2/docs/blob/develop/pages/11.searching/docs.md
|
||||
function matcher(params, data) {
|
||||
this.matcher = function (params, data) {
|
||||
// Always return the object if there is nothing to compare
|
||||
if (jQuery.trim(params.term) === '') {
|
||||
return data;
|
||||
@@ -86,7 +88,7 @@ export default class KimaiFormSelect extends KimaiPlugin {
|
||||
for (let c = data.children.length - 1; c >= 0; c--) {
|
||||
let child = data.children[c];
|
||||
|
||||
let matches = matcher(newParams, child);
|
||||
let matches = self.matcher(newParams, child);
|
||||
|
||||
// If there wasn't a match, remove the object in the array
|
||||
if (matches === null) {
|
||||
@@ -103,29 +105,42 @@ export default class KimaiFormSelect extends KimaiPlugin {
|
||||
// If the option or its children do not contain the term, don't return anything
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
activateSelectPickerByElement(node, container) {
|
||||
let options = {};
|
||||
if (container !== undefined) {
|
||||
options = {
|
||||
dropdownParent: jQuery(container),
|
||||
};
|
||||
}
|
||||
|
||||
options = {...options, ...{
|
||||
language: this.getConfiguration('locale').replace('_', '-'),
|
||||
theme: "bootstrap",
|
||||
matcher: matcher
|
||||
matcher: this.matcher
|
||||
}};
|
||||
|
||||
const templateResultFunc = function (state) {
|
||||
return jQuery('<span><span style="background-color:'+state.id+'; width: 20px; height: 20px; display: inline-block; margin-right: 10px;"> </span>' + state.text + '</span>');
|
||||
};
|
||||
if (node.dataset['renderer'] !== undefined && node.dataset['renderer'] === 'color') {
|
||||
const templateResultFunc = function (state) {
|
||||
return jQuery('<span><span style="background-color:'+state.id+'; width: 20px; height: 20px; display: inline-block; margin-right: 10px;"> </span>' + state.text + '</span>');
|
||||
};
|
||||
|
||||
let optionsColor = {...options, ...{
|
||||
templateSelection: templateResultFunc,
|
||||
templateResult: templateResultFunc
|
||||
}};
|
||||
const colorOptions = {...options, ...{
|
||||
templateSelection: templateResultFunc,
|
||||
templateResult: templateResultFunc
|
||||
}};
|
||||
|
||||
jQuery(selector + ' ' + elementSelector + ':not([data-renderer=color])').select2(options);
|
||||
jQuery(selector + ' ' + elementSelector + '[data-renderer=color]').select2(optionsColor);
|
||||
jQuery(node).select2(colorOptions);
|
||||
} else {
|
||||
jQuery(node).select2(options);
|
||||
}
|
||||
}
|
||||
|
||||
jQuery('body').on('reset', 'form', function(event){
|
||||
setTimeout(function() {
|
||||
jQuery(event.target).find(elementSelector).trigger('change');
|
||||
}, 10);
|
||||
activateSelectPicker(selector, container) {
|
||||
const self = this;
|
||||
jQuery(selector + ' ' + this.selector).each(function(i, el) {
|
||||
self.activateSelectPickerByElement(el, container);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -40,13 +40,13 @@ export default class KimaiSelectDataAPI extends KimaiPlugin {
|
||||
return;
|
||||
}
|
||||
|
||||
let formPrefix = jQuery(this).parents('form').first().attr('name');
|
||||
let formPrefix = this.dataset['formPrefix'];
|
||||
if (formPrefix === undefined || formPrefix === null) {
|
||||
formPrefix = '';
|
||||
} else {
|
||||
} else if (formPrefix.length > 0) {
|
||||
formPrefix += '_';
|
||||
}
|
||||
|
||||
|
||||
let newApiUrl = self._buildUrlWithFormFields(this.dataset['apiUrl'], formPrefix);
|
||||
|
||||
const selectValue = jQuery(this).val();
|
||||
@@ -74,11 +74,11 @@ export default class KimaiSelectDataAPI extends KimaiPlugin {
|
||||
let newApiUrl = apiUrl;
|
||||
|
||||
apiUrl.split('?')[1].split('&').forEach(item => {
|
||||
let [key, value] = item.split('=');
|
||||
let decoded = decodeURIComponent(value);
|
||||
let test = decoded.match(/%(.*)%/);
|
||||
const [key, value] = item.split('=');
|
||||
const decoded = decodeURIComponent(value);
|
||||
const test = decoded.match(/%(.*)%/);
|
||||
if (test !== null) {
|
||||
let targetField = jQuery('#' + formPrefix + test[1]);
|
||||
const targetField = jQuery('#' + formPrefix + test[1]);
|
||||
let newValue = '';
|
||||
if (targetField.length === 0) {
|
||||
// happens for example:
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
@import "variables";
|
||||
|
||||
table.dataTable.table > tbody > tr > td {
|
||||
vertical-align: middle;
|
||||
@@ -98,6 +99,28 @@ table.dataTable {
|
||||
}
|
||||
}
|
||||
}
|
||||
th.weekend,
|
||||
td.weekend {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
/* order is important, "today” should overwrite "weekend" therefor later in the file */
|
||||
th.today,
|
||||
td.today {
|
||||
background-color: $highlight-today;
|
||||
}
|
||||
th.total,
|
||||
td.total {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
/* Quick entry form */
|
||||
.form-dataTable {
|
||||
table.dataTable {
|
||||
.form-group {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table.table-hover {
|
||||
@@ -108,4 +131,4 @@ table.table-hover {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
.dataTable {
|
||||
.weekend {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
|
||||
.form-reporting .box-header .form-group {
|
||||
margin-right: 10px;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
/* For highlighting rows, fieldsets and so on */
|
||||
$highlight-bg: #f5f5f5;
|
||||
$highlight-today: #fcf8e3;
|
||||
|
||||
/**
|
||||
* BELOW: A simple one to one clone of /node_modules/admin-lte/build/less/variables.less
|
||||
|
||||
Reference in New Issue
Block a user