mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-24 23:58:54 +01:00
WIP timesheet timer
just a prototype for now, no persistence beside the session to test reloads
This commit is contained in:
parent
4d5f9f87f0
commit
3c79bd4345
@ -515,7 +515,6 @@ egw.extend('links', egw.MODULE_GLOBAL, function()
|
||||
{
|
||||
select.dropdown.trigger.style.visibility = 'hidden';
|
||||
select.dropdown.trigger.style.height = '0px';
|
||||
select.querySelector('sl-menu-item[value=""]').style.display = 'none';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -29,4 +29,5 @@ import "./egw_tail.js";
|
||||
import "./egw_inheritance.js";
|
||||
import "./egw_message.js";
|
||||
import "./egw_notification.js";
|
||||
import "./jsapi.js";
|
||||
import "./egw_timer.js";
|
||||
import "./jsapi.js";
|
184
api/js/jsapi/egw_timer.js
Normal file
184
api/js/jsapi/egw_timer.js
Normal file
@ -0,0 +1,184 @@
|
||||
/**
|
||||
* EGroupware clientside API object
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package etemplate
|
||||
* @subpackage api
|
||||
* @link https://www.egroupware.org
|
||||
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||
*/
|
||||
|
||||
import './egw_core.js';
|
||||
import {sprintf} from "../egw_action/egw_action_common";
|
||||
|
||||
egw.extend('timer', egw.MODULE_GLOBAL, function()
|
||||
{
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Timer state
|
||||
*/
|
||||
let timer_start;
|
||||
let timer_offset = 0;
|
||||
let timer_paused = false;
|
||||
|
||||
const timer = document.querySelector('#topmenu_timer');
|
||||
let timer_interval;
|
||||
|
||||
function setState(_state)
|
||||
{
|
||||
timer_start = _state.start ? new Date(_state.start) : undefined;
|
||||
timer_offset = _state.offset || 0;
|
||||
if (timer_offset && timer_start)
|
||||
{
|
||||
timer_start.setMilliseconds(timer_start.getMilliseconds()-timer_offset);
|
||||
}
|
||||
if (timer_start || _state.paused)
|
||||
{
|
||||
startTimer();
|
||||
|
||||
if (_state.paused) stopTimer(true); // sets timer_paused
|
||||
}
|
||||
}
|
||||
|
||||
function getState()
|
||||
{
|
||||
return {
|
||||
start: timer_start,
|
||||
offset: timer_offset,
|
||||
paused: timer_paused
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run timer action eg. start/stop
|
||||
*
|
||||
* @param {string} _action
|
||||
*/
|
||||
function timerAction(_action)
|
||||
{
|
||||
switch(_action)
|
||||
{
|
||||
case 'overall-start':
|
||||
startTimer();
|
||||
break;
|
||||
|
||||
case 'overall-pause':
|
||||
stopTimer(true);
|
||||
break;
|
||||
|
||||
case 'overall-stop':
|
||||
stopTimer();
|
||||
break;
|
||||
}
|
||||
// persist state
|
||||
let state = getState();
|
||||
state.action = _action;
|
||||
egw.request('timesheet.timesheet_bo.ajax_event', [state])
|
||||
}
|
||||
|
||||
function startTimer()
|
||||
{
|
||||
timer_paused = false;
|
||||
timer_start = new Date();
|
||||
if (timer_offset > 0)
|
||||
{
|
||||
timer_start.setMilliseconds(timer_start.getMilliseconds()-timer_offset);
|
||||
}
|
||||
const update = () =>
|
||||
{
|
||||
if (!timer_start)
|
||||
{
|
||||
timer.textContent = '0:00';
|
||||
}
|
||||
else if (timer_paused)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
let diff = Math.round(((new Date()).valueOf() - timer_start.valueOf())/1000.0);
|
||||
const sep = diff % 2 ? ' ' : ':';
|
||||
diff = Math.round(diff / 60.0);
|
||||
timer.textContent = sprintf('%d%s%02d', Math.round(diff/60), sep, diff % 60);
|
||||
}
|
||||
}
|
||||
timer.classList.add('running');
|
||||
timer.classList.remove('paused');
|
||||
update();
|
||||
timer_interval = window.setInterval(update, 1000);
|
||||
}
|
||||
|
||||
function stopTimer(_pause)
|
||||
{
|
||||
if (timer_interval)
|
||||
{
|
||||
window.clearInterval(timer_interval);
|
||||
}
|
||||
timer.classList.remove('running');
|
||||
timer.textContent = timer.textContent.replace(' ', ':');
|
||||
|
||||
if (_pause)
|
||||
{
|
||||
timer.classList.add('paused');
|
||||
timer_paused = true;
|
||||
}
|
||||
timer_offset = (new Date()).valueOf() - timer_start.valueOf();
|
||||
if (!_pause)
|
||||
{
|
||||
timer_start = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Create timer in top-menu
|
||||
*
|
||||
* @param {string} _parent parent to create selectbox in
|
||||
*/
|
||||
add_timer: function(_parent)
|
||||
{
|
||||
const timer_container = document.getElementById(_parent);
|
||||
if (!timer_container) return;
|
||||
|
||||
// set state if given
|
||||
const timer = document.getElementById('topmenu_timer');
|
||||
if (timer && timer.getAttribute('data-state'))
|
||||
{
|
||||
setState(JSON.parse(timer.getAttribute('data-state')));
|
||||
}
|
||||
|
||||
// create selectbox / menu
|
||||
const select = document.createElement('et2-select', {id: 'timer_selectbox'});
|
||||
timer_container.append(select);
|
||||
|
||||
// bind change handler
|
||||
select.addEventListener('change', () =>
|
||||
{
|
||||
if (select.value) timerAction(select.value);
|
||||
select.value = '';
|
||||
});
|
||||
// bind click handler
|
||||
timer_container.addEventListener('click', (ev) =>
|
||||
{
|
||||
select.dropdown.open = !select.dropdown.open ? true : false;
|
||||
ev.stopPropagation();
|
||||
});
|
||||
// need to load timesheet translations for app-names
|
||||
this.langRequire(window, [{app: 'timesheet', lang: this.preference('lang')}], () =>
|
||||
{
|
||||
select.select_options = [
|
||||
{ value:'', label: this.lang('Select one...')},
|
||||
{ value: 'overall-start', label: this.lang('Start working time')},
|
||||
{ value: 'overall-pause', label: this.lang('Pause working time')},
|
||||
{ value: 'overall-stop', label: this.lang('Stop working time')},
|
||||
];
|
||||
select.updateComplete.then(() =>
|
||||
{
|
||||
select.dropdown.trigger.style.visibility = 'hidden';
|
||||
select.dropdown.trigger.style.height = '0px';
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
@ -5268,7 +5268,8 @@ span.overlayContainer img.overlay {
|
||||
Author : stefanreinhardt
|
||||
*/
|
||||
#egw_fw_topmenu_info_items {
|
||||
display: inline-block;
|
||||
display: flex !important;
|
||||
flex-direction: row-reverse;
|
||||
height: 45px;
|
||||
position: absolute;
|
||||
padding-right: 2px;
|
||||
@ -5456,7 +5457,6 @@ span.overlayContainer img.overlay {
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add {
|
||||
position: relative;
|
||||
/* do NOT show empty label */
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add span#quick_add {
|
||||
float: right;
|
||||
@ -5475,23 +5475,71 @@ span.overlayContainer img.overlay {
|
||||
line-height: 0.6em;
|
||||
background-color: white;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer {
|
||||
order: 1;
|
||||
position: relative;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #topmenu_timer {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
top: 10px !important;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
color: #606060;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #topmenu_timer.running {
|
||||
color: black;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url(../../timesheet/templates/default/images/navbar.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 32px;
|
||||
background-position: center center;
|
||||
filter: opacity(0.3);
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox {
|
||||
height: 0px;
|
||||
float: left;
|
||||
display: inline-block;
|
||||
/* do NOT show empty label */
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control-input) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox sl-menu-item[value=""] {
|
||||
display: none;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(form-control-input) {
|
||||
border: none !important;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(form-control) {
|
||||
margin-left: -3em;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(menu) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(menu) {
|
||||
max-height: 60vh;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add et2-select#quick_add_selectbox sl-menu-item[value=""] {
|
||||
display: none;
|
||||
}
|
||||
#egw_fw_topmenu_info_items img#topmenu_info_error {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
@ -5248,7 +5248,8 @@ span.overlayContainer img.overlay {
|
||||
Author : stefanreinhardt
|
||||
*/
|
||||
#egw_fw_topmenu_info_items {
|
||||
display: inline-block;
|
||||
display: flex !important;
|
||||
flex-direction: row-reverse;
|
||||
height: 45px;
|
||||
position: absolute;
|
||||
padding-right: 2px;
|
||||
@ -5436,7 +5437,6 @@ span.overlayContainer img.overlay {
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add {
|
||||
position: relative;
|
||||
/* do NOT show empty label */
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add span#quick_add {
|
||||
float: right;
|
||||
@ -5455,23 +5455,71 @@ span.overlayContainer img.overlay {
|
||||
line-height: 0.6em;
|
||||
background-color: white;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer {
|
||||
order: 1;
|
||||
position: relative;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #topmenu_timer {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
top: 10px !important;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
color: #606060;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #topmenu_timer.running {
|
||||
color: black;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url(../../timesheet/templates/default/images/navbar.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 32px;
|
||||
background-position: center center;
|
||||
filter: opacity(0.3);
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox {
|
||||
height: 0px;
|
||||
float: left;
|
||||
display: inline-block;
|
||||
/* do NOT show empty label */
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control-input) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox sl-menu-item[value=""] {
|
||||
display: none;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(form-control-input) {
|
||||
border: none !important;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(form-control) {
|
||||
margin-left: -3em;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(menu) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(menu) {
|
||||
max-height: 60vh;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add et2-select#quick_add_selectbox sl-menu-item[value=""] {
|
||||
display: none;
|
||||
}
|
||||
#egw_fw_topmenu_info_items img#topmenu_info_error {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
@ -5258,7 +5258,8 @@ span.overlayContainer img.overlay {
|
||||
Author : stefanreinhardt
|
||||
*/
|
||||
#egw_fw_topmenu_info_items {
|
||||
display: inline-block;
|
||||
display: flex !important;
|
||||
flex-direction: row-reverse;
|
||||
height: 45px;
|
||||
position: absolute;
|
||||
padding-right: 2px;
|
||||
@ -5446,7 +5447,6 @@ span.overlayContainer img.overlay {
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add {
|
||||
position: relative;
|
||||
/* do NOT show empty label */
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add span#quick_add {
|
||||
float: right;
|
||||
@ -5465,23 +5465,71 @@ span.overlayContainer img.overlay {
|
||||
line-height: 0.6em;
|
||||
background-color: white;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer {
|
||||
order: 1;
|
||||
position: relative;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #topmenu_timer {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
top: 10px !important;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
color: #606060;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #topmenu_timer.running {
|
||||
color: black;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url(../../timesheet/templates/default/images/navbar.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 32px;
|
||||
background-position: center center;
|
||||
filter: opacity(0.3);
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox {
|
||||
height: 0px;
|
||||
float: left;
|
||||
display: inline-block;
|
||||
/* do NOT show empty label */
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control-input) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox sl-menu-item[value=""] {
|
||||
display: none;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(form-control-input) {
|
||||
border: none !important;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(form-control) {
|
||||
margin-left: -3em;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(menu) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(menu) {
|
||||
max-height: 60vh;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add et2-select#quick_add_selectbox sl-menu-item[value=""] {
|
||||
display: none;
|
||||
}
|
||||
#egw_fw_topmenu_info_items img#topmenu_info_error {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
@ -138,6 +138,7 @@ import './slider.js';
|
||||
.on('change', function() { framework.tzSelection(this.value); return false; })
|
||||
.on('click', function(e) { e.stopPropagation(); });
|
||||
window.egw.link_quick_add('topmenu_info_quick_add');
|
||||
window.egw.add_timer('topmenu_info_timer');
|
||||
|
||||
// allowing javascript urls in topmenu and sidebox only under CSP by binding click handlers to them
|
||||
var href_regexp = /^javascript:([^\(]+)\((.*)?\);?$/;
|
||||
|
@ -19,7 +19,8 @@
|
||||
@import (reference) "definitions.less";
|
||||
|
||||
#egw_fw_topmenu_info_items {
|
||||
display: inline-block;
|
||||
display: flex !important;
|
||||
flex-direction: row-reverse;
|
||||
height: 45px;
|
||||
position: absolute;
|
||||
padding-right: 2px;
|
||||
@ -42,7 +43,6 @@
|
||||
}
|
||||
}
|
||||
#topmenu_info_user_avatar {
|
||||
|
||||
span.fw_avatar_stat {
|
||||
position: absolute;
|
||||
}
|
||||
@ -231,31 +231,61 @@
|
||||
background-color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ##############################################################################
|
||||
// quick_add selectbox
|
||||
// ADD different APPs
|
||||
#topmenu_info_timer {
|
||||
order: 1;
|
||||
position: relative;
|
||||
#topmenu_timer {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
top: 10px !important;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
color: #606060;
|
||||
}
|
||||
#topmenu_timer.running {
|
||||
color: black;
|
||||
}
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
&:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url(../../timesheet/templates/default/images/navbar.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 32px;
|
||||
background-position: center center;
|
||||
filter: opacity(0.3);
|
||||
}
|
||||
}
|
||||
|
||||
#quick_add_selectbox {
|
||||
// quick_add and timer selectbox / menu
|
||||
#topmenu_info_quick_add, #topmenu_info_timer {
|
||||
#quick_add_selectbox, #timer_selectbox {
|
||||
height: 0px;
|
||||
float: left;
|
||||
display: inline-block;
|
||||
}
|
||||
#quick_add_selectbox::part(form-control-input) {
|
||||
border: none !important;
|
||||
}
|
||||
#quick_add_selectbox::part(form-control) {
|
||||
margin-left: -3em;
|
||||
}
|
||||
#quick_add_selectbox::part(menu) {
|
||||
max-height: 60vh;
|
||||
}
|
||||
/* do NOT show empty label */
|
||||
et2-select#quick_add_selectbox {
|
||||
/* do NOT show empty label */
|
||||
sl-menu-item[value=""] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
#quick_add_selectbox::part(form-control-input), #timer_selectbox::part(form-control-input) {
|
||||
border: none !important;
|
||||
}
|
||||
#quick_add_selectbox::part(form-control), #timer_selectbox::part(form-control) {
|
||||
margin-left: -3em;
|
||||
}
|
||||
#quick_add_selectbox::part(menu), #timer_selectbox::part(menu) {
|
||||
max-height: 60vh;
|
||||
}
|
||||
}
|
||||
|
||||
// ##############################################################################
|
||||
|
@ -5279,7 +5279,8 @@ span.overlayContainer img.overlay {
|
||||
Author : stefanreinhardt
|
||||
*/
|
||||
#egw_fw_topmenu_info_items {
|
||||
display: inline-block;
|
||||
display: flex !important;
|
||||
flex-direction: row-reverse;
|
||||
height: 45px;
|
||||
position: absolute;
|
||||
padding-right: 2px;
|
||||
@ -5467,7 +5468,6 @@ span.overlayContainer img.overlay {
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add {
|
||||
position: relative;
|
||||
/* do NOT show empty label */
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add span#quick_add {
|
||||
float: right;
|
||||
@ -5486,23 +5486,71 @@ span.overlayContainer img.overlay {
|
||||
line-height: 0.6em;
|
||||
background-color: white;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer {
|
||||
order: 1;
|
||||
position: relative;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #topmenu_timer {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
top: 10px !important;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
color: #606060;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #topmenu_timer.running {
|
||||
color: black;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url(../../timesheet/templates/default/images/navbar.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 32px;
|
||||
background-position: center center;
|
||||
filter: opacity(0.3);
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox,
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox {
|
||||
height: 0px;
|
||||
float: left;
|
||||
display: inline-block;
|
||||
/* do NOT show empty label */
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control-input) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox sl-menu-item[value=""],
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox sl-menu-item[value=""] {
|
||||
display: none;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(form-control-input),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(form-control-input) {
|
||||
border: none !important;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(form-control),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(form-control) {
|
||||
margin-left: -3em;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(menu) {
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #quick_add_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #quick_add_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add #timer_selectbox::part(menu),
|
||||
#egw_fw_topmenu_info_items #topmenu_info_timer #timer_selectbox::part(menu) {
|
||||
max-height: 60vh;
|
||||
}
|
||||
#egw_fw_topmenu_info_items #topmenu_info_quick_add et2-select#quick_add_selectbox sl-menu-item[value=""] {
|
||||
display: none;
|
||||
}
|
||||
#egw_fw_topmenu_info_items img#topmenu_info_error {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
@ -1041,4 +1041,14 @@ class timesheet_bo extends Api\Storage
|
||||
}
|
||||
return parent::data2db($intern ? null : $data); // important to use null, if $intern!
|
||||
}
|
||||
}
|
||||
|
||||
public function ajax_event(array $state)
|
||||
{
|
||||
Api\Cache::setSession(__CLASS__, 'timer', $state);
|
||||
}
|
||||
|
||||
public static function timerState()
|
||||
{
|
||||
return Api\Cache::getSession(__CLASS__, 'timer');
|
||||
}
|
||||
}
|
@ -213,4 +213,12 @@ class timesheet_hooks
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static function add_timer($data)
|
||||
{
|
||||
$state = timesheet_bo::timerState();
|
||||
$GLOBALS['egw']->framework->_add_topmenu_info_item('<div id="topmenu_timer" title="'.
|
||||
lang('Start & stop timer').'"'.
|
||||
($state ? ' data-state="'.htmlspecialchars(json_encode($state)).'"' : '').'>0:00</div>', 'timer');
|
||||
}
|
||||
}
|
@ -16,9 +16,9 @@ if (!defined('TIMESHEET_APP'))
|
||||
}
|
||||
|
||||
$setup_info[TIMESHEET_APP]['name'] = TIMESHEET_APP;
|
||||
$setup_info[TIMESHEET_APP]['version'] = '21.1';
|
||||
$setup_info[TIMESHEET_APP]['version'] = '22.1';
|
||||
$setup_info[TIMESHEET_APP]['app_order'] = 5;
|
||||
$setup_info[TIMESHEET_APP]['tables'] = array('egw_timesheet','egw_timesheet_extra');
|
||||
$setup_info[TIMESHEET_APP]['tables'] = array('egw_timesheet','egw_timesheet_extra','egw_timesheet_events');
|
||||
$setup_info[TIMESHEET_APP]['enable'] = 1;
|
||||
$setup_info[TIMESHEET_APP]['index'] = 'timesheet.timesheet_ui.index&ajax=true';
|
||||
|
||||
@ -45,9 +45,10 @@ $setup_info[TIMESHEET_APP]['hooks']['search_link'] = 'timesheet_hooks::search_li
|
||||
$setup_info[TIMESHEET_APP]['hooks']['pm_cumulate'] = 'timesheet_hooks::cumulate';
|
||||
$setup_info[TIMESHEET_APP]['hooks']['deleteaccount'] = 'timesheet.timesheet_bo.deleteaccount';
|
||||
$setup_info[TIMESHEET_APP]['hooks']['acl_rights'] = 'timesheet_hooks::acl_rights';
|
||||
$setup_info[TIMESHEET_APP]['hooks']['topmenu_info'] = 'timesheet_hooks::add_timer';
|
||||
|
||||
/* Dependencies for this app to work */
|
||||
$setup_info[TIMESHEET_APP]['depends'][] = array(
|
||||
'appname' => 'api',
|
||||
'versions' => Array('21.1')
|
||||
);
|
||||
);
|
@ -45,5 +45,23 @@ $phpgw_baseline = array(
|
||||
'fk' => array(),
|
||||
'ix' => array(),
|
||||
'uc' => array()
|
||||
),
|
||||
'egw_timesheet_events' => array(
|
||||
'fd' => array(
|
||||
'tse_id' => array('type' => 'auto','nullable' => False),
|
||||
'ts_id' => array('type' => 'int','precision' => '4','comment' => 'or NULL for not yet created'),
|
||||
'tse_timestamp' => array('type' => 'timestamp','nullable' => False,'comment' => 'original time'),
|
||||
'tse_time' => array('type' => 'timestamp','comment' => 'edited time'),
|
||||
'account_id' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'user timesheet is for'),
|
||||
'tse_modified' => array('type' => 'timestamp','nullable' => False,'default' => 'current_timestamp','comment' => 'automatic modification TS'),
|
||||
'tse_modifier' => array('type' => 'int','meta' => 'user','precision' => '4','comment' => 'modifier'),
|
||||
'tse_app' => array('type' => 'ascii','precision' => '24','comment' => 'app, if set on creation'),
|
||||
'tse_app_id' => array('type' => 'ascii','precision' => '64','comment' => 'app-id, if set on creation'),
|
||||
'tse_type' => array('type' => 'int','precision' => '16','nullable' => False,'comment' => '&1=start,&2=stop/pause,&16=overal-working-time')
|
||||
),
|
||||
'pk' => array('tse_id'),
|
||||
'fk' => array(),
|
||||
'ix' => array('ts_id'),
|
||||
'uc' => array('tse_id')
|
||||
)
|
||||
);
|
||||
|
@ -200,3 +200,28 @@ function timesheet_upgrade20_1()
|
||||
{
|
||||
return $GLOBALS['setup_info']['timesheet']['currentver'] = '21.1';
|
||||
}
|
||||
|
||||
function timesheet_upgrade21_1()
|
||||
{
|
||||
$GLOBALS['egw_setup']->oProc->CreateTable('egw_timesheet_events',array(
|
||||
'fd' => array(
|
||||
'tse_id' => array('type' => 'auto','nullable' => False),
|
||||
'ts_id' => array('type' => 'int','precision' => '4','comment' => 'or NULL for not yet created'),
|
||||
'tse_timestamp' => array('type' => 'timestamp','nullable' => False,'comment' => 'original time'),
|
||||
'tse_time' => array('type' => 'timestamp','comment' => 'edited time'),
|
||||
'account_id' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'user timesheet is for'),
|
||||
'tse_modified' => array('type' => 'timestamp','nullable' => False,'default' => 'current_timestamp','comment' => 'automatic modification TS'),
|
||||
'tse_modifier' => array('type' => 'int','meta' => 'user','precision' => '4','comment' => 'modifier'),
|
||||
'tse_app' => array('type' => 'ascii','precision' => '24','comment' => 'app, if set on creation'),
|
||||
'tse_app_id' => array('type' => 'ascii','precision' => '64','comment' => 'app-id, if set on creation'),
|
||||
'tse_type' => array('type' => 'int','precision' => '16','nullable' => False,'comment' => '&1=start,&2=stop/pause,&16=overal-working-time')
|
||||
),
|
||||
'pk' => array('tse_id'),
|
||||
'fk' => array(),
|
||||
'ix' => array('ts_id'),
|
||||
'uc' => array('tse_id')
|
||||
));
|
||||
|
||||
return $GLOBALS['setup_info']['timesheet']['currentver'] = '22.1';
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user