weekly quick-entry form (#2793)

This commit is contained in:
Kevin Papst
2021-10-18 11:12:46 +02:00
committed by GitHub
parent 64893e0a95
commit 9ab098af86
105 changed files with 3356 additions and 778 deletions

View File

@@ -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();
}
}

View File

@@ -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;">&nbsp;</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;">&nbsp;</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);
});
}

View File

@@ -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:

View File

@@ -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 {
}
}
}
}
}

View File

@@ -1,8 +1,3 @@
.dataTable {
.weekend {
background-color: #f9f9f9;
}
}
.form-reporting .box-header .form-group {
margin-right: 10px;

View File

@@ -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