Format JS code
This commit is contained in:
parent
4752c9306c
commit
9d9211c054
|
@ -2,79 +2,79 @@ const lang = document.documentElement.getAttribute('lang');
|
|||
|
||||
const templateFuture = 'in %value %unit';
|
||||
const templatePast = lang === 'en'
|
||||
? '%value %unit ago'
|
||||
: 'vor %value %unit';
|
||||
? '%value %unit ago'
|
||||
: 'vor %value %unit';
|
||||
|
||||
const yearUnits = lang === 'en'
|
||||
? ['year', 'years']
|
||||
: ['Jahr', 'Jahren'];
|
||||
? ['year', 'years']
|
||||
: ['Jahr', 'Jahren'];
|
||||
|
||||
const monthUnits = lang === 'en'
|
||||
? ['month', 'months']
|
||||
: ['Monat', 'Monaten'];
|
||||
? ['month', 'months']
|
||||
: ['Monat', 'Monaten'];
|
||||
|
||||
const dayUnits = lang === 'en'
|
||||
? ['day', 'days']
|
||||
: ['Tag', 'Tagen'];
|
||||
? ['day', 'days']
|
||||
: ['Tag', 'Tagen'];
|
||||
|
||||
const hourUnits = lang === 'en'
|
||||
? ['hour', 'hours']
|
||||
: ['Stunde', 'Stunden'];
|
||||
? ['hour', 'hours']
|
||||
: ['Stunde', 'Stunden'];
|
||||
|
||||
const minuteUnits = lang === 'en'
|
||||
? ['minute', 'minutes']
|
||||
: ['Minute', 'Minuten'];
|
||||
? ['minute', 'minutes']
|
||||
: ['Minute', 'Minuten'];
|
||||
|
||||
const secondUnits = lang === 'en'
|
||||
? ['second', 'seconds']
|
||||
: ['Sekunde', 'Sekunden'];
|
||||
? ['second', 'seconds']
|
||||
: ['Sekunde', 'Sekunden'];
|
||||
|
||||
const nowString = lang === 'en' ? 'now' : 'jetzt';
|
||||
|
||||
const secondsHour = 60 * 60;
|
||||
|
||||
const timeFrames = [
|
||||
[365 * 24 * 60 * 60, yearUnits],
|
||||
[30 * 24 * 60 * 60, monthUnits],
|
||||
[24 * 60 * 60, dayUnits],
|
||||
[secondsHour, hourUnits],
|
||||
[60, minuteUnits],
|
||||
[1, secondUnits],
|
||||
[365 * 24 * 60 * 60, yearUnits],
|
||||
[30 * 24 * 60 * 60, monthUnits],
|
||||
[24 * 60 * 60, dayUnits],
|
||||
[secondsHour, hourUnits],
|
||||
[60, minuteUnits],
|
||||
[1, secondUnits],
|
||||
];
|
||||
|
||||
function formatFromNow(timestamp) {
|
||||
const now = Date.now() / 1000;
|
||||
const diff = Math.abs(timestamp - now);
|
||||
const ago = now > timestamp;
|
||||
const now = Date.now() / 1000;
|
||||
const diff = Math.abs(timestamp - now);
|
||||
const ago = now > timestamp;
|
||||
|
||||
for (const [duration, [singular, plural]] of timeFrames) {
|
||||
const value = diff < secondsHour
|
||||
? Math.floor(diff / duration)
|
||||
: Math.round(diff / duration);
|
||||
for (const [duration, [singular, plural]] of timeFrames) {
|
||||
const value = diff < secondsHour
|
||||
? Math.floor(diff / duration)
|
||||
: Math.round(diff / duration);
|
||||
|
||||
if (value) {
|
||||
const template = ago ? templatePast : templateFuture;
|
||||
const unit = value === 1 ? singular : plural;
|
||||
return template
|
||||
.replace('%value', value)
|
||||
.replace('%unit', unit);
|
||||
}
|
||||
if (value) {
|
||||
const template = ago ? templatePast : templateFuture;
|
||||
const unit = value === 1 ? singular : plural;
|
||||
return template
|
||||
.replace('%value', value)
|
||||
.replace('%unit', unit);
|
||||
}
|
||||
}
|
||||
|
||||
return nowString;
|
||||
return nowString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises all countdown fields on the page.
|
||||
*/
|
||||
$(function () {
|
||||
$.each($('[data-countdown-ts]'), function (i, e) {
|
||||
const span = $(e);
|
||||
const timestamp = span.data('countdown-ts');
|
||||
const text = span.html();
|
||||
span.html(text.replace('%c', formatFromNow(timestamp)));
|
||||
setInterval(function () {
|
||||
span.html(text.replace('%c', formatFromNow(timestamp)));
|
||||
}, 1000);
|
||||
});
|
||||
$.each($('[data-countdown-ts]'), function (i, e) {
|
||||
const span = $(e);
|
||||
const timestamp = span.data('countdown-ts');
|
||||
const text = span.html();
|
||||
span.html(text.replace('%c', formatFromNow(timestamp)));
|
||||
setInterval(function () {
|
||||
span.html(text.replace('%c', formatFromNow(timestamp)));
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
* @returns {string|undefined} Formatted time or undefined for non-Date
|
||||
*/
|
||||
export const formatTime = (date) => {
|
||||
if (!date instanceof Date) return;
|
||||
if (!date instanceof Date) return;
|
||||
|
||||
return String(date.getHours()).padStart(2, '0') + ':'
|
||||
return String(date.getHours()).padStart(2, '0') + ':'
|
||||
+ String(date.getMinutes()).padStart(2, '0');
|
||||
}
|
||||
|
||||
|
@ -18,9 +18,9 @@ export const formatTime = (date) => {
|
|||
* @returns {string|undefined} Formatted date or undefined for non-Date
|
||||
*/
|
||||
export const formatDay = (date) => {
|
||||
if (!date instanceof Date) return;
|
||||
if (!date instanceof Date) return;
|
||||
|
||||
return String(date.getFullYear()) + '-'
|
||||
return String(date.getFullYear()) + '-'
|
||||
+ String(date.getMonth() + 1).padStart(2, '0') + '-'
|
||||
+ String(date.getDate()).padStart(2, '0');
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import { formatDay, formatTime } from './date';
|
|||
* @param {boolean} checked True if the checkboxes should be checked
|
||||
*/
|
||||
global.checkAll = (id, checked) => {
|
||||
$('#' + id + ' input[type="checkbox"]').each(function () {
|
||||
this.checked = checked;
|
||||
});
|
||||
$('#' + id + ' input[type="checkbox"]').each(function () {
|
||||
this.checked = checked;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -20,9 +20,9 @@ global.checkAll = (id, checked) => {
|
|||
* @param {list} shiftsList A list of numbers
|
||||
*/
|
||||
global.checkOwnTypes = (id, shiftsList) => {
|
||||
$('#' + id + ' input[type="checkbox"]').each(function () {
|
||||
this.checked = $.inArray(parseInt(this.value), shiftsList) != -1;
|
||||
});
|
||||
$('#' + id + ' input[type="checkbox"]').each(function () {
|
||||
this.checked = $.inArray(parseInt(this.value), shiftsList) != -1;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -36,63 +36,63 @@ global.checkOwnTypes = (id, shiftsList) => {
|
|||
* @param {Date} to
|
||||
*/
|
||||
global.setInput = (from, to) => {
|
||||
const fromDay = $('#start_day');
|
||||
const fromTime = $('#start_time');
|
||||
const toDay = $('#end_day');
|
||||
const toTime = $('#end_time');
|
||||
const fromDay = $('#start_day');
|
||||
const fromTime = $('#start_time');
|
||||
const toDay = $('#end_day');
|
||||
const toTime = $('#end_time');
|
||||
|
||||
if (!fromDay || !fromTime || !toDay || !toTime) {
|
||||
console.warn('cannot set input date because of missing field');
|
||||
return;
|
||||
}
|
||||
if (!fromDay || !fromTime || !toDay || !toTime) {
|
||||
console.warn('cannot set input date because of missing field');
|
||||
return;
|
||||
}
|
||||
|
||||
fromDay.val(formatDay(from)).trigger('change');
|
||||
fromTime.val(formatTime(from));
|
||||
fromDay.val(formatDay(from)).trigger('change');
|
||||
fromTime.val(formatTime(from));
|
||||
|
||||
toDay.val(formatDay(to)).trigger('change');
|
||||
toTime.val(formatTime(to));
|
||||
toDay.val(formatDay(to)).trigger('change');
|
||||
toTime.val(formatTime(to));
|
||||
};
|
||||
|
||||
global.setDay = (days) => {
|
||||
days = days || 0;
|
||||
days = days || 0;
|
||||
|
||||
const from = new Date();
|
||||
from.setHours(0, 0, 0, 0);
|
||||
const from = new Date();
|
||||
from.setHours(0, 0, 0, 0);
|
||||
|
||||
// add days, Date handles the overflow
|
||||
from.setDate(from.getDate() + days);
|
||||
// add days, Date handles the overflow
|
||||
from.setDate(from.getDate() + days);
|
||||
|
||||
const to = new Date(from);
|
||||
to.setHours(23, 59);
|
||||
const to = new Date(from);
|
||||
to.setHours(23, 59);
|
||||
|
||||
setInput(from, to);
|
||||
setInput(from, to);
|
||||
};
|
||||
|
||||
global.setHours = (hours) => {
|
||||
hours = hours || 1;
|
||||
hours = hours || 1;
|
||||
|
||||
const from = new Date();
|
||||
const to = new Date(from);
|
||||
const from = new Date();
|
||||
const to = new Date(from);
|
||||
|
||||
// convert hours to add to milliseconds (60 minutes * 60 seconds * 1000 for milliseconds)
|
||||
const msToAdd = hours * 60 * 60 * 1000;
|
||||
to.setTime(to.getTime() + msToAdd, 'h');
|
||||
if (to < from) {
|
||||
setInput(to, from);
|
||||
return;
|
||||
}
|
||||
// convert hours to add to milliseconds (60 minutes * 60 seconds * 1000 for milliseconds)
|
||||
const msToAdd = hours * 60 * 60 * 1000;
|
||||
to.setTime(to.getTime() + msToAdd, 'h');
|
||||
if (to < from) {
|
||||
setInput(to, from);
|
||||
return;
|
||||
}
|
||||
|
||||
setInput(from, to);
|
||||
setInput(from, to);
|
||||
};
|
||||
|
||||
$(function () {
|
||||
/**
|
||||
/**
|
||||
* Disable every submit button after clicking (to prevent double-clicking)
|
||||
*/
|
||||
$('form').submit(function (ev) {
|
||||
$('input[type="submit"]').prop('readonly', true).addClass('disabled');
|
||||
return true;
|
||||
});
|
||||
$('form').submit(function (ev) {
|
||||
$('input[type="submit"]').prop('readonly', true).addClass('disabled');
|
||||
return true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
@ -100,44 +100,44 @@ $(function () {
|
|||
* Button to set current time in time input fields.
|
||||
*/
|
||||
$(function () {
|
||||
$('.input-group.time').each(function () {
|
||||
const elem = $(this);
|
||||
elem.find('button').on('click', function () {
|
||||
const now = new Date();
|
||||
const input = elem.children('input').first();
|
||||
input.val(formatTime(now));
|
||||
const daySelector = $('#' + input.attr('id').replace('time', 'day'));
|
||||
const days = daySelector.children('option');
|
||||
const yyyyMMDD = formatDay(now);
|
||||
days.each(function (i) {
|
||||
if ($(days[i]).val() === yyyyMMDD) {
|
||||
daySelector.val($(days[i]).val());
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
$('.input-group.time').each(function () {
|
||||
const elem = $(this);
|
||||
elem.find('button').on('click', function () {
|
||||
const now = new Date();
|
||||
const input = elem.children('input').first();
|
||||
input.val(formatTime(now));
|
||||
const daySelector = $('#' + input.attr('id').replace('time', 'day'));
|
||||
const days = daySelector.children('option');
|
||||
const yyyyMMDD = formatDay(now);
|
||||
days.each(function (i) {
|
||||
if ($(days[i]).val() === yyyyMMDD) {
|
||||
daySelector.val($(days[i]).val());
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$(function () {
|
||||
$('select').select2({
|
||||
theme: 'bootstrap-5',
|
||||
});
|
||||
$('select').select2({
|
||||
theme: 'bootstrap-5',
|
||||
});
|
||||
})
|
||||
|
||||
/**
|
||||
* Show oauth buttons on welcome title click
|
||||
*/
|
||||
$(function () {
|
||||
$('#welcome-title').on('click', function () {
|
||||
$('.btn-group.btn-group .btn.d-none').removeClass('d-none');
|
||||
});
|
||||
$('#settings-title').on('click', function () {
|
||||
$('.user-settings .nav-item').removeClass('d-none');
|
||||
});
|
||||
$('#oauth-settings-title').on('click', function () {
|
||||
$('table tr.d-none').removeClass('d-none');
|
||||
});
|
||||
$('#welcome-title').on('click', function () {
|
||||
$('.btn-group.btn-group .btn.d-none').removeClass('d-none');
|
||||
});
|
||||
$('#settings-title').on('click', function () {
|
||||
$('.user-settings .nav-item').removeClass('d-none');
|
||||
});
|
||||
$('#oauth-settings-title').on('click', function () {
|
||||
$('table tr.d-none').removeClass('d-none');
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -146,24 +146,24 @@ $(function () {
|
|||
* Uses DOMContentLoaded to prevent flickering
|
||||
*/
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const filter = document.getElementById('collapseShiftsFilterSelect');
|
||||
if (!filter || localStorage.getItem('collapseShiftsFilterSelect') !== 'hidden') {
|
||||
return;
|
||||
}
|
||||
const filter = document.getElementById('collapseShiftsFilterSelect');
|
||||
if (!filter || localStorage.getItem('collapseShiftsFilterSelect') !== 'hidden') {
|
||||
return;
|
||||
}
|
||||
|
||||
filter.classList.remove('show');
|
||||
filter.classList.remove('show');
|
||||
});
|
||||
|
||||
$(() => {
|
||||
if (typeof (localStorage) === 'undefined') {
|
||||
return;
|
||||
}
|
||||
if (typeof (localStorage) === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
const onChange = (e) => {
|
||||
localStorage.setItem('collapseShiftsFilterSelect', e.type);
|
||||
};
|
||||
const onChange = (e) => {
|
||||
localStorage.setItem('collapseShiftsFilterSelect', e.type);
|
||||
};
|
||||
|
||||
$('#collapseShiftsFilterSelect')
|
||||
.on('hidden.bs.collapse', onChange)
|
||||
.on('shown.bs.collapse', onChange);
|
||||
$('#collapseShiftsFilterSelect')
|
||||
.on('hidden.bs.collapse', onChange)
|
||||
.on('shown.bs.collapse', onChange);
|
||||
});
|
||||
|
|
|
@ -2,31 +2,31 @@
|
|||
* Enables the fixed headers and time lane for the shift-calendar and datatables
|
||||
*/
|
||||
$(function () {
|
||||
if ($('.shift-calendar').length) {
|
||||
const timeLanes = $('.shift-calendar .time');
|
||||
const headers = $('.shift-calendar .header');
|
||||
const topReference = $('.container-fluid .row');
|
||||
if ($('.shift-calendar').length) {
|
||||
const timeLanes = $('.shift-calendar .time');
|
||||
const headers = $('.shift-calendar .header');
|
||||
const topReference = $('.container-fluid .row');
|
||||
timeLanes.css({
|
||||
'position': 'relative',
|
||||
'z-index': 999
|
||||
});
|
||||
headers.css({
|
||||
'position': 'relative',
|
||||
'z-index': 900
|
||||
});
|
||||
$(window).scroll(
|
||||
function () {
|
||||
const top = headers.parent().offset().top;
|
||||
const left = 15;
|
||||
timeLanes.css({
|
||||
'position': 'relative',
|
||||
'z-index': 999
|
||||
'left': Math.max(0, $(window).scrollLeft() - left) + 'px'
|
||||
});
|
||||
headers.css({
|
||||
'position': 'relative',
|
||||
'z-index': 900
|
||||
});
|
||||
$(window).scroll(
|
||||
function () {
|
||||
const top = headers.parent().offset().top;
|
||||
const left = 15;
|
||||
timeLanes.css({
|
||||
'left': Math.max(0, $(window).scrollLeft() - left) + 'px'
|
||||
});
|
||||
headers.css({
|
||||
'top': Math.max(0, $(window).scrollTop() - top
|
||||
'top': Math.max(0, $(window).scrollTop() - top
|
||||
- 13
|
||||
+ topReference.offset().top)
|
||||
+ 'px'
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -6,5 +6,5 @@ require('./sticky-headers');
|
|||
require('./countdown');
|
||||
|
||||
$.ajaxSetup({
|
||||
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}
|
||||
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}
|
||||
});
|
||||
|
|
|
@ -28,7 +28,7 @@ const plugins = [
|
|||
let themeFileNameRegex = /theme\d+/;
|
||||
|
||||
if (process.env.THEMES) {
|
||||
themeFileNameRegex = new RegExp(`theme(${process.env.THEMES.replace(/,/g, '|')})\\.`);
|
||||
themeFileNameRegex = new RegExp(`theme(${process.env.THEMES.replace(/,/g, '|')})\\.`);
|
||||
}
|
||||
|
||||
const themePath = path.resolve('resources/assets/themes');
|
||||
|
|
Loading…
Reference in New Issue